/*
* JacORB - a free Java ORB
*
* Copyright (C) 1999-2014 Gerald Brose / The JacORB Team.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
package org.jacorb.test.orb;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Arrays;
import org.jacorb.orb.CDROutputStream;
import org.jacorb.orb.CodeSet;
import org.jacorb.test.harness.ORBTestCase;
import org.jacorb.test.harness.TestUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.omg.CORBA.BAD_PARAM;
public class CDROutputStreamTest extends ORBTestCase
{
private CDROutputStream objectUnderTest;
@Before
public void setUp() throws Exception
{
objectUnderTest = new CDROutputStream(orb);
}
@After
public void tearDown() throws Exception
{
objectUnderTest.close();
objectUnderTest = null;
}
@Test
public void testIncreaseSize()
{
byte[] buffer = new byte[4];
objectUnderTest.setBuffer(buffer);
objectUnderTest.increaseSize(8);
assertTrue(objectUnderTest.size() >= 8);
}
/**
* Verifies that the public ctor is available and that the releaseBuffer works as expected
*/
@Test
public void testCDRStreamSizeCtor()
{
CDROutputStream co = new CDROutputStream (orb, 1000);
co.increaseSize(8);
byte[] result = co.releaseBuffer();
co.close();
assertTrue (result.length == 1023);
}
/**
* Verifies that the default encoding (ISO8859_1) works for char, char arrays, and strings. Reading the string
* forces alignment of the 4-byte length, and ignores any null terminator.
*/
@Test
public void testDefaultEncodingChar() throws Exception {
objectUnderTest.write_char( 'a' );
objectUnderTest.write_char( 's' );
objectUnderTest.write_char( 'd' );
objectUnderTest.write_char( 'f' );
objectUnderTest.write_char_array( "wxyz".toCharArray(), 1, 3 );
objectUnderTest.write_string( "CAFE" );
byte[] codedText = { 'a', 's', 'd', 'f', 'x', 'y', 'z', 0,
0, 0, 0, 5, 'C', 'A', 'F', 'E', 0 };
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
/**
* Verifies that the default encoding (UTF-16) works for wchar, wchar arrays, and wstrings
* with no byte-order-marker. Reading the wstring
* forces alignment of the 4-byte length.
*/
@Test
public void testDefaultEncodingWChar() throws Exception {
byte[] codedText = { 2, 0x5, (byte) (0xD0 & 0xff), // Hebrew letter aleph
2, 0x30, 0x51, // Hiragana syllable ha
2, 0x30, 0x74, // Hiragana syllable pi
2, 0x5, (byte) (0xD1 & 0xff), // Hebrew letter beis
2, 0x5, (byte) (0xD2 & 0xff), // Hebrew letter gimmel
2, 0x5, (byte) (0xD3 & 0xff), // Hebrew letter dalet
0, 0, // bytes ignored by 'long' alignment
0, 0, 0, 8, // string length in bytes, not chars
0x30, (byte) (0xDF & 0xff), // Mitsubishi, in Katakana
0x30, (byte) (0xC4 & 0xff),
0x30, (byte) (0xFA & 0xff),
0x30, (byte) (0xB7 & 0xff),
};
objectUnderTest.write_wchar( '\u05D0' );
objectUnderTest.write_wchar( '\u3051' );
objectUnderTest.write_wchar( '\u3074' );
objectUnderTest.write_wchar_array( "\u05D0\u05D1\u05D2\u05D3".toCharArray(), 1, 3 );
objectUnderTest.write_wstring( "\u30DF\u30C4\u30FA\u30B7" );
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
/**
* Verifies that the UCS-2 encoding works for wchar, wchar arrays, and wstrings. Unlike UTF-16,
* the byte-order-marker is not optional.
*/
@Test
public void testUCS2EncodingWChar() throws Exception {
byte[] codedText = { 2, 0x5, (byte) (0xD0 & 0xff), // Hebrew letter aleph
2, 0x30, 0x51, // Hiragana syllable ha
2, 0x30, 0x74, // Hiragana syllable pi
2, 0x5, (byte) (0xD1 & 0xff), // Hebrew letter beis
2, 0x5, (byte) (0xD2 & 0xff), // Hebrew letter gimmel
2, 0x5, (byte) (0xD3 & 0xff), // Hebrew letter dalet
0, 0, // bytes ignored by 'long' alignment
0, 0, 0, 8, // string length in bytes, not chars
0x30, (byte) (0xDF & 0xff), // Mitsubishi, in Katakana
0x30, (byte) (0xC4 & 0xff),
0x30, (byte) (0xFA & 0xff),
0x30, (byte) (0xB7 & 0xff),
};
selectCodeSets( "UTF8", "UCS2" );
objectUnderTest.write_wchar( '\u05D0' );
objectUnderTest.write_wchar( '\u3051' );
objectUnderTest.write_wchar( '\u3074' );
objectUnderTest.write_wchar_array( "\u05D0\u05D1\u05D2\u05D3".toCharArray(), 1, 3 );
objectUnderTest.write_wstring( "\u30DF\u30C4\u30FA\u30B7" );
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
/**
* Verifies that the default encoding (UTF-16) works for wstrings in giop 1.1, which uses the length
* indicator to specify the number of characters rather than bytes and require a two-byte null terminator.
* Wide characters in 1.1 do not take width bytes
*/
@Test
public void testDefaultEncodingWCharGiop1_1() throws Exception {
byte[] codedText = { 0, 0, 0, 5, // string length in bytes, not chars
0x30, (byte) (0xDF & 0xff), // Mitsubishi, in Katakana
0x30, (byte) (0xC4 & 0xff),
0x30, (byte) (0xFA & 0xff),
0x30, (byte) (0xB7 & 0xff),
0, 0, // two-byte null terminator
0x5, (byte) (0xD1 & 0xff), // Hebrew letter beis
};
objectUnderTest.setGIOPMinor( 1 );
objectUnderTest.write_wstring( "\u30DF\u30C4\u30FA\u30B7" );
objectUnderTest.write_wchar( '\u05D1' );
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
/**
* Verifies that the UTF-8 encoding works for strings in giop 1.1.
*/
@Test
public void testUTF8EncodingCharGiop1_1() throws Exception {
byte[] codedText = { 0, 0, 0, 5, // string length in bytes, including null pointer
'a', 's', 'd', 'f', 0, // one-byte null terminator
'x'
};
selectCodeSets( "UTF8", "UTF8" );
objectUnderTest.setGIOPMinor( 1 );
objectUnderTest.write_string( "asdf" );
objectUnderTest.write_char( 'x' );
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
/**
* Verifies that the UTF-8 encoding works for strings in giop 1.1. Have to check - this may not be required.
*/
@Test
public void testUTF8EncodingWCharGiop1_1() throws Exception {
byte[] codedText = { 0, 0, 0, 13, // string length in bytes, including null terminator
(byte) (0xE3 & 0xff), (byte) (0x83 & 0xff), (byte) (0x9F & 0xff), // Mitsubishi, in Katakana
(byte) (0xE3 & 0xff), (byte) (0x83 & 0xff), (byte) (0x84 & 0xff),
(byte) (0xE3 & 0xff), (byte) (0x83 & 0xff), (byte) (0xBA & 0xff),
(byte) (0xE3 & 0xff), (byte) (0x82 & 0xff), (byte) (0xB7 & 0xff),
0, // one-byte null terminator
(byte) (0xD7 & 0xff), (byte) (0x91 & 0xff), // Hebrew letter beis (w/o length byte)
};
selectCodeSets( "ISO8859_1", "UTF8" );
objectUnderTest.setGIOPMinor( 1 );
objectUnderTest.write_wstring( "\u30DF\u30C4\u30FA\u30B7" );
objectUnderTest.write_wchar( '\u05D1' );
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
/**
* Verifies that the UTF-8 works for wchar, wchar arrays, and wstrings. Reading the wstring
* forces alignment of the 4-byte length. Note that byte-ordering is fixed by the encoding.
*/
@Test
public void testUTF8EncodingWChar() throws Exception {
byte[] codedText = { 1, 'x', // Latin-l lowercase x
2, (byte) (0xD7 & 0xff), (byte) (0x90 & 0xff), // Hebrew letter aleph
3, (byte) (0xE3 & 0xff), (byte) (0x81 & 0xff), (byte) (0x91 & 0xff), // Hiragana syllable ha
3, (byte) (0xE3 & 0xff), (byte) (0x81 & 0xff), (byte) (0xB4 & 0xff), // Hiragana syllable pi
2, (byte) (0xD7 & 0xff), (byte) (0x91 & 0xff), // Hebrew letter beis
2, (byte) (0xD7 & 0xff), (byte) (0x92 & 0xff), // Hebrew letter gimmel
2, (byte) (0xD7 & 0xff), (byte) (0x93 & 0xff), // Hebrew letter dalet
0, 0, // bytes ignored by 'long' alignment
0, 0, 0, 12, // string length in bytes, not chars
(byte) (0xE3 & 0xff), (byte) (0x83 & 0xff), (byte) (0x9F & 0xff), // Mitsubishi, in Katakana
(byte) (0xE3 & 0xff), (byte) (0x83 & 0xff), (byte) (0x84 & 0xff),
(byte) (0xE3 & 0xff), (byte) (0x83 & 0xff), (byte) (0xBA & 0xff),
(byte) (0xE3 & 0xff), (byte) (0x82 & 0xff), (byte) (0xB7 & 0xff),
};
selectCodeSets( "ISO8859_1", "UTF8" );
objectUnderTest.write_wchar( 'x' );
objectUnderTest.write_wchar( '\u05D0' );
objectUnderTest.write_wchar( '\u3051' );
objectUnderTest.write_wchar( '\u3074' );
objectUnderTest.write_wchar_array( "\u05D0\u05D1\u05D2\u05D3".toCharArray(), 1, 3 );
objectUnderTest.write_wstring( "\u30DF\u30C4\u30FA\u30B7" );
assertEquals( "generated bytes", codedText, objectUnderTest.getBufferCopy() );
}
private void selectCodeSets( String charCodeSet, String wideCharCodeSet )
{
objectUnderTest.setCodeSets( CodeSet.getCodeSet( charCodeSet ), CodeSet.getCodeSet( wideCharCodeSet ) );
}
private static void assertEquals( String comment, byte[] expected, byte[] actual ) {
if (Arrays.equals( expected, actual )) return;
StringBuffer sb = new StringBuffer( comment );
append( sb, " expected: ", expected );
append( sb, "but was: ", actual );
fail( sb.toString() );
}
private static final int BYTES_PER_GROUP = 8;
private static final int GROUPS_PER_LINE = 8;
private static final int BYTES_PER_LINE = BYTES_PER_GROUP * GROUPS_PER_LINE;
private static final int LAST_IN_GROUP = BYTES_PER_GROUP - 1;
private static void append( StringBuffer sb, String comment, byte[] bytes ) {
sb.append( comment ).append( '\n' );
int pos = 0;
while (pos < bytes.length ) {
for (int i = 0; i < BYTES_PER_LINE && i < bytes.length - pos; i++) {
formatOneByte( sb, bytes[i] );
if ((i % BYTES_PER_GROUP) == LAST_IN_GROUP) sb.append( ' ' );
}
sb.append( '\n' );
pos += BYTES_PER_LINE;
}
}
private static void formatOneByte(StringBuffer sb, byte aByte ) {
int value = aByte & 0x0ff;
if (value < 0x10) sb.append( '0' );
sb.append( Integer.toHexString( value ) );
}
@Test
public void testDoesNotLikeNonJacORB()
{
org.omg.CORBA.ORB sunORB = org.omg.CORBA.ORB.init(new String[0], TestUtils.newForeignORBProperties());
try
{
try
{
new CDROutputStream(sunORB);
}
catch(BAD_PARAM e)
{
}
}
finally
{
orb.shutdown(true);
}
}
}