You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2014/07/07 07:59:32 UTC
[5/5] git commit: forgotten files from Hendrik Saly patch - sorry
forgotten files from Hendrik Saly patch - sorry
Project: http://git-wip-us.apache.org/repos/asf/incubator-fleece/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-fleece/commit/9fc85e49
Tree: http://git-wip-us.apache.org/repos/asf/incubator-fleece/tree/9fc85e49
Diff: http://git-wip-us.apache.org/repos/asf/incubator-fleece/diff/9fc85e49
Branch: refs/heads/master
Commit: 9fc85e49ceb0ad28cf80a6556f5ecada46349527
Parents: 64b94e6
Author: Romain Manni-Bucau <rm...@gmail.com>
Authored: Mon Jul 7 07:59:19 2014 +0200
Committer: Romain Manni-Bucau <rm...@gmail.com>
Committed: Mon Jul 7 07:59:19 2014 +0200
----------------------------------------------------------------------
.../fleece/core/JsonBaseStreamParser.java | 823 +
.../fleece/core/JsonCharBufferStreamParser.java | 128 +
.../src/test/resources/bench/big_600kb.json | 21170 ++++++++
.../src/test/resources/bench/huge_1mb.json | 44003 +++++++++++++++++
.../src/test/resources/bench/large_130kb.json | 4328 ++
.../src/test/resources/bench/medium_11kb.json | 443 +
.../src/test/resources/bench/small_3kb.json | 86 +
.../src/test/resources/bench/tiny_50b.json | 5 +
.../resources/bench/unicode_chars_170kb.json | Bin 0 -> 178048 bytes
.../resources/bench/unicode_chars_huge.json | Bin 0 -> 1424384 bytes
.../src/test/resources/bench/unicodes.json | Bin 0 -> 178048 bytes
.../src/test/resources/bench/unicodes_big.json | Bin 0 -> 1424384 bytes
fleece-core/src/test/resources/json/empty.json | 1 +
.../src/test/resources/json/emptyarray.json | 3 +
.../src/test/resources/json/fails/fail1.json | 8 +
.../src/test/resources/json/fails/fail10.json | 7 +
.../src/test/resources/json/fails/fail11.json | 8 +
.../src/test/resources/json/fails/fail12.json | 8 +
.../src/test/resources/json/fails/fail13.json | 8 +
.../src/test/resources/json/fails/fail14.json | 8 +
.../src/test/resources/json/fails/fail15.json | 11 +
.../src/test/resources/json/fails/fail16.json | 9 +
.../src/test/resources/json/fails/fail17.json | 9 +
.../src/test/resources/json/fails/fail18.json | 11 +
.../src/test/resources/json/fails/fail19.json | 10 +
.../src/test/resources/json/fails/fail2.json | 8 +
.../src/test/resources/json/fails/fail20.json | 10 +
.../src/test/resources/json/fails/fail21.json | 10 +
.../src/test/resources/json/fails/fail22.json | 1 +
.../src/test/resources/json/fails/fail23.json | 8 +
.../src/test/resources/json/fails/fail24.json | 5 +
.../src/test/resources/json/fails/fail25.json | 8 +
.../src/test/resources/json/fails/fail3.json | 8 +
.../src/test/resources/json/fails/fail4.json | 8 +
.../src/test/resources/json/fails/fail5.json | 8 +
.../src/test/resources/json/fails/fail6.json | 8 +
.../src/test/resources/json/fails/fail7.json | 8 +
.../src/test/resources/json/fails/fail8.json | 8 +
.../src/test/resources/json/fails/fail9.json | 8 +
.../src/test/resources/json/special.json | 18 +
.../src/test/resources/json/stringescape.json | 3 +
.../src/test/resources/json/unicode.json | 10 +
42 files changed, 71224 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-fleece/blob/9fc85e49/fleece-core/src/main/java/org/apache/fleece/core/JsonBaseStreamParser.java
----------------------------------------------------------------------
diff --git a/fleece-core/src/main/java/org/apache/fleece/core/JsonBaseStreamParser.java b/fleece-core/src/main/java/org/apache/fleece/core/JsonBaseStreamParser.java
new file mode 100644
index 0000000..fbec4a2
--- /dev/null
+++ b/fleece-core/src/main/java/org/apache/fleece/core/JsonBaseStreamParser.java
@@ -0,0 +1,823 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fleece.core;
+
+import static org.apache.fleece.core.Strings.asEscapedChar;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.NoSuchElementException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.json.JsonException;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParsingException;
+
+public abstract class JsonBaseStreamParser implements JsonChars,
+ EscapedStringAwareJsonParser {
+ private static final Logger LOGGER = Logger.getLogger(JsonBaseStreamParser.class.getName());
+ private static final boolean LOG = LOGGER.isLoggable(Level.FINE);
+
+ // private static BufferCache<char[]> VBUFFER_CACHE;
+
+ private final int maxStringSize;
+
+ // current state
+ private Event event = null;
+ private Event lastEvent = null;
+ private int lastSignificantChar = -1;
+
+ private final char[] currentValue;
+ private int valueLength = 0;
+
+ // location
+ private int line = 1;
+ private int column = 1;
+ private int offset = 0;
+
+ private boolean constructingStringValue = false;
+ private boolean withinArray = false;
+ private boolean stringValueIsKey = false;
+
+ private int openObjects = 0;
+ private int openArrays = 0;
+ private boolean escaped = false;
+
+ protected JsonBaseStreamParser(final int maxStringLength) {
+
+ /*
+ * if(VBUFFER_CACHE == null) { VBUFFER_CACHE = new BufferCache<char[]>(
+ * maxStringLength) {
+ *
+ * @Override protected char[] newValue(final int defaultSize) { return
+ * new char[defaultSize]; } };}
+ */
+
+ this.maxStringSize = maxStringLength < 0 ? 8192 : maxStringLength;
+ // currentValue = VBUFFER_CACHE.getCache();
+ currentValue = new char[maxStringLength];
+ }
+
+ private void appendValue(final char c) {
+ if (valueLength >= maxStringSize) {
+ throw new JsonParsingException("to many chars", createLocation());
+ }
+
+ currentValue[valueLength] = c;
+ valueLength++;
+ }
+
+ private void resetValue() {
+ valueLength = 0;
+
+ }
+
+ private String getValue() {
+ return new String(currentValue, 0, valueLength);
+ }
+
+ @Override
+ public final boolean hasNext() {
+
+ if (event == null) {
+ return true;
+ }
+
+ return !(openArrays == 0 && openObjects == 0);
+
+ }
+
+ private static boolean isAsciiDigit(final char value) {
+ return value >= ZERO && value <= NINE;
+ }
+
+ private static boolean isHexDigit(final char value) {
+ return isAsciiDigit(value) || (value >= 'a' && value <= 'f')
+ || (value >= 'A' && value <= 'F');
+ }
+
+ private JsonLocationImpl createLocation() {
+ return new JsonLocationImpl(line, column, offset);
+ }
+
+ private boolean ifConstructingStringValueAdd(char c) throws IOException {
+ if (escaped) {
+
+ if (c == 'u') {
+ final char[] tmp = read(4);
+
+ for (int i = 0; i < tmp.length; i++) {
+ if (!isHexDigit(tmp[i])) {
+ throw new JsonParsingException("unexpected character "
+ + tmp[i], createLocation());
+ }
+ }
+
+ if (LOG) {
+ LOGGER.fine((int) tmp[3] + "/" + (int) tmp[2] + "/"
+ + (int) tmp[1] + "/" + (int) tmp[0]);
+ }
+
+ final int decimal = ((tmp[3]) - 48) * 1 + ((tmp[2]) - 48) * 16
+ + ((tmp[1]) - 48) * 256 + ((tmp[0]) - 48) * 4096;
+ c = (char) decimal;
+
+ } else {
+ c = asEscapedChar(c);
+ }
+
+ escaped = false;
+ }
+
+ return ifConstructingStringValueAdd(c, false);
+ }
+
+ private boolean ifConstructingStringValueAdd(final char c,
+ final boolean escape) {
+ if (constructingStringValue) {
+
+ appendValue(escape ? Strings.asEscapedChar(c) : c);
+ }
+ return constructingStringValue;
+ }
+
+ protected abstract char readNextChar() throws IOException;
+
+ protected abstract void mark();
+
+ private void resetToMark() {
+
+ reset();
+ offset--;
+ column--;
+ }
+
+ protected abstract void reset();
+
+ private char read() throws IOException {
+ final char c = readNextChar();
+
+ if (LOG) {
+ LOGGER.fine("reading: " + c + " -> " + ((int) c));
+ }
+
+ if (c == -1) {
+ // hasNext = false;
+ throw new NoSuchElementException();
+ }
+
+ offset++;
+ column++;
+
+ return c;
+ }
+
+ private char[] read(final int count) throws IOException {
+ final char[] tmp = new char[count];
+
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = read();
+
+ }
+
+ return tmp;
+ }
+
+ // Event.START_ARRAY
+ // Event.START_OBJECT
+
+ // Event.END_ARRAY
+ // Event.END_OBJECT
+
+ // Event.KEY_NAME
+
+ // ** 5 Value Event
+ // Event.VALUE_FALSE
+ // Event.VALUE_NULL
+ // Event.VALUE_NUMBER
+ // Event.VALUE_STRING
+ // Event.VALUE_TRUE
+
+ // ***********************
+ // ***********************
+ // Significant chars (8)
+
+ // 0 - start doc
+ // " - quote
+ // , - comma
+
+ // : - separator
+ // { - start obj
+ // } - end obj
+ // [ - start arr
+ // ] - end arr
+
+ @Override
+ public final Event next() {
+
+ int dosCount = 0;
+ lastEvent = event;
+ event = null;
+
+ resetValue();
+
+ try {
+ while (true) {
+ final char c = read();
+
+ switch (c) {
+
+ case START_OBJECT_CHAR:
+
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ handleStartObject(c);
+
+ break;
+
+ case END_OBJECT_CHAR:
+
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ handleEndObject(c);
+
+ break;
+ case START_ARRAY_CHAR:
+
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ handleStartArray(c);
+
+ break;
+ case END_ARRAY_CHAR:
+
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ handleEndArray(c);
+ break;
+ case EOL:
+ if (ifConstructingStringValueAdd(c)) {
+ throw new JsonParsingException("Unexpected character "
+ + c + " (" + (int) c + ")", createLocation());
+ }
+ line++;
+ continue; // eol no allowed within a value
+
+ case TAB:
+ case CR:
+ case SPACE:
+ if (ifConstructingStringValueAdd(c)) { // escaping
+
+ continue;
+
+ } else {
+ // dos check
+ if (dosCount >= maxStringSize) {
+ throw new JsonParsingException(
+ "max string size reached", createLocation());
+ }
+ dosCount++;
+ }
+
+ break;
+ case COMMA:
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ if (lastSignificantChar >= 0
+ && (char) lastSignificantChar != QUOTE
+ && (char) lastSignificantChar != END_ARRAY_CHAR
+ && (char) lastSignificantChar != END_OBJECT_CHAR) {
+ throw new JsonParsingException("Unexpected character "
+ + c + " (last significant was "
+ + lastSignificantChar + ")", createLocation());
+ }
+
+ lastSignificantChar = c;
+
+ stringValueIsKey = true;
+ if (LOG) {
+ LOGGER.fine(" VAL_IS_KEY");
+ }
+
+ break;
+ case KEY_SEPARATOR:
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ if (lastSignificantChar >= 0
+ && (char) lastSignificantChar != QUOTE) {
+ throw new JsonParsingException("Unexpected character "
+ + c, createLocation());
+ }
+
+ lastSignificantChar = c;
+
+ stringValueIsKey = false;
+ if (LOG) {
+ LOGGER.fine(" VAL_IS_VALUE");
+ }
+
+ break;
+
+ case QUOTE: // must be escaped within a value
+
+ if (handleQuote(c)) {
+ continue;
+ } else {
+ break;
+ }
+
+ // non string values (literals)
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case MINUS:
+ case FALSE_F: // false
+ case TRUE_T: // true
+ case NULL_N: // null
+
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+
+ handleLiteral(c);
+
+ break;
+
+ // escape char
+ case ESCAPE_CHAR:// must be escaped within a value
+ if (!constructingStringValue) {
+ throw new JsonParsingException("Unexpected character "
+ + c, createLocation());
+ }
+
+ if (escaped) {
+ if (LOG) {
+ LOGGER.fine(" ESCAPEDESCAPED");
+ }
+
+ appendValue(ESCAPE_CHAR);
+ escaped = false;
+ } else {
+ if (LOG) {
+ LOGGER.fine(" ESCAPECHAR");
+ }
+ escaped = true;
+ }
+
+ break;
+
+ // eof
+ case EOF:
+
+ throw new NoSuchElementException();
+
+ default:
+ if (ifConstructingStringValueAdd(c)) {
+ continue;
+ }
+ lastSignificantChar = -2;
+ throw new JsonParsingException("Unexpected character " + c,
+ createLocation());
+
+ }
+
+ if (event != null) {
+
+ if (LOG) {
+ LOGGER.fine(" +++ +++ +++ +++ +++ +++" + event
+ + "::" + getValue());
+ }
+
+ return event;
+
+ }
+
+ }
+ } catch (final IOException e) {
+ new JsonParsingException("Unexpected IO Excpetion", e,
+ createLocation());
+ }
+
+ throw new JsonParsingException("Unexpected error due to invalid json",
+ createLocation());
+ }
+
+ private void handleStartObject(final char c) {
+
+ if (LOG) {
+ LOGGER.fine(" LASIC " + lastSignificantChar);
+ }
+
+ if (lastSignificantChar == -2
+ || (lastSignificantChar != -1
+ && (char) lastSignificantChar != KEY_SEPARATOR
+ && (char) lastSignificantChar != COMMA && (char) lastSignificantChar != START_ARRAY_CHAR)) {
+ throw new JsonParsingException("Unexpected character " + c
+ + " (last significant was " + lastSignificantChar + ")",
+ createLocation());
+ }
+
+ stringValueIsKey = true;
+ withinArray = false;
+ if (LOG) {
+ LOGGER.fine(" VAL_IS_KEY");
+ }
+
+ lastSignificantChar = c;
+ openObjects++;
+ event = Event.START_OBJECT;
+
+ }
+
+ private void handleEndObject(final char c) {
+ if (lastSignificantChar >= 0
+ && (char) lastSignificantChar != START_OBJECT_CHAR
+ && (char) lastSignificantChar != END_ARRAY_CHAR
+ && (char) lastSignificantChar != QUOTE
+ && (char) lastSignificantChar != END_OBJECT_CHAR) {
+ throw new JsonParsingException("Unexpected character " + c
+ + " (last significant was " + lastSignificantChar + ")",
+ createLocation());
+ }
+
+ if (openObjects == 0) {
+ throw new JsonParsingException("Unexpected character " + c,
+ createLocation());
+ }
+
+ lastSignificantChar = c;
+ openObjects--;
+ event = Event.END_OBJECT;
+ }
+
+ private void handleStartArray(final char c) {
+ withinArray = true;
+
+ if (lastSignificantChar == -2
+ || (lastSignificantChar != -1
+ && (char) lastSignificantChar != KEY_SEPARATOR
+ && (char) lastSignificantChar != COMMA && (char) lastSignificantChar != START_ARRAY_CHAR)) {
+ throw new JsonParsingException("Unexpected character " + c
+ + " (last significant was " + lastSignificantChar + ")",
+ createLocation());
+ }
+
+ lastSignificantChar = c;
+ openArrays++;
+ event = Event.START_ARRAY;
+ }
+
+ private void handleEndArray(final char c) {
+ withinArray = false;
+
+ if (lastSignificantChar >= 0
+ && (char) lastSignificantChar != START_ARRAY_CHAR
+ && (char) lastSignificantChar != END_ARRAY_CHAR
+ && (char) lastSignificantChar != END_OBJECT_CHAR
+ && (char) lastSignificantChar != QUOTE) {
+ throw new JsonParsingException("Unexpected character " + c
+ + " (last significant was " + lastSignificantChar + ")",
+ createLocation());
+ }
+
+ if (openArrays == 0) {
+ throw new JsonParsingException("Unexpected character " + c,
+ createLocation());
+ }
+
+ lastSignificantChar = c;
+ openArrays--;
+
+ event = Event.END_ARRAY;
+ }
+
+ private boolean handleQuote(final char c) {
+
+ if (lastSignificantChar >= 0 && (char) lastSignificantChar != QUOTE
+ && (char) lastSignificantChar != KEY_SEPARATOR
+ && (char) lastSignificantChar != START_OBJECT_CHAR
+ && (char) lastSignificantChar != START_ARRAY_CHAR
+ && (char) lastSignificantChar != COMMA) {
+ throw new JsonParsingException("Unexpected character " + c
+ + " (last significant was " + lastSignificantChar + ")",
+ createLocation());
+ }
+
+ lastSignificantChar = c;
+
+ if (constructingStringValue) {
+
+ if (escaped) {
+ appendValue(QUOTE);
+ escaped = false;
+ return true;
+ } else {
+
+ if (!withinArray && stringValueIsKey) {
+ event = Event.KEY_NAME;
+ stringValueIsKey = false;
+ if (LOG) {
+ LOGGER.fine(" VAL_IS_VALUE");
+ }
+ } else {
+
+ if (lastEvent != Event.KEY_NAME && !withinArray) {
+ throw new JsonParsingException("Unexpected character "
+ + c + " (lastevent " + lastEvent
+ + ", comma missing)", createLocation());
+ }
+
+ // string value end
+ event = Event.VALUE_STRING;
+ }
+
+ constructingStringValue = false;
+
+ return false;
+ }
+ } else {
+
+ if (escaped) {
+ throw new JsonParsingException("Unexpected character " + c,
+ createLocation());
+ }
+
+ // string value start
+ resetValue();
+ constructingStringValue = true;
+ return false;
+ }
+
+ }
+
+ private void handleLiteral(final char c) throws IOException {
+ if (lastSignificantChar >= 0 && lastSignificantChar != KEY_SEPARATOR
+ && lastSignificantChar != COMMA
+ && lastSignificantChar != START_ARRAY_CHAR) {
+ throw new JsonParsingException("unexpected character " + c,
+ createLocation());
+ }
+
+ lastSignificantChar = -2;
+
+ resetValue();
+
+ if (lastSignificantChar != QUOTE) {
+ // probe literals
+ switch (c) {
+ case TRUE_T:
+ final char[] tmpt = read(3);
+ if (tmpt[0] != TRUE_R || tmpt[1] != TRUE_U || tmpt[2] != TRUE_E) {
+ throw new JsonParsingException("Unexpected literal " + c
+ + new String(tmpt), createLocation());
+ }
+ event = Event.VALUE_TRUE;
+ break;
+ case FALSE_F:
+ final char[] tmpf = read(4);
+ if (tmpf[0] != FALSE_A || tmpf[1] != FALSE_L
+ || tmpf[2] != FALSE_S || tmpf[3] != FALSE_E) {
+ throw new JsonParsingException("Unexpected literal " + c
+ + new String(tmpf), createLocation());
+ }
+
+ event = Event.VALUE_FALSE;
+ break;
+ case NULL_N:
+ final char[] tmpn = read(3);
+ if (tmpn[0] != NULL_U || tmpn[1] != NULL_L || tmpn[2] != NULL_L) {
+ throw new JsonParsingException("Unexpected literal " + c
+ + new String(tmpn), createLocation());
+ }
+ event = Event.VALUE_NULL;
+ break;
+
+ default: // number
+ appendValue(c);
+
+ boolean endExpected = false;
+ final boolean zeropassed = c == '0';
+ boolean dotpassed = false;
+ boolean epassed = false;
+ char last = c;
+ int i = -1;
+
+ while (true) {
+ i++;
+
+ if (LOG) {
+ LOGGER.fine("while i:" + i);
+ }
+
+ final char n = read();
+ mark();
+
+ if (n == COMMA || n == END_ARRAY_CHAR
+ || n == END_OBJECT_CHAR) {
+ resetToMark();
+
+ event = Event.VALUE_NUMBER;
+ break;
+ }
+
+ if (n == EOL) {
+ last = n;
+ continue;
+ }
+
+ if (endExpected && n != SPACE && n != TAB && n != CR) {
+ throw new JsonParsingException("unexpected character "
+ + n + " (" + (int) n + ")", createLocation());
+ }
+
+ if (n == SPACE || n == TAB || n == CR) {
+ endExpected = true;
+ last = n;
+ continue;
+ }
+
+ if (!isNumber(n)) {
+ throw new JsonParsingException("unexpected character "
+ + n, createLocation());
+ }
+
+ // minus only allowed as first char or after e/E
+ if (n == MINUS && i != 0 && last != EXP_LOWERCASE
+ && last != EXP_UPPERCASE) {
+ throw new JsonParsingException("unexpected character "
+ + n, createLocation());
+ }
+
+ // plus only allowed after e/E
+ if (n == PLUS && last != EXP_LOWERCASE
+ && last != EXP_UPPERCASE) {
+ throw new JsonParsingException("unexpected character "
+ + n, createLocation());
+ }
+
+ if (!dotpassed && zeropassed && i == 0 && n != DOT) {
+ throw new JsonParsingException("unexpected character "
+ + n + " (no leading zeros allowed)",
+ createLocation());
+ }
+
+ if (LOG) {
+ LOGGER.fine("dotpassed:" + dotpassed
+ + "/zeropassed:" + zeropassed + "/i:" + i
+ + "/n:" + n);
+ }
+
+ if (n == DOT) {
+
+ if (dotpassed) {
+ throw new JsonParsingException("more than one dot",
+ createLocation());
+ }
+
+ dotpassed = true;
+
+ }
+
+ if (n == EXP_LOWERCASE || n == EXP_UPPERCASE) {
+
+ if (epassed) {
+ throw new JsonParsingException("more than one e/E",
+ createLocation());
+ }
+
+ epassed = true;
+ }
+
+ appendValue(n);
+ last = n;
+
+ }
+
+ break;
+
+ }
+
+ } else {
+ throw new JsonParsingException("Unexpected character " + c,
+ createLocation());
+ }
+
+ }
+
+ private boolean isNumber(final char c) {
+ return isAsciiDigit(c) || c == DOT || c == MINUS || c == PLUS
+ || c == EXP_LOWERCASE || c == EXP_UPPERCASE;
+ }
+
+ @Override
+ public String getString() {
+ if (event == Event.KEY_NAME || event == Event.VALUE_STRING
+ || event == Event.VALUE_NUMBER) {
+ return getValue();
+ }
+ throw new IllegalStateException(event + " doesn't support getString()");
+ }
+
+ @Override
+ public boolean isIntegralNumber() {
+
+ if (event != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(event
+ + " doesn't supportisIntegralNumber()");
+ }
+
+ for (int i = 0; i < valueLength; i++) {
+ if (!isAsciiDigit(currentValue[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public int getInt() {
+ if (event != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(event + " doesn't supportgetInt()");
+ }
+ return Integer.parseInt(getValue());
+ }
+
+ @Override
+ public long getLong() {
+ if (event != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(event + " doesn't supporgetLong()");
+ }
+ return Long.parseLong(getValue());
+ }
+
+ @Override
+ public BigDecimal getBigDecimal() {
+ if (event != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(event
+ + " doesn't support getBigDecimal()");
+ }
+ return new BigDecimal(getValue());
+ }
+
+ @Override
+ public JsonLocation getLocation() {
+ return createLocation();
+ }
+
+ protected abstract void closeUnderlyingSource() throws IOException;
+
+ @Override
+ public void close() {
+
+ // VBUFFER_CACHE.release(currentValue);
+
+ try {
+ closeUnderlyingSource();
+ } catch (final IOException e) {
+ throw new JsonException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public String getEscapedString() {
+ return Strings.escape(getValue());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-fleece/blob/9fc85e49/fleece-core/src/main/java/org/apache/fleece/core/JsonCharBufferStreamParser.java
----------------------------------------------------------------------
diff --git a/fleece-core/src/main/java/org/apache/fleece/core/JsonCharBufferStreamParser.java b/fleece-core/src/main/java/org/apache/fleece/core/JsonCharBufferStreamParser.java
new file mode 100644
index 0000000..8c84f51
--- /dev/null
+++ b/fleece-core/src/main/java/org/apache/fleece/core/JsonCharBufferStreamParser.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fleece.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class JsonCharBufferStreamParser extends JsonBaseStreamParser {
+ private static final Logger LOGGER = Logger.getLogger(JsonCharBufferStreamParser.class.getName());
+ private static final boolean LOG = LOGGER.isLoggable(Level.FINE);
+
+ /*
+ * private static final BufferCache<char[]> BUFFER_CACHE = new
+ * BufferCache<char[]>(
+ * Integer.getInteger("org.apache.fleece.default-char-buffer", 8192) ) {
+ *
+ * @Override protected char[] newValue(final int defaultSize) { return new
+ * char[defaultSize]; } };
+ */
+
+ private final char[] buffer0;// BUFFER_CACHE.getCache();
+ private final Reader in;
+ private int pointer = -1;
+ private int avail;
+ private char mark;
+ private boolean reset;
+
+ // private int availOnMark;
+
+ // Test increment buffer sizes
+
+ public JsonCharBufferStreamParser(final Reader reader,
+ final int maxStringLength, final int bufferSize) {
+ super(maxStringLength);
+ in = reader;
+ buffer0 = new char[bufferSize];
+ }
+
+ public JsonCharBufferStreamParser(final InputStream stream,
+ final int maxStringLength, final int bufferSize) {
+ this(new InputStreamReader(stream), maxStringLength, bufferSize);
+ }
+
+ public JsonCharBufferStreamParser(final InputStream in,
+ final Charset charset, final int maxStringLength, final int bufferSize) {
+ this(new InputStreamReader(in, charset), maxStringLength, bufferSize);
+ }
+
+ @Override
+ protected char readNextChar() throws IOException {
+ if (reset) {
+ reset = false;
+ return mark;
+ }
+
+ if (avail <= 0) {
+ if (LOG) {
+ LOGGER.fine("avail:" + avail + "/pointer:" + pointer);
+ }
+
+ avail = in.read(buffer0, 0, buffer0.length);
+
+ pointer = -1;
+
+ if (LOG) {
+ LOGGER.fine("******* Fill buffer with " + avail
+ + " chars");
+ }
+
+ if (avail <= 0) {
+ throw new IOException("EOF");
+ }
+
+ }
+
+ pointer++;
+ avail--;
+ return buffer0[pointer];
+
+ }
+
+ @Override
+ protected void mark() {
+ if (LOG) {
+ LOGGER.fine(" MARK " + buffer0[pointer] + " ("
+ + (int) buffer0[pointer] + ")");
+ }
+ mark = buffer0[pointer];
+ }
+
+ @Override
+ protected void reset() {
+ if (LOG) {
+ LOGGER.fine(" RESET ");
+ }
+ reset = true;
+ }
+
+ @Override
+ protected void closeUnderlyingSource() throws IOException {
+ // BUFFER_CACHE.release(buffer0);
+ if (in != null) {
+ in.close();
+ }
+ }
+
+}