first sketch to get rid of nasty self implemented stack
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
index 27fcbe2..960761a 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
@@ -24,6 +24,7 @@
import java.io.Reader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
+import java.util.ArrayDeque;
import java.util.NoSuchElementException;
import javax.json.JsonException;
@@ -93,19 +94,7 @@
//This can only be determined by build up a stack which tracks the trail of Json objects and arrays
//This stack here is only needed for validating the above mentioned case, if we want to be lenient we can skip suing the stack.
//Stack can cause out of memory issues when the nesting depth of a Json stream is too deep.
- private StructureElement currentStructureElement = null;
-
- //minimal stack implementation
- private static final class StructureElement {
- final StructureElement previous;
- final boolean isArray;
-
- StructureElement(final StructureElement previous, final boolean isArray) {
- super();
- this.previous = previous;
- this.isArray = isArray;
- }
- }
+ private ArrayDeque<Boolean> stack = new ArrayDeque<Boolean>(100);
//detect charset according to RFC 4627
public JsonStreamParserImpl(final InputStream inputStream, final int maxStringLength,
@@ -180,7 +169,7 @@
@Override
public final boolean hasNext() {
- if (currentStructureElement != null || (previousEvent != END_ARRAY && previousEvent != END_OBJECT) || previousEvent == 0) {
+ if (stack.peek() != null || (previousEvent != END_ARRAY && previousEvent != END_OBJECT) || previousEvent == 0) {
return true;
}
@@ -326,7 +315,7 @@
throw new NoSuchElementException();
}
- if (previousEvent != 0 && currentStructureElement == null) {
+ if (previousEvent != 0 && stack.peek() == null) {
throw uexc("Unexpected end of structure");
}
@@ -431,35 +420,29 @@
throw uexc("Expected : , [");
}
- //push upon the stack
- if (currentStructureElement == null) {
- currentStructureElement = new StructureElement(null, false);
- } else {
- if(!currentStructureElement.isArray && previousEvent != KEY_SEPARATOR_EVENT) {
- throw uexc("Expected :");
- }
- final StructureElement localStructureElement = new StructureElement(currentStructureElement, false);
- currentStructureElement = localStructureElement;
+ if(stack.peek() == Boolean.FALSE && previousEvent != KEY_SEPARATOR_EVENT) {
+ throw uexc("Expected \"");
}
- return EVT_MAP[previousEvent = START_OBJECT];
+ stack.push(Boolean.FALSE);
+ return EVT_MAP[previousEvent = START_OBJECT];
}
private Event handleEndObject() {
//last event must one of the following-> " ] { } LITERAL
if (previousEvent == START_ARRAY || previousEvent == COMMA_EVENT || previousEvent == KEY_NAME
- || previousEvent == KEY_SEPARATOR_EVENT || currentStructureElement == null) {
+ || previousEvent == KEY_SEPARATOR_EVENT || stack.peek() == null) {
throw uexc("Expected \" ] { } LITERAL");
}
- if (currentStructureElement.isArray) {
+ if (stack.peek() == Boolean.TRUE) {
throw uexc("Expected : ]");
}
//pop from stack
- currentStructureElement = currentStructureElement.previous;
+ stack.pop();
return EVT_MAP[previousEvent = END_OBJECT];
}
@@ -472,15 +455,11 @@
}
//push upon the stack
- if (currentStructureElement == null) {
- currentStructureElement = new StructureElement(null, true);
- } else {
- if(!currentStructureElement.isArray && previousEvent != KEY_SEPARATOR_EVENT) {
- throw uexc("Expected \"");
- }
- final StructureElement localStructureElement = new StructureElement(currentStructureElement, true);
- currentStructureElement = localStructureElement;
+ if(stack.peek() == Boolean.FALSE && previousEvent != KEY_SEPARATOR_EVENT) {
+ throw uexc("Expected \"");
}
+
+ stack.push(Boolean.TRUE);
return EVT_MAP[previousEvent = START_ARRAY];
}
@@ -489,16 +468,16 @@
//last event must one of the following-> [ ] } " LITERAL
if (previousEvent == START_OBJECT || previousEvent == COMMA_EVENT || previousEvent == KEY_SEPARATOR_EVENT
- || currentStructureElement == null) {
+ || stack.peek() == null) {
throw uexc("Expected [ ] } \" LITERAL");
}
- if (!currentStructureElement.isArray) {
+ if (stack.peek() == Boolean.FALSE) {
throw uexc("Expected : }");
}
//pop from stack
- currentStructureElement = currentStructureElement.previous;
+ stack.pop();
return EVT_MAP[previousEvent = END_ARRAY];
}
@@ -639,12 +618,13 @@
//starting quote already consumed
readString();
//end quote already consumed
-
+ Boolean state = stack.peek();
//make the decision if its an key or value
if (previousEvent == KEY_SEPARATOR_EVENT) {
//must be value
- if (currentStructureElement != null && currentStructureElement.isArray) {
+
+ if (state != null && state == Boolean.TRUE) {
//not in array, only allowed within array
throw uexc("Key value pair not allowed in an array");
}
@@ -654,7 +634,7 @@
} else { //Event is START_OBJECT OR START_ARRAY OR COMMA_EVENT
//must be a key if we are in an object, if not its a value
- if (currentStructureElement != null && currentStructureElement.isArray) {
+ if (state != null && state == Boolean.TRUE) {
return EVT_MAP[previousEvent = VALUE_STRING];
}
@@ -781,7 +761,7 @@
throw uexc("Expected : , [");
}
- if (previousEvent == COMMA_EVENT && !currentStructureElement.isArray) {
+ if (previousEvent == COMMA_EVENT && stack.peek() == Boolean.FALSE) {
//only allowed within array
throw uexc("Not in an array context");
}