blob: 002e6834ac059d526b539bc888775907169f6997 [file] [log] [blame]
package org.codehaus.jackson.impl;
import main.BaseTest;
import org.codehaus.jackson.*;
import org.codehaus.jackson.io.SerializedString;
import java.io.*;
import java.util.Random;
/**
* Set of basic unit tests for verifying that the basic parser
* functionality works as expected.
*/
public class TestUtf8Parser
extends BaseTest
{
final static String[] UTF8_2BYTE_STRINGS = new String[] {
/* This may look funny, but UTF8 scanner has fairly
* elaborate decoding machinery, and it is indeed
* necessary to try out various combinations...
*/
"b", "A\u00D8", "abc", "c3p0",
"12345", "......", "Long\u00FAer",
"Latin1-fully-\u00BE-develop\u00A8d",
"Some very long name, ridiculously long actually to see that buffer expansion works: \u00BF?"
};
final static String[] UTF8_3BYTE_STRINGS = new String[] {
"\uC823?", "A\u400F", "1\u1234?",
"Ab123\u4034",
"Even-longer:\uC023"
};
public void testEmptyName()
throws Exception
{
final String DOC = "{ \"\" : \"\" }";
JsonParser jp = createParserUsingStream(DOC, "UTF-8");
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals("", jp.getCurrentName());
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
assertEquals("", jp.getText());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
jp.close();
}
public void testUtf8Name2Bytes()
throws Exception
{
final String[] NAMES = UTF8_2BYTE_STRINGS;
for (int i = 0; i < NAMES.length; ++i) {
String NAME = NAMES[i];
String DOC = "{ \""+NAME+"\" : 0 }";
JsonParser jp = createParserUsingStream(DOC, "UTF-8");
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals(NAME, jp.getCurrentName());
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
// should retain name during value entry, too
assertEquals(NAME, jp.getCurrentName());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
jp.close();
}
}
public void testUtf8Name3Bytes() throws Exception
{
final String[] NAMES = UTF8_3BYTE_STRINGS;
for (int i = 0; i < NAMES.length; ++i) {
String NAME = NAMES[i];
String DOC = "{ \""+NAME+"\" : true }";
JsonParser jp = createParserUsingStream(DOC, "UTF-8");
assertToken(JsonToken.START_OBJECT, jp.nextToken());
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
assertEquals(NAME, jp.getCurrentName());
assertToken(JsonToken.VALUE_TRUE, jp.nextToken());
assertEquals(NAME, jp.getCurrentName());
assertToken(JsonToken.END_OBJECT, jp.nextToken());
jp.close();
}
}
// How about tests for Surrogate-Pairs?
public void testUtf8StringTrivial() throws Exception
{
String[] VALUES = UTF8_2BYTE_STRINGS;
for (int i = 0; i < VALUES.length; ++i) {
String VALUE = VALUES[i];
String DOC = "[ \""+VALUE+"\" ]";
JsonParser jp = createParserUsingStream(DOC, "UTF-8");
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
String act = getAndVerifyText(jp);
if (act.length() != VALUE.length()) {
fail("Failed for value #"+(i+1)+"/"+VALUES.length+": length was "+act.length()+", should be "+VALUE.length());
}
assertEquals(VALUE, act);
assertToken(JsonToken.END_ARRAY, jp.nextToken());
jp.close();
}
VALUES = UTF8_3BYTE_STRINGS;
for (int i = 0; i < VALUES.length; ++i) {
String VALUE = VALUES[i];
String DOC = "[ \""+VALUE+"\" ]";
JsonParser jp = createParserUsingStream(DOC, "UTF-8");
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
assertEquals(VALUE, getAndVerifyText(jp));
assertToken(JsonToken.END_ARRAY, jp.nextToken());
jp.close();
}
}
public void testUtf8StringValue() throws Exception
{
Random r = new Random(13);
//int LEN = 72000;
int LEN = 720;
StringBuilder sb = new StringBuilder(LEN + 20);
while (sb.length() < LEN) {
int c;
if (r.nextBoolean()) { // ascii
c = 32 + (r.nextInt() & 0x3F);
if (c == '"' || c == '\\') {
c = ' ';
}
} else if (r.nextBoolean()) { // 2-byte
c = 160 + (r.nextInt() & 0x3FF);
} else if (r.nextBoolean()) { // 3-byte (non-surrogate)
c = 8000 + (r.nextInt() & 0x7FFF);
} else { // surrogates (2 chars)
int value = r.nextInt() & 0x3FFFF; // 20-bit, ~ 1 million
sb.append((char) (0xD800 + (value >> 10)));
c = (0xDC00 + (value & 0x3FF));
}
sb.append((char) c);
}
ByteArrayOutputStream bout = new ByteArrayOutputStream(LEN);
OutputStreamWriter out = new OutputStreamWriter(bout, "UTF-8");
out.write("[\"");
String VALUE = sb.toString();
out.write(VALUE);
out.write("\"]");
out.close();
byte[] data = bout.toByteArray();
JsonParser jp = new JsonFactory().createJsonParser(new ByteArrayInputStream(data));
assertToken(JsonToken.START_ARRAY, jp.nextToken());
assertToken(JsonToken.VALUE_STRING, jp.nextToken());
String act = jp.getText();
assertEquals(VALUE.length(), act.length());
assertEquals(VALUE, act);
jp.close();
}
// [JACKSON-889]
public void testNextFieldName() throws IOException
{
JsonFactory f = new JsonFactory();
SerializedString id = new SerializedString("id");
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write('{');
for (int i = 0; i < 3994; i++) {
os.write(' ');
}
os.write("\"id\":2".getBytes("UTF-8"));
os.write('}');
JsonParser parser = f.createJsonParser(new ByteArrayInputStream(os.toByteArray()));
assertEquals(parser.nextToken(), JsonToken.START_OBJECT);
assertTrue(parser.nextFieldName(id));
assertEquals(parser.nextToken(), JsonToken.VALUE_NUMBER_INT);
assertEquals(parser.nextToken(), JsonToken.END_OBJECT);
parser.close();
}
}