Updated Grammar for matching JsonArray to be left-associative rather than right-associative. Gson can now parse arrays of size over 11MB instead of 80KB which was the prior limit. Thanks for the tip, kenotron.

This commit is contained in:
Inderjeet Singh 2009-08-22 01:03:27 +00:00
parent c13fc568c7
commit cbcf7defa3
12 changed files with 1037 additions and 905 deletions

View File

@ -19,9 +19,9 @@ package com.google.gson;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
/** /**
@ -39,7 +39,7 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
* Creates an empty JsonArray. * Creates an empty JsonArray.
*/ */
public JsonArray() { public JsonArray() {
elements = new LinkedList<JsonElement>(); elements = new ArrayList<JsonElement>();
} }
/** /**

View File

@ -138,6 +138,10 @@ final class JsonParserJavacc implements JsonParserJavaccConstants {
JsonArray array = new JsonArray(); JsonArray array = new JsonArray();
jj_consume_token(31); jj_consume_token(31);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 32:
array = JsonArrayEmpty(array);
{if (true) return array;}
break;
case DIGITS: case DIGITS:
case NULL: case NULL:
case NAN: case NAN:
@ -148,31 +152,51 @@ final class JsonParserJavacc implements JsonParserJavaccConstants {
case 27: case 27:
case 31: case 31:
case 33: case 33:
Elements(array); JsonArrayElement(array);
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case 29:
;
break;
default:
jj_la1[6] = jj_gen;
break label_1;
}
JsonArrayNextElement(array);
}
jj_consume_token(32);
{if (true) return array;}
break; break;
default: default:
jj_la1[6] = jj_gen; jj_la1[7] = jj_gen;
; jj_consume_token(-1);
throw new ParseException();
} }
throw new Error("Missing return statement in function");
}
final private JsonArray JsonArrayEmpty(JsonArray array) throws ParseException {
jj_consume_token(32); jj_consume_token(32);
array.reverse(); {if (true) return array;}
throw new Error("Missing return statement in function");
}
final private JsonArray JsonArrayElement(JsonArray array) throws ParseException {
JsonElement element = null;
element = JsonValue();
array.add(element);
{if (true) return array;} {if (true) return array;}
throw new Error("Missing return statement in function"); throw new Error("Missing return statement in function");
} }
final private void Elements(JsonArray array) throws ParseException { final private JsonArray JsonArrayNextElement(JsonArray array) throws ParseException {
JsonElement element; JsonElement element = null;
jj_consume_token(29);
element = JsonValue(); element = JsonValue();
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { array.add(element);
case 29: {if (true) return array;}
jj_consume_token(29); throw new Error("Missing return statement in function");
Elements(array);
break;
default:
jj_la1[7] = jj_gen;
;
}
array.add(element);
} }
final private JsonElement JsonValue() throws ParseException { final private JsonElement JsonValue() throws ParseException {
@ -406,36 +430,36 @@ final class JsonParserJavacc implements JsonParserJavaccConstants {
finally { jj_save(0, xla); } finally { jj_save(0, xla); }
} }
private boolean jj_3R_4() { private boolean jj_3R_3() {
if (jj_scan_token(NAN)) return true;
return false;
}
private boolean jj_3R_2() {
Token xsp;
xsp = jj_scanpos;
if (jj_3R_3()) {
jj_scanpos = xsp;
if (jj_3R_4()) return true;
}
return false;
}
private boolean jj_3R_5() {
if (jj_scan_token(33)) return true; if (jj_scan_token(33)) return true;
return false; return false;
} }
private boolean jj_3R_3() { private boolean jj_3R_4() {
Token xsp; Token xsp;
xsp = jj_scanpos; xsp = jj_scanpos;
if (jj_3R_4()) jj_scanpos = xsp; if (jj_3R_5()) jj_scanpos = xsp;
if (jj_scan_token(INFINITY)) return true; if (jj_scan_token(INFINITY)) return true;
return false; return false;
} }
private boolean jj_3_1() { private boolean jj_3_1() {
if (jj_3R_1()) return true; if (jj_3R_2()) return true;
return false;
}
private boolean jj_3R_2() {
if (jj_scan_token(NAN)) return true;
return false;
}
private boolean jj_3R_1() {
Token xsp;
xsp = jj_scanpos;
if (jj_3R_2()) {
jj_scanpos = xsp;
if (jj_3R_3()) return true;
}
return false; return false;
} }
@ -458,10 +482,10 @@ final class JsonParserJavacc implements JsonParserJavaccConstants {
jj_la1_init_1(); jj_la1_init_1();
} }
private static void jj_la1_init_0() { private static void jj_la1_init_0() {
jj_la1_0 = new int[] {0x4000000,0x880307c0,0x8c0307c1,0x31800,0x20000000,0x31800,0x880307c0,0x20000000,0x880307c0,0x30740,0x0,0x20,0x40,0x0,0x300,0x0,0x1800,0x30000,}; jj_la1_0 = new int[] {0x4000000,0x880307c0,0x8c0307c1,0x31800,0x20000000,0x31800,0x20000000,0x880307c0,0x880307c0,0x30740,0x0,0x20,0x40,0x0,0x300,0x0,0x1800,0x30000,};
} }
private static void jj_la1_init_1() { private static void jj_la1_init_1() {
jj_la1_1 = new int[] {0x0,0x2,0x2,0x0,0x0,0x0,0x2,0x0,0x2,0x2,0x4,0x0,0x2,0x2,0x2,0x2,0x0,0x0,}; jj_la1_1 = new int[] {0x0,0x2,0x2,0x0,0x0,0x0,0x0,0x3,0x2,0x2,0x4,0x0,0x2,0x2,0x2,0x2,0x0,0x0,};
} }
final private JJCalls[] jj_2_rtns = new JJCalls[1]; final private JJCalls[] jj_2_rtns = new JJCalls[1];
private boolean jj_rescan = false; private boolean jj_rescan = false;

View File

@ -6,7 +6,6 @@ package com.google.gson;
* Token literal values and constants. * Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start() * Generated by org.javacc.parser.OtherFilesGen#start()
*/ */
@SuppressWarnings("all")
interface JsonParserJavaccConstants { interface JsonParserJavaccConstants {
/** End of File. */ /** End of File. */

View File

@ -1077,9 +1077,7 @@ protected Token jjFillToken()
beginColumn = input_stream.getBeginColumn(); beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine(); endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn(); endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind); t = Token.newToken(jjmatchedKind, curTokenImage);
t.kind = jjmatchedKind;
t.image = curTokenImage;
t.beginLine = beginLine; t.beginLine = beginLine;
t.endLine = endLine; t.endLine = endLine;

View File

@ -1,193 +1,188 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */ /* Generated By:JavaCC: Do not edit this line. ParseException.java Version 4.1 */
package com.google.gson; /* JavaCCOptions:KEEP_LINE_COL=null */
package com.google.gson;
/**
* This exception is thrown when parse errors are encountered. /**
* You can explicitly create objects of this exception type by * This exception is thrown when parse errors are encountered.
* calling the method generateParseException in the generated * You can explicitly create objects of this exception type by
* parser. * calling the method generateParseException in the generated
* * parser.
* You can modify this class to customize your error reporting *
* mechanisms so long as you retain the public fields. * You can modify this class to customize your error reporting
*/ * mechanisms so long as you retain the public fields.
@SuppressWarnings("all") */
final class ParseException extends Exception { @SuppressWarnings("all")
final class ParseException extends Exception {
/**
* This constructor is used by the method "generateParseException" /**
* in the generated parser. Calling this constructor generates * The version identifier for this Serializable class.
* a new object of this type with the fields "currentToken", * Increment only if the <i>serialized</i> form of the
* "expectedTokenSequences", and "tokenImage" set. The boolean * class changes.
* flag "specialConstructor" is also set to true to indicate that */
* this constructor was used to create this object. private static final long serialVersionUID = 1L;
* This constructor calls its super class with the empty string
* to force the "toString" method of parent class "Throwable" to /**
* print the error message in the form: * This constructor is used by the method "generateParseException"
* ParseException: <result of getMessage> * in the generated parser. Calling this constructor generates
*/ * a new object of this type with the fields "currentToken",
public ParseException(Token currentTokenVal, * "expectedTokenSequences", and "tokenImage" set.
int[][] expectedTokenSequencesVal, */
String[] tokenImageVal public ParseException(Token currentTokenVal,
) int[][] expectedTokenSequencesVal,
{ String[] tokenImageVal
super(""); )
specialConstructor = true; {
currentToken = currentTokenVal; super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
expectedTokenSequences = expectedTokenSequencesVal; currentToken = currentTokenVal;
tokenImage = tokenImageVal; expectedTokenSequences = expectedTokenSequencesVal;
} tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever /**
* purpose you can think of. Constructing the exception in this * The following constructors are for use by you for whatever
* manner makes the exception behave in the normal way - i.e., as * purpose you can think of. Constructing the exception in this
* documented in the class "Throwable". The fields "errorToken", * manner makes the exception behave in the normal way - i.e., as
* "expectedTokenSequences", and "tokenImage" do not contain * documented in the class "Throwable". The fields "errorToken",
* relevant information. The JavaCC generated code does not use * "expectedTokenSequences", and "tokenImage" do not contain
* these constructors. * relevant information. The JavaCC generated code does not use
*/ * these constructors.
*/
public ParseException() {
super(); public ParseException() {
specialConstructor = false; super();
} }
public ParseException(String message) { /** Constructor with message. */
super(message); public ParseException(String message) {
specialConstructor = false; super(message);
} }
/**
* This variable determines which constructor was used to create /**
* this object and thereby affects the semantics of the * This is the last token that has been consumed successfully. If
* "getMessage" method (see below). * this object has been created due to a parse error, the token
*/ * followng this token will (therefore) be the first error token.
protected boolean specialConstructor; */
public Token currentToken;
/**
* This is the last token that has been consumed successfully. If /**
* this object has been created due to a parse error, the token * Each entry in this array is an array of integers. Each array
* followng this token will (therefore) be the first error token. * of integers represents a sequence of tokens (by their ordinal
*/ * values) that is expected at this point of the parse.
public Token currentToken; */
public int[][] expectedTokenSequences;
/**
* Each entry in this array is an array of integers. Each array /**
* of integers represents a sequence of tokens (by their ordinal * This is a reference to the "tokenImage" array of the generated
* values) that is expected at this point of the parse. * parser within which the parse error occurred. This array is
*/ * defined in the generated ...Constants interface.
public int[][] expectedTokenSequences; */
public String[] tokenImage;
/**
* This is a reference to the "tokenImage" array of the generated /**
* parser within which the parse error occurred. This array is * It uses "currentToken" and "expectedTokenSequences" to generate a parse
* defined in the generated ...Constants interface. * error message and returns it. If this object has been created
*/ * due to a parse error, and you do not catch it (it gets thrown
public String[] tokenImage; * from the parser) the correct error message
* gets displayed.
/** */
* This method has the standard behavior when this object has been private static String initialise(Token currentToken,
* created using the standard constructors. Otherwise, it uses int[][] expectedTokenSequences,
* "currentToken" and "expectedTokenSequences" to generate a parse String[] tokenImage) {
* error message and returns it. If this object has been created String eol = System.getProperty("line.separator", "\n");
* due to a parse error, and you do not catch it (it gets thrown StringBuffer expected = new StringBuffer();
* from the parser), then this method is called during the printing int maxSize = 0;
* of the final stack trace, and hence the correct error message for (int i = 0; i < expectedTokenSequences.length; i++) {
* gets displayed. if (maxSize < expectedTokenSequences[i].length) {
*/ maxSize = expectedTokenSequences[i].length;
public String getMessage() { }
if (!specialConstructor) { for (int j = 0; j < expectedTokenSequences[i].length; j++) {
return super.getMessage(); expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
} }
StringBuffer expected = new StringBuffer(); if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
int maxSize = 0; expected.append("...");
for (int i = 0; i < expectedTokenSequences.length; i++) { }
if (maxSize < expectedTokenSequences[i].length) { expected.append(eol).append(" ");
maxSize = expectedTokenSequences[i].length; }
} String retval = "Encountered \"";
for (int j = 0; j < expectedTokenSequences[i].length; j++) { Token tok = currentToken.next;
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" "); for (int i = 0; i < maxSize; i++) {
} if (i != 0) retval += " ";
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { if (tok.kind == 0) {
expected.append("..."); retval += tokenImage[0];
} break;
expected.append(eol).append(" "); }
} retval += " " + tokenImage[tok.kind];
String retval = "Encountered \""; retval += " \"";
Token tok = currentToken.next; retval += add_escapes(tok.image);
for (int i = 0; i < maxSize; i++) { retval += " \"";
if (i != 0) retval += " "; tok = tok.next;
if (tok.kind == 0) { }
retval += tokenImage[0]; retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
break; retval += "." + eol;
} if (expectedTokenSequences.length == 1) {
retval += add_escapes(tok.image); retval += "Was expecting:" + eol + " ";
tok = tok.next; } else {
} retval += "Was expecting one of:" + eol + " ";
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; }
retval += "." + eol; retval += expected.toString();
if (expectedTokenSequences.length == 1) { return retval;
retval += "Was expecting:" + eol + " "; }
} else {
retval += "Was expecting one of:" + eol + " "; /**
} * The end of line string for this machine.
retval += expected.toString(); */
return retval; protected String eol = System.getProperty("line.separator", "\n");
}
/**
/** * Used to convert raw characters to their escaped version
* The end of line string for this machine. * when these raw version cannot be used as part of an ASCII
*/ * string literal.
protected String eol = System.getProperty("line.separator", "\n"); */
static String add_escapes(String str) {
/** StringBuffer retval = new StringBuffer();
* Used to convert raw characters to their escaped version char ch;
* when these raw version cannot be used as part of an ASCII for (int i = 0; i < str.length(); i++) {
* string literal. switch (str.charAt(i))
*/ {
protected String add_escapes(String str) { case 0 :
StringBuffer retval = new StringBuffer(); continue;
char ch; case '\b':
for (int i = 0; i < str.length(); i++) { retval.append("\\b");
switch (str.charAt(i)) continue;
{ case '\t':
case 0 : retval.append("\\t");
continue; continue;
case '\b': case '\n':
retval.append("\\b"); retval.append("\\n");
continue; continue;
case '\t': case '\f':
retval.append("\\t"); retval.append("\\f");
continue; continue;
case '\n': case '\r':
retval.append("\\n"); retval.append("\\r");
continue; continue;
case '\f': case '\"':
retval.append("\\f"); retval.append("\\\"");
continue; continue;
case '\r': case '\'':
retval.append("\\r"); retval.append("\\\'");
continue; continue;
case '\"': case '\\':
retval.append("\\\""); retval.append("\\\\");
continue; continue;
case '\'': default:
retval.append("\\\'"); if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
continue; String s = "0000" + Integer.toString(ch, 16);
case '\\': retval.append("\\u" + s.substring(s.length() - 4, s.length()));
retval.append("\\\\"); } else {
continue; retval.append(ch);
default: }
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { continue;
String s = "0000" + Integer.toString(ch, 16); }
retval.append("\\u" + s.substring(s.length() - 4, s.length())); }
} else { return retval.toString();
retval.append(ch); }
}
continue; }
} /* JavaCC - OriginalChecksum=bf6325585417e7bd5d488795e151433b (do not edit this line) */
}
return retval.toString();
}
}

View File

@ -1,440 +1,469 @@
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */ /* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.1 */
package com.google.gson; /* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.google.gson;
/**
* An implementation of interface CharStream, where the stream is assumed to /**
* contain only ASCII characters (without unicode processing). * An implementation of interface CharStream, where the stream is assumed to
*/ * contain only ASCII characters (without unicode processing).
*/
@SuppressWarnings("all") @SuppressWarnings("all")
final class SimpleCharStream final class SimpleCharStream
{ {
public static final boolean staticFlag = false; /** Whether parser is static. */
int bufsize; public static final boolean staticFlag = false;
int available; int bufsize;
int tokenBegin; int available;
public int bufpos = -1; int tokenBegin;
protected int bufline[]; /** Position in buffer. */
protected int bufcolumn[]; public int bufpos = -1;
protected int bufline[];
protected int column = 0; protected int bufcolumn[];
protected int line = 1;
protected int column = 0;
protected boolean prevCharIsCR = false; protected int line = 1;
protected boolean prevCharIsLF = false;
protected boolean prevCharIsCR = false;
protected java.io.Reader inputStream; protected boolean prevCharIsLF = false;
protected char[] buffer; protected java.io.Reader inputStream;
protected int maxNextCharInd = 0;
protected int inBuf = 0; protected char[] buffer;
protected int tabSize = 8; protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected void setTabSize(int i) { tabSize = i; } protected int tabSize = 8;
protected int getTabSize(int i) { return tabSize; }
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048]; protected void ExpandBuff(boolean wrapAround)
int newbufline[] = new int[bufsize + 2048]; {
int newbufcolumn[] = new int[bufsize + 2048]; char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
try int newbufcolumn[] = new int[bufsize + 2048];
{
if (wrapAround) try
{ {
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); if (wrapAround)
System.arraycopy(buffer, 0, newbuffer, {
bufsize - tokenBegin, bufpos); System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer; System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline; System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn; System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
} maxNextCharInd = (bufpos += (bufsize - tokenBegin));
else }
{ else
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); {
buffer = newbuffer; System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline; System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn; System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
} maxNextCharInd = (bufpos -= tokenBegin);
} }
catch (Throwable t) }
{ catch (Throwable t)
throw new Error(t.getMessage()); {
} throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize; bufsize += 2048;
tokenBegin = 0; available = bufsize;
} tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{ protected void FillBuff() throws java.io.IOException
if (maxNextCharInd == available) {
{ if (maxNextCharInd == available)
if (available == bufsize) {
{ if (available == bufsize)
if (tokenBegin > 2048) {
{ if (tokenBegin > 2048)
bufpos = maxNextCharInd = 0; {
available = tokenBegin; bufpos = maxNextCharInd = 0;
} available = tokenBegin;
else if (tokenBegin < 0) }
bufpos = maxNextCharInd = 0; else if (tokenBegin < 0)
else bufpos = maxNextCharInd = 0;
ExpandBuff(false); else
} ExpandBuff(false);
else if (available > tokenBegin) }
available = bufsize; else if (available > tokenBegin)
else if ((tokenBegin - available) < 2048) available = bufsize;
ExpandBuff(true); else if ((tokenBegin - available) < 2048)
else ExpandBuff(true);
available = tokenBegin; else
} available = tokenBegin;
}
int i;
try { int i;
if ((i = inputStream.read(buffer, maxNextCharInd, try {
available - maxNextCharInd)) == -1) if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{ {
inputStream.close(); inputStream.close();
throw new java.io.IOException(); throw new java.io.IOException();
} }
else else
maxNextCharInd += i; maxNextCharInd += i;
return; return;
} }
catch(java.io.IOException e) { catch(java.io.IOException e) {
--bufpos; --bufpos;
backup(0); backup(0);
if (tokenBegin == -1) if (tokenBegin == -1)
tokenBegin = bufpos; tokenBegin = bufpos;
throw e; throw e;
} }
} }
public char BeginToken() throws java.io.IOException /** Start. */
{ public char BeginToken() throws java.io.IOException
tokenBegin = -1; {
char c = readChar(); tokenBegin = -1;
tokenBegin = bufpos; char c = readChar();
tokenBegin = bufpos;
return c;
} return c;
}
protected void UpdateLineColumn(char c)
{ protected void UpdateLineColumn(char c)
column++; {
column++;
if (prevCharIsLF)
{ if (prevCharIsLF)
prevCharIsLF = false; {
line += (column = 1); prevCharIsLF = false;
} line += (column = 1);
else if (prevCharIsCR) }
{ else if (prevCharIsCR)
prevCharIsCR = false; {
if (c == '\n') prevCharIsCR = false;
{ if (c == '\n')
prevCharIsLF = true; {
} prevCharIsLF = true;
else }
line += (column = 1); else
} line += (column = 1);
}
switch (c)
{ switch (c)
case '\r' : {
prevCharIsCR = true; case '\r' :
break; prevCharIsCR = true;
case '\n' : break;
prevCharIsLF = true; case '\n' :
break; prevCharIsLF = true;
case '\t' : break;
column--; case '\t' :
column += (tabSize - (column % tabSize)); column--;
break; column += (tabSize - (column % tabSize));
default : break;
break; default :
} break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column; bufline[bufpos] = line;
} bufcolumn[bufpos] = column;
}
public char readChar() throws java.io.IOException
{ /** Read a character. */
if (inBuf > 0) public char readChar() throws java.io.IOException
{ {
--inBuf; if (inBuf > 0)
{
if (++bufpos == bufsize) --inBuf;
bufpos = 0;
if (++bufpos == bufsize)
return buffer[bufpos]; bufpos = 0;
}
return buffer[bufpos];
if (++bufpos >= maxNextCharInd) }
FillBuff();
if (++bufpos >= maxNextCharInd)
char c = buffer[bufpos]; FillBuff();
UpdateLineColumn(c); char c = buffer[bufpos];
return (c);
} UpdateLineColumn(c);
return c;
/** }
* @deprecated
* @see #getEndColumn /**
*/ * @deprecated
* @see #getEndColumn
public int getColumn() { */
return bufcolumn[bufpos];
} public int getColumn() {
return bufcolumn[bufpos];
/** }
* @deprecated
* @see #getEndLine /**
*/ * @deprecated
* @see #getEndLine
public int getLine() { */
return bufline[bufpos];
} public int getLine() {
return bufline[bufpos];
public int getEndColumn() { }
return bufcolumn[bufpos];
} /** Get token end column number. */
public int getEndColumn() {
public int getEndLine() { return bufcolumn[bufpos];
return bufline[bufpos]; }
}
/** Get token end line number. */
public int getBeginColumn() { public int getEndLine() {
return bufcolumn[tokenBegin]; return bufline[bufpos];
} }
public int getBeginLine() { /** Get token beginning column number. */
return bufline[tokenBegin]; public int getBeginColumn() {
} return bufcolumn[tokenBegin];
}
public void backup(int amount) {
/** Get token beginning line number. */
inBuf += amount; public int getBeginLine() {
if ((bufpos -= amount) < 0) return bufline[tokenBegin];
bufpos += bufsize; }
}
/** Backup a number of characters. */
public SimpleCharStream(java.io.Reader dstream, int startline, public void backup(int amount) {
int startcolumn, int buffersize)
{ inBuf += amount;
inputStream = dstream; if ((bufpos -= amount) < 0)
line = startline; bufpos += bufsize;
column = startcolumn - 1; }
available = bufsize = buffersize; /** Constructor. */
buffer = new char[buffersize]; public SimpleCharStream(java.io.Reader dstream, int startline,
bufline = new int[buffersize]; int startcolumn, int buffersize)
bufcolumn = new int[buffersize]; {
} inputStream = dstream;
line = startline;
public SimpleCharStream(java.io.Reader dstream, int startline, column = startcolumn - 1;
int startcolumn)
{ available = bufsize = buffersize;
this(dstream, startline, startcolumn, 4096); buffer = new char[buffersize];
} bufline = new int[buffersize];
bufcolumn = new int[buffersize];
public SimpleCharStream(java.io.Reader dstream) }
{
this(dstream, 1, 1, 4096); /** Constructor. */
} public SimpleCharStream(java.io.Reader dstream, int startline,
public void ReInit(java.io.Reader dstream, int startline, int startcolumn)
int startcolumn, int buffersize) {
{ this(dstream, startline, startcolumn, 4096);
inputStream = dstream; }
line = startline;
column = startcolumn - 1; /** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
if (buffer == null || buffersize != buffer.length) {
{ this(dstream, 1, 1, 4096);
available = bufsize = buffersize; }
buffer = new char[buffersize];
bufline = new int[buffersize]; /** Reinitialise. */
bufcolumn = new int[buffersize]; public void ReInit(java.io.Reader dstream, int startline,
} int startcolumn, int buffersize)
prevCharIsLF = prevCharIsCR = false; {
tokenBegin = inBuf = maxNextCharInd = 0; inputStream = dstream;
bufpos = -1; line = startline;
} column = startcolumn - 1;
public void ReInit(java.io.Reader dstream, int startline, if (buffer == null || buffersize != buffer.length)
int startcolumn) {
{ available = bufsize = buffersize;
ReInit(dstream, startline, startcolumn, 4096); buffer = new char[buffersize];
} bufline = new int[buffersize];
bufcolumn = new int[buffersize];
public void ReInit(java.io.Reader dstream) }
{ prevCharIsLF = prevCharIsCR = false;
ReInit(dstream, 1, 1, 4096); tokenBegin = inBuf = maxNextCharInd = 0;
} bufpos = -1;
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, }
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{ /** Reinitialise. */
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); public void ReInit(java.io.Reader dstream, int startline,
} int startcolumn)
{
public SimpleCharStream(java.io.InputStream dstream, int startline, ReInit(dstream, startline, startcolumn, 4096);
int startcolumn, int buffersize) }
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); /** Reinitialise. */
} public void ReInit(java.io.Reader dstream)
{
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, ReInit(dstream, 1, 1, 4096);
int startcolumn) throws java.io.UnsupportedEncodingException }
{ /** Constructor. */
this(dstream, encoding, startline, startcolumn, 4096); public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
} int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
public SimpleCharStream(java.io.InputStream dstream, int startline, this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
int startcolumn) }
{
this(dstream, startline, startcolumn, 4096); /** Constructor. */
} public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
{ this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
this(dstream, encoding, 1, 1, 4096); }
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream) public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
{ int startcolumn) throws java.io.UnsupportedEncodingException
this(dstream, 1, 1, 4096); {
} this(dstream, encoding, startline, startcolumn, 4096);
}
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException /** Constructor. */
{ public SimpleCharStream(java.io.InputStream dstream, int startline,
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); int startcolumn)
} {
this(dstream, startline, startcolumn, 4096);
public void ReInit(java.io.InputStream dstream, int startline, }
int startcolumn, int buffersize)
{ /** Constructor. */
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
} {
this(dstream, encoding, 1, 1, 4096);
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException }
{
ReInit(dstream, encoding, 1, 1, 4096); /** Constructor. */
} public SimpleCharStream(java.io.InputStream dstream)
{
public void ReInit(java.io.InputStream dstream) this(dstream, 1, 1, 4096);
{ }
ReInit(dstream, 1, 1, 4096);
} /** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline, public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{ {
ReInit(dstream, encoding, startline, startcolumn, 4096); ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
} }
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn) /** Reinitialise. */
{ public void ReInit(java.io.InputStream dstream, int startline,
ReInit(dstream, startline, startcolumn, 4096); int startcolumn, int buffersize)
} {
public String GetImage() ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
{ }
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); /** Reinitialise. */
else public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
return new String(buffer, tokenBegin, bufsize - tokenBegin) + {
new String(buffer, 0, bufpos + 1); ReInit(dstream, encoding, 1, 1, 4096);
} }
public char[] GetSuffix(int len) /** Reinitialise. */
{ public void ReInit(java.io.InputStream dstream)
char[] ret = new char[len]; {
ReInit(dstream, 1, 1, 4096);
if ((bufpos + 1) >= len) }
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); /** Reinitialise. */
else public void ReInit(java.io.InputStream dstream, String encoding, int startline,
{ int startcolumn) throws java.io.UnsupportedEncodingException
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, {
len - bufpos - 1); ReInit(dstream, encoding, startline, startcolumn, 4096);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); }
} /** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
return ret; int startcolumn)
} {
ReInit(dstream, startline, startcolumn, 4096);
public void Done() }
{ /** Get token literal value. */
buffer = null; public String GetImage()
bufline = null; {
bufcolumn = null; if (bufpos >= tokenBegin)
} return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
/** return new String(buffer, tokenBegin, bufsize - tokenBegin) +
* Method to adjust line and column numbers for the start of a token. new String(buffer, 0, bufpos + 1);
*/ }
public void adjustBeginLineColumn(int newLine, int newCol)
{ /** Get the suffix. */
int start = tokenBegin; public char[] GetSuffix(int len)
int len; {
char[] ret = new char[len];
if (bufpos >= tokenBegin)
{ if ((bufpos + 1) >= len)
len = bufpos - tokenBegin + inBuf + 1; System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
} else
else {
{ System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len = bufsize - tokenBegin + bufpos + 1 + inBuf; len - bufpos - 1);
} System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0; return ret;
}
while (i < len &&
bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) /** Reset buffer when finished. */
{ public void Done()
bufline[j] = newLine; {
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; buffer = null;
bufcolumn[j] = newCol + columnDiff; bufline = null;
columnDiff = nextColDiff; bufcolumn = null;
i++; }
}
/**
if (i < len) * Method to adjust line and column numbers for the start of a token.
{ */
bufline[j] = newLine++; public void adjustBeginLineColumn(int newLine, int newCol)
bufcolumn[j] = newCol + columnDiff; {
int start = tokenBegin;
while (i++ < len) int len;
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize]) if (bufpos >= tokenBegin)
bufline[j] = newLine++; {
else len = bufpos - tokenBegin + inBuf + 1;
bufline[j] = newLine; }
} else
} {
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
line = bufline[j]; }
column = bufcolumn[j];
} int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
}
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=351e3d8e62614bff24f1b9ba2fd77764 (do not edit this line) */

View File

@ -1,82 +1,131 @@
/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */ /* Generated By:JavaCC: Do not edit this line. Token.java Version 4.1 */
package com.google.gson; /* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.google.gson;
/**
* Describes the input token stream. /**
*/ * Describes the input token stream.
*/
@SuppressWarnings("all") @SuppressWarnings("all")
final class Token { final class Token implements java.io.Serializable {
/** /**
* An integer that describes the kind of this token. This numbering * The version identifier for this Serializable class.
* system is determined by JavaCCParser, and a table of these numbers is * Increment only if the <i>serialized</i> form of the
* stored in the file ...Constants.java. * class changes.
*/ */
public int kind; private static final long serialVersionUID = 1L;
/** /**
* beginLine and beginColumn describe the position of the first character * An integer that describes the kind of this token. This numbering
* of this token; endLine and endColumn describe the position of the * system is determined by JavaCCParser, and a table of these numbers is
* last character of this token. * stored in the file ...Constants.java.
*/ */
public int beginLine, beginColumn, endLine, endColumn; public int kind;
/** /** The line number of the first character of this Token. */
* The string image of the token. public int beginLine;
*/ /** The column number of the first character of this Token. */
public String image; public int beginColumn;
/** The line number of the last character of this Token. */
/** public int endLine;
* A reference to the next regular (non-special) token from the input /** The column number of the last character of this Token. */
* stream. If this is the last token from the input stream, or if the public int endColumn;
* token manager has not read tokens beyond this one, this field is
* set to null. This is true only if this token is also a regular /**
* token. Otherwise, see below for a description of the contents of * The string image of the token.
* this field. */
*/ public String image;
public Token next;
/**
/** * A reference to the next regular (non-special) token from the input
* This field is used to access special tokens that occur prior to this * stream. If this is the last token from the input stream, or if the
* token, but after the immediately preceding regular (non-special) token. * token manager has not read tokens beyond this one, this field is
* If there are no such special tokens, this field is set to null. * set to null. This is true only if this token is also a regular
* When there are more than one such special token, this field refers * token. Otherwise, see below for a description of the contents of
* to the last of these special tokens, which in turn refers to the next * this field.
* previous special token through its specialToken field, and so on */
* until the first special token (whose specialToken field is null). public Token next;
* The next fields of special tokens refer to other special tokens that
* immediately follow it (without an intervening regular token). If there /**
* is no such token, this field is null. * This field is used to access special tokens that occur prior to this
*/ * token, but after the immediately preceding regular (non-special) token.
public Token specialToken; * If there are no such special tokens, this field is set to null.
* When there are more than one such special token, this field refers
/** * to the last of these special tokens, which in turn refers to the next
* Returns the image. * previous special token through its specialToken field, and so on
*/ * until the first special token (whose specialToken field is null).
public String toString() * The next fields of special tokens refer to other special tokens that
{ * immediately follow it (without an intervening regular token). If there
return image; * is no such token, this field is null.
} */
public Token specialToken;
/**
* Returns a new Token object, by default. However, if you want, you /**
* can create and return subclass objects based on the value of ofKind. * An optional attribute value of the Token.
* Simply add the cases to the switch for all those special cases. * Tokens which are not used as syntactic sugar will often contain
* For example, if you have a subclass of Token called IDToken that * meaningful values that will be used later on by the compiler or
* you want to create if ofKind is ID, simlpy add something like : * interpreter. This attribute value is often different from the image.
* * Any subclass of Token that actually wants to return a non-null value can
* case MyParserConstants.ID : return new IDToken(); * override this method as appropriate.
* */
* to the following switch statement. Then you can cast matchedToken public Object getValue() {
* variable to the appropriate type and use it in your lexical actions. return null;
*/ }
public static final Token newToken(int ofKind)
{ /**
switch(ofKind) * No-argument constructor
{ */
default : return new Token(); public Token() {}
}
} /**
* Constructs a new token for the specified Image.
} */
public Token(int kind)
{
this(kind, null);
}
/**
* Constructs a new token for the specified Image and Kind.
*/
public Token(int kind, String image)
{
this.kind = kind;
this.image = image;
}
/**
* Returns the image.
*/
public String toString()
{
return image;
}
/**
* Returns a new Token object, by default. However, if you want, you
* can create and return subclass objects based on the value of ofKind.
* Simply add the cases to the switch for all those special cases.
* For example, if you have a subclass of Token called IDToken that
* you want to create if ofKind is ID, simply add something like :
*
* case MyParserConstants.ID : return new IDToken(ofKind, image);
*
* to the following switch statement. Then you can cast matchedToken
* variable to the appropriate type and use sit in your lexical actions.
*/
public static Token newToken(int ofKind, String image)
{
switch(ofKind)
{
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind)
{
return newToken(ofKind, null);
}
}
/* JavaCC - OriginalChecksum=f683548fa415467062989dfb10c566e6 (do not edit this line) */

View File

@ -1,134 +1,148 @@
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */ /* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 4.1 */
package com.google.gson; /* JavaCCOptions: */
package com.google.gson;
@SuppressWarnings("all")
final class TokenMgrError extends Error /** Token Manager Error. */
{ @SuppressWarnings("all")
/* final class TokenMgrError extends Error
* Ordinals for various reasons why an Error of this type can be thrown. {
*/
/**
/** * The version identifier for this Serializable class.
* Lexical error occured. * Increment only if the <i>serialized</i> form of the
*/ * class changes.
static final int LEXICAL_ERROR = 0; */
private static final long serialVersionUID = 1L;
/**
* An attempt wass made to create a second instance of a static token manager. /*
*/ * Ordinals for various reasons why an Error of this type can be thrown.
static final int STATIC_LEXER_ERROR = 1; */
/** /**
* Tried to change to an invalid lexical state. * Lexical error occurred.
*/ */
static final int INVALID_LEXICAL_STATE = 2; static final int LEXICAL_ERROR = 0;
/** /**
* Detected (and bailed out of) an infinite loop in the token manager. * An attempt was made to create a second instance of a static token manager.
*/ */
static final int LOOP_DETECTED = 3; static final int STATIC_LEXER_ERROR = 1;
/** /**
* Indicates the reason why the exception is thrown. It will have * Tried to change to an invalid lexical state.
* one of the above 4 values. */
*/ static final int INVALID_LEXICAL_STATE = 2;
int errorCode;
/**
/** * Detected (and bailed out of) an infinite loop in the token manager.
* Replaces unprintable characters by their espaced (or unicode escaped) */
* equivalents in the given string static final int LOOP_DETECTED = 3;
*/
protected static final String addEscapes(String str) { /**
StringBuffer retval = new StringBuffer(); * Indicates the reason why the exception is thrown. It will have
char ch; * one of the above 4 values.
for (int i = 0; i < str.length(); i++) { */
switch (str.charAt(i)) int errorCode;
{
case 0 : /**
continue; * Replaces unprintable characters by their escaped (or unicode escaped)
case '\b': * equivalents in the given string
retval.append("\\b"); */
continue; protected static final String addEscapes(String str) {
case '\t': StringBuffer retval = new StringBuffer();
retval.append("\\t"); char ch;
continue; for (int i = 0; i < str.length(); i++) {
case '\n': switch (str.charAt(i))
retval.append("\\n"); {
continue; case 0 :
case '\f': continue;
retval.append("\\f"); case '\b':
continue; retval.append("\\b");
case '\r': continue;
retval.append("\\r"); case '\t':
continue; retval.append("\\t");
case '\"': continue;
retval.append("\\\""); case '\n':
continue; retval.append("\\n");
case '\'': continue;
retval.append("\\\'"); case '\f':
continue; retval.append("\\f");
case '\\': continue;
retval.append("\\\\"); case '\r':
continue; retval.append("\\r");
default: continue;
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { case '\"':
String s = "0000" + Integer.toString(ch, 16); retval.append("\\\"");
retval.append("\\u" + s.substring(s.length() - 4, s.length())); continue;
} else { case '\'':
retval.append(ch); retval.append("\\\'");
} continue;
continue; case '\\':
} retval.append("\\\\");
} continue;
return retval.toString(); default:
} if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
/** retval.append("\\u" + s.substring(s.length() - 4, s.length()));
* Returns a detailed message for the Error when it is thrown by the } else {
* token manager to indicate a lexical error. retval.append(ch);
* Parameters : }
* EOFSeen : indicates if EOF caused the lexicl error continue;
* curLexState : lexical state in which this error occured }
* errorLine : line number when the error occured }
* errorColumn : column number when the error occured return retval.toString();
* errorAfter : prefix that was seen before this error occured }
* curchar : the offending character
* Note: You can customize the lexical error message by modifying this method. /**
*/ * Returns a detailed message for the Error when it is thrown by the
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { * token manager to indicate a lexical error.
return("Lexical error at line " + * Parameters :
errorLine + ", column " + * EOFSeen : indicates if EOF caused the lexical error
errorColumn + ". Encountered: " + * curLexState : lexical state in which this error occurred
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + * errorLine : line number when the error occurred
"after : \"" + addEscapes(errorAfter) + "\""); * errorColumn : column number when the error occurred
} * errorAfter : prefix that was seen before this error occurred
* curchar : the offending character
/** * Note: You can customize the lexical error message by modifying this method.
* You can also modify the body of this method to customize your error messages. */
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
* of end-users concern, so you can return something like : return("Lexical error at line " +
* errorLine + ", column " +
* "Internal Error : Please file a bug report .... " errorColumn + ". Encountered: " +
* (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
* from this method for such cases in the release version of your parser. "after : \"" + addEscapes(errorAfter) + "\"");
*/ }
public String getMessage() {
return super.getMessage(); /**
} * You can also modify the body of this method to customize your error messages.
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
/* * of end-users concern, so you can return something like :
* Constructors of various flavors follow. *
*/ * "Internal Error : Please file a bug report .... "
*
public TokenMgrError() { * from this method for such cases in the release version of your parser.
} */
public String getMessage() {
public TokenMgrError(String message, int reason) { return super.getMessage();
super(message); }
errorCode = reason;
} /*
* Constructors of various flavors follow.
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { */
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
} /** No arg constructor. */
} public TokenMgrError() {
}
/** Constructor with message and reason. */
public TokenMgrError(String message, int reason) {
super(message);
errorCode = reason;
}
/** Full Constructor. */
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
}
}
/* JavaCC - OriginalChecksum=f9c23e3fca926dbaf51c810110262be0 (do not edit this line) */

View File

@ -116,20 +116,29 @@ private JsonPrimitive JsonMemberName() :
private JsonArray JsonArray() : private JsonArray JsonArray() :
{ JsonArray array = new JsonArray(); } { JsonArray array = new JsonArray(); }
{ {
"[" [ Elements(array) ] "]" "[" (
{ array=JsonArrayEmpty(array) {return array;} |
array.reverse(); JsonArrayElement(array) (JsonArrayNextElement(array))* "]" {return array; } )
return array;
}
} }
private void Elements(JsonArray array) : private JsonArray JsonArrayEmpty(JsonArray array) :
{ }
{ {
JsonElement element; "]" { return array; }
} }
private JsonArray JsonArrayElement(JsonArray array) :
{ JsonElement element = null; }
{ {
element=JsonValue() [ "," Elements(array) ] element=JsonValue() {array.add(element);}
{ array.add(element); } { return array; }
}
private JsonArray JsonArrayNextElement(JsonArray array) :
{ JsonElement element = null; }
{
"," element=JsonValue() {array.add(element);}
{ return array; }
} }
private JsonElement JsonValue() : private JsonElement JsonValue() :

View File

@ -18,6 +18,7 @@ package com.google.gson.functional;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.google.gson.common.MoreAsserts; import com.google.gson.common.MoreAsserts;
import com.google.gson.common.TestTypes.BagOfPrimitives; import com.google.gson.common.TestTypes.BagOfPrimitives;
import com.google.gson.common.TestTypes.CrazyLongTypeAdapter; import com.google.gson.common.TestTypes.CrazyLongTypeAdapter;
@ -55,6 +56,15 @@ public class ArrayTest extends TestCase {
MoreAsserts.assertEquals(expected, actual); MoreAsserts.assertEquals(expected, actual);
} }
public void testInvalidArrayDeserialization() {
String json = "[1, 2 3, 4, 5]";
try {
gson.fromJson(json, int[].class);
fail("Gson should not deserialize array elements with missing ,");
} catch (JsonParseException expected) {
}
}
public void testEmptyArraySerialization() { public void testEmptyArraySerialization() {
int[] target = {}; int[] target = {};
assertEquals("[]", gson.toJson(target)); assertEquals("[]", gson.toJson(target));
@ -66,7 +76,10 @@ public class ArrayTest extends TestCase {
Integer[] actualObject2 = gson.fromJson("[]", Integer[].class); Integer[] actualObject2 = gson.fromJson("[]", Integer[].class);
assertTrue(actualObject2.length == 0); assertTrue(actualObject2.length == 0);
}
actualObject = gson.fromJson("[ ]", int[].class);
assertTrue(actualObject.length == 0);
}
public void testNullsInArraySerialization() { public void testNullsInArraySerialization() {
String[] array = {"foo", null, "bar"}; String[] array = {"foo", null, "bar"};

View File

@ -117,16 +117,18 @@ public class ObjectTest extends TestCase {
} }
public void testClassWithTransientFieldsSerialization() throws Exception { public void testClassWithTransientFieldsSerialization() throws Exception {
ClassWithTransientFields target = new ClassWithTransientFields(1L); ClassWithTransientFields<Long> target = new ClassWithTransientFields<Long>(1L);
assertEquals(target.getExpectedJson(), gson.toJson(target)); assertEquals(target.getExpectedJson(), gson.toJson(target));
} }
@SuppressWarnings("unchecked")
public void testClassWithTransientFieldsDeserialization() throws Exception { public void testClassWithTransientFieldsDeserialization() throws Exception {
String json = "{\"longValue\":[1]}"; String json = "{\"longValue\":[1]}";
ClassWithTransientFields target = gson.fromJson(json, ClassWithTransientFields.class); ClassWithTransientFields target = gson.fromJson(json, ClassWithTransientFields.class);
assertEquals(json, target.getExpectedJson()); assertEquals(json, target.getExpectedJson());
} }
@SuppressWarnings("unchecked")
public void testClassWithTransientFieldsDeserializationTransientFieldsPassedInJsonAreIgnored() public void testClassWithTransientFieldsDeserializationTransientFieldsPassedInJsonAreIgnored()
throws Exception { throws Exception {
String json = "{\"transientLongValue\":1,\"longValue\":[1]}"; String json = "{\"transientLongValue\":1,\"longValue\":[1]}";

View File

@ -148,9 +148,9 @@ public class PerformanceTest extends TestCase {
/** /**
* Created in response to http://code.google.com/p/google-gson/issues/detail?id=96 * Created in response to http://code.google.com/p/google-gson/issues/detail?id=96
*/ */
// Last I tested, Gson was able to deserialize a byte array of 80KB // Last I tested, Gson was able to deserialize a byte array of 11MB
public void disable_testByteArrayDeserialization() { public void disable_testByteArrayDeserialization() {
for (int numElements = 32768; true; numElements += 4096) { for (int numElements = 10639296; true; numElements += 16384) {
StringBuilder sb = new StringBuilder(numElements*2); StringBuilder sb = new StringBuilder(numElements*2);
sb.append("["); sb.append("[");
boolean first = true; boolean first = true;