Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,9 @@ Authors:
<include name="schema/config/SurrogatePairLengthTest.class"/>
<include name="schema/config/UseGrammarPoolOnly_True_Test.class"/>
<include name="schema/config/UnparsedEntityCheckingTest.class"/>
-->
-->
<include name="io/UTF8.class"/>
<include name="io/UTF16.class"/>
<include name="schema/Test.class"/>
<include name="jaxp/JAXPSpecTest.class"/>
<include name="dom/ids/Test.class"/>
Expand Down
212 changes: 54 additions & 158 deletions tests/io/UTF16.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.InputStreamReader;
import java.io.Reader;

import junit.framework.TestCase;
import org.apache.xerces.impl.io.UTF16Reader;
import org.apache.xerces.util.XMLChar;

Expand All @@ -31,234 +32,129 @@
*
* @version $Id$
*/
public class UTF16 {

//
// MAIN
//
public class UTF16 extends TestCase {

/** Main program entry. */
public static void main(String[] argv) throws Exception {
public void testUTF16DecoderBigEndian() throws Exception {
testUTF16Decoder(true);
}

public void testUTF16DecoderLittleEndian() throws Exception {
testUTF16Decoder(false);
} // main(String[])

//
// Public static methods
//

public static void testUTF16Decoder(boolean isBigEndian) throws Exception {

}

private void testUTF16Decoder(boolean isBigEndian) throws Exception {
final int BLOCK_READ_SIZE = 2048;
final String encoding = isBigEndian ? "UnicodeBig" : "UnicodeLittle";
final String shortName = isBigEndian ? "BE" : "LE";

//
// Test Java reference implementation of UTF-16 decoder
//

System.err.println("#");
System.err.println("# Testing Java UTF-16" + shortName + " decoder");
System.err.println("#");

// test character by character
try {
InputStream stream = new UTF16Producer(isBigEndian);
Reader reader = new InputStreamReader(stream, encoding);
long time = testCharByChar(reader);
System.err.println("PASS ("+time+" ms)");
reader.close();
}
catch (IOException e) {
System.err.println("FAIL: "+e.getMessage());
}

// test character array
try {
InputStream stream = new UTF16Producer(isBigEndian);
Reader reader = new InputStreamReader(stream, encoding);
long time = testCharArray(reader, BLOCK_READ_SIZE);
System.err.println("PASS ("+time+" ms)");
reader.close();
}
catch (IOException e) {
System.err.println("FAIL: "+e.getMessage());
}

//
// Test custom implementation of UTF-16 decoder
//
InputStream stream = new UTF16Producer(isBigEndian);
Reader reader = new InputStreamReader(stream, encoding);
testCharByChar(reader);
reader.close();

System.err.println("#");
System.err.println("# Testing custom UTF-16" + shortName + " decoder");
System.err.println("#");
// test character array
stream = new UTF16Producer(isBigEndian);
reader = new InputStreamReader(stream, encoding);
testCharArray(reader, BLOCK_READ_SIZE);
reader.close();

// Test custom implementation of UTF-16 decoder
// test character by character
try {
InputStream stream = new UTF16Producer(isBigEndian);
Reader reader = new UTF16Reader(stream, isBigEndian);
long time = testCharByChar(reader);
System.err.println("PASS ("+time+" ms)");
reader.close();
}
catch (IOException e) {
System.err.println("FAIL: "+e.getMessage());
}

stream = new UTF16Producer(isBigEndian);
reader = new UTF16Reader(stream, isBigEndian);
testCharByChar(reader);
reader.close();

// test character array
try {
InputStream stream = new UTF16Producer(isBigEndian);
Reader reader = new UTF16Reader(stream, isBigEndian);
long time = testCharArray(reader, BLOCK_READ_SIZE);
System.err.println("PASS ("+time+" ms)");
reader.close();
}
catch (IOException e) {
System.err.println("FAIL: "+e.getMessage());
}
stream = new UTF16Producer(isBigEndian);
reader = new UTF16Reader(stream, isBigEndian);
testCharArray(reader, BLOCK_READ_SIZE);
reader.close();
}

/** This function tests the specified reader character by character. */
public static long testCharByChar(Reader reader) throws Exception {

long before = System.currentTimeMillis();
System.err.println("# Testing character by character");

System.err.println("testing 0x000000 -> 0x00D7FF");
private void testCharByChar(Reader reader) throws Exception {
for (int i = 0; i < 0xD800; i++) {
int c = reader.read();
if (c != i) {
UTF8.expectedChar(null, i, c);
}
assertEquals("character 0x" + Integer.toHexString(i) + " mismatch", i, reader.read());
}
System.err.println("testing 0x00E000 -> 0x00FFFD");
for (int i = 0xE000; i < 0xFFFE; i++) {
int c = reader.read();
if (c != i) {
UTF8.expectedChar(null, i, c);
}
assertEquals("character 0x" + Integer.toHexString(i) + " mismatch", i, reader.read());
}
System.err.println("testing 0x010000 -> 0x10FFFF");
for (int i = 0x10000; i < 0x110000; i++) {
// vars
int uuuuu = (i >> 16) & 0x001F;
int wwww = uuuuu - 1;
int zzzz = (i >> 12) & 0x000F;
int yyyyyy = (i >> 6) & 0x003F;
int xxxxxx = i & 0x003F;
int hs = 0xD800 | (wwww << 6) | (zzzz << 2) | (yyyyyy >> 4);
int ls = 0xDC00 | ((yyyyyy << 6) & 0x03C0) | xxxxxx;
// high surrogate
int c = reader.read();
if (c != hs) {
UTF8.expectedChar("high surrogate", hs, c);
}
// low surrogate
c = reader.read();
if (c != ls) {
UTF8.expectedChar("low surrogate", ls, c);
}
}
System.err.println("checking EOF");
int c = reader.read();
if (c != -1) {
UTF8.extraChar(c);
assertEquals("high surrogate mismatch", hs, reader.read());
assertEquals("low surrogate mismatch", ls, reader.read());
}
long after = System.currentTimeMillis();

return after - before;

} // testCharByChar(Reader):long

/**
* This function tests the given reader by performing block character
* reads of the specified size.
*/
public static long testCharArray(Reader reader, int size) throws Exception {

long before = System.currentTimeMillis();
System.err.println("# Testing character array of size "+size);
assertEquals("Expected EOF", -1, reader.read());
}

private void testCharArray(Reader reader, int size) throws Exception {
char[] ch = new char[size];
int count = 0;
int position = 0;

System.err.println("testing 0x000000 -> 0x00D7FF");
for (int i = 0; i < 0xD800; i++) {
if (position == count) {
count = UTF8.load(reader, ch);
count = reader.read(ch, 0, ch.length);
position = 0;
}
int c = ch[position++];
if (c != i) {
UTF8.expectedChar(null, i, c);
}
assertEquals("character 0x" + Integer.toHexString(i) + " mismatch", i, c);
}
System.err.println("testing 0x00E000 -> 0x00FFFD");
for (int i = 0xE000; i < 0xFFFE; i++) {
if (position == count) {
count = UTF8.load(reader, ch);
count = reader.read(ch, 0, ch.length);
position = 0;
}
int c = ch[position++];
if (c != i) {
UTF8.expectedChar(null, i, c);
}
assertEquals("character 0x" + Integer.toHexString(i) + " mismatch", i, c);
}
System.err.println("testing 0x010000 -> 0x110000");
for (int i = 0x10000; i < 0x110000; i++) {
// vars
int uuuuu = (i >> 16) & 0x001F;
int wwww = uuuuu - 1;
int zzzz = (i >> 12) & 0x000F;
int yyyyyy = (i >> 6) & 0x003F;
int xxxxxx = i & 0x003F;
int hs = 0xD800 | (wwww << 6) | (zzzz << 2) | (yyyyyy >> 4);
int ls = 0xDC00 | ((yyyyyy << 6) & 0x03C0) | xxxxxx;
// high surrogate
if (position == count) {
count = UTF8.load(reader, ch);
count = reader.read(ch, 0, ch.length);
position = 0;
}
int c = ch[position++];
if (c != hs) {
UTF8.expectedChar("high surrogate", hs, c);
}
// low surrogate
assertEquals("high surrogate mismatch", hs, c);
if (position == count) {
count = UTF8.load(reader, ch);
count = reader.read(ch, 0, ch.length);
position = 0;
}
c = ch[position++];
if (c != ls) {
UTF8.expectedChar("low surrogate", ls, c);
}
assertEquals("low surrogate mismatch", ls, c);
}
System.err.println("checking EOF");
if (position == count) {
count = UTF8.load(reader, ch);
count = reader.read(ch, 0, ch.length);
position = 0;
}
if (count != -1) {
UTF8.extraChar(ch[position]);
}
long after = System.currentTimeMillis();

return after - before;
assertEquals("Expected EOF", -1, count);
}

} // testCharArray(Reader):long

//
// Classes
//

/**
* This classes produces a stream of UTF-16 byte sequences for all
* valid Unicode characters.
*/
public static class UTF16Producer
extends InputStream {

//
// Data
//
Expand All @@ -268,25 +164,25 @@ public static class UTF16Producer

/** The current byte of the current code point. */
private int fByte;

/** Endianness. */
private final boolean fIsBigEndian;

//
// Constructors
//

public UTF16Producer(boolean isBigEndian) {
fIsBigEndian = isBigEndian;
}

//
// InputStream methods
//

/** Reads the next character. */
public int read() throws IOException {

if (fCodePoint < 0xFFFE) {
// skip surrogate blocks
if (fCodePoint == 0xD800) {
Expand Down
Loading
Loading