Minor tweaking of number parsing
diff --git a/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java
index 67d2c25..87337ca 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java
@@ -1404,7 +1404,7 @@
++intLen;
outBuf[outPtr++] = (char) c;
}
- if (c == '.' || c == 'e' || c == 'E') {
+ if (c == INT_PERIOD || c == INT_e || c == INT_E) {
return _parseFloat(outBuf, outPtr, c, false, intLen);
}
--_inputPtr; // to push back trailing char (comma etc)
@@ -1430,13 +1430,14 @@
}
int c = (int) _inputBuffer[_inputPtr++] & 0xFF;
// Note: must be followed by a digit
- if (c < INT_0 || c > INT_9) {
- return _handleInvalidNumberStart(c, true);
- }
-
- // One special case: if first char is 0, must not be followed by a digit
- if (c == INT_0) {
+ if (c <= INT_0) {
+ // One special case: if first char is 0, must not be followed by a digit
+ if (c != INT_0) {
+ return _handleInvalidNumberStart(c, true);
+ }
c = _verifyNoLeadingZeroes();
+ } else if (c > INT_9) {
+ return _handleInvalidNumberStart(c, true);
}
// Ok: we can first just add digit we saw first:
@@ -1459,7 +1460,7 @@
++intLen;
outBuf[outPtr++] = (char) c;
}
- if (c == '.' || c == 'e' || c == 'E') {
+ if (c == INT_PERIOD || c == INT_e || c == INT_E) {
return _parseFloat(outBuf, outPtr, c, true, intLen);
}
@@ -1613,7 +1614,7 @@
}
exp_loop:
- while (c <= INT_9 && c >= INT_0) {
+ while (c >= INT_0 && c <= INT_9) {
++expLen;
if (outPtr >= outBuf.length) {
outBuf = _textBuffer.finishCurrentSegment();
diff --git a/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java
index 607e1a6..08258d2 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java
@@ -4,6 +4,7 @@
import java.io.OutputStream;
import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.async.ByteArrayFeeder;
import com.fasterxml.jackson.core.async.NonBlockingInputFeeder;
import com.fasterxml.jackson.core.io.IOContext;
@@ -228,6 +229,15 @@
return _finishKeywordToken("false", _pending32, JsonToken.VALUE_FALSE);
case MINOR_VALUE_TOKEN_ERROR: // case of "almost token", just need tokenize for error
return _finishErrorToken();
+
+ case MINOR_NUMBER_LEADING_MINUS:
+ case MINOR_NUMBER_LEADING_ZERO:
+ case MINOR_NUMBER_INTEGER_DIGITS:
+ case MINOR_NUMBER_DECIMAL_POINT:
+ case MINOR_NUMBER_FRACTION_DIGITS:
+ case MINOR_NUMBER_EXPONENT_MARKER:
+ case MINOR_NUMBER_EXPONENT_SIGN:
+ case MINOR_NUMBER_EXPONENT_DIGITS:
}
return null;
}
@@ -660,17 +670,56 @@
/*
/**********************************************************************
- /* Second-level decoding, String decoding
+ /* Second-level decoding, Number decoding
/**********************************************************************
*/
protected JsonToken _startPositiveNumber(int ch) throws IOException
{
+ _numberNegative = false;
+ char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
+ boolean leadingZero = (ch == INT_0);
+ outBuf[0] = (char) ch;
+
+ // in unlikely event of not having more input, denote location
+ if (_inputPtr >= _inputEnd) {
+ _minorState = leadingZero ? MINOR_NUMBER_LEADING_ZERO : MINOR_NUMBER_INTEGER_DIGITS;
+ _textBuffer.setCurrentLength(1);
+ return (_currToken = JsonToken.NOT_AVAILABLE);
+ }
+ ch = _inputBuffer[_inputPtr];
+
+ // one early check: leading zeroes may or may not be allowed
+ if (leadingZero) {
+ if (ch == INT_0) {
+ if (!isEnabled(Feature.ALLOW_NUMERIC_LEADING_ZEROS)) {
+ reportInvalidNumber("Leading zeroes not allowed");
+ }
+ }
+ }
+ outBuf[1] = (char) ch;
+ int outPtr = 2;
+
+ // !!! TBI
+ // One special case: if first char is 0, must not be followed by a digit
+ ch = _inputBuffer[_inputPtr];
return null;
}
protected JsonToken _startNegativeNumber() throws IOException
{
+ _numberNegative = true;
+ char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
+ outBuf[0] = '-';
+ if (_inputPtr >= _inputEnd) {
+ _minorState = MINOR_NUMBER_LEADING_MINUS;
+ _textBuffer.setCurrentLength(1);
+ return (_currToken = JsonToken.NOT_AVAILABLE);
+ }
+
+ // Need to get
+
+ // !!! TBI
return null;
}
diff --git a/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParserBase.java b/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParserBase.java
index 2df7b5a..1f9a144 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParserBase.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParserBase.java
@@ -71,14 +71,21 @@
protected final static int MINOR_VALUE_LEADING_WS = 15;
protected final static int MINOR_VALUE_LEADING_COMMA = 16;
protected final static int MINOR_VALUE_LEADING_COLON = 17;
-
- protected final static int MINOR_VALUE_NUMBER = 20;
- protected final static int MINOR_VALUE_STRING = 25;
+ protected final static int MINOR_NUMBER_LEADING_MINUS = 20;
+ protected final static int MINOR_NUMBER_LEADING_ZERO = 21;
+ protected final static int MINOR_NUMBER_INTEGER_DIGITS = 22;
+ protected final static int MINOR_NUMBER_DECIMAL_POINT = 23;
+ protected final static int MINOR_NUMBER_FRACTION_DIGITS = 24;
+ protected final static int MINOR_NUMBER_EXPONENT_MARKER = 25;
+ protected final static int MINOR_NUMBER_EXPONENT_SIGN = 26;
+ protected final static int MINOR_NUMBER_EXPONENT_DIGITS = 27;
- protected final static int MINOR_VALUE_TOKEN_NULL = 30;
- protected final static int MINOR_VALUE_TOKEN_TRUE = 31;
- protected final static int MINOR_VALUE_TOKEN_FALSE = 32;
+ protected final static int MINOR_VALUE_STRING = 45;
+
+ protected final static int MINOR_VALUE_TOKEN_NULL = 60;
+ protected final static int MINOR_VALUE_TOKEN_TRUE = 61;
+ protected final static int MINOR_VALUE_TOKEN_FALSE = 62;
/**
* Special state at which point decoding of a non-quoted token has encountered
diff --git a/src/test/java/perf/ManualIntRead.java b/src/test/java/perf/ManualIntRead.java
new file mode 100644
index 0000000..4bea027
--- /dev/null
+++ b/src/test/java/perf/ManualIntRead.java
@@ -0,0 +1,68 @@
+package perf;
+
+import com.fasterxml.jackson.core.*;
+
+/**
+ * Manually run micro-benchmark for checking performance of tokenizing
+ * simple tokens (false, true, null).
+ */
+public class ManualIntRead extends ParserTestBase
+{
+ protected final JsonFactory _factory;
+
+ protected final byte[] _jsonBytes;
+ protected final char[] _jsonChars;
+
+ private ManualIntRead(JsonFactory f, String json) throws Exception {
+ _factory = f;
+ _jsonChars = json.toCharArray();
+ _jsonBytes = json.getBytes("UTF-8");
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ if (args.length != 0) {
+ System.err.println("Usage: java ...");
+ System.exit(1);
+ }
+ final JsonFactory f = new JsonFactory();
+ final String jsonStr = aposToQuotes(
+"{'data':[1,-2,138,-78,0,12435,-12,-9],'last':12345}"
+ );
+ new ManualIntRead(f, jsonStr).test("char[]", "byte[]", jsonStr.length());
+ }
+
+ @Override
+ protected void testRead1(int reps) throws Exception
+ {
+ while (--reps >= 0) {
+ JsonParser p = _factory.createParser(_jsonChars);
+ _stream(p);
+ p.close();
+ }
+ }
+
+ @Override
+ protected void testRead2(int reps) throws Exception
+ {
+ while (--reps >= 0) {
+ JsonParser p = _factory.createParser(_jsonBytes);
+ _stream(p);
+ p.close();
+ }
+ }
+
+ private final void _stream(JsonParser p) throws Exception
+ {
+ JsonToken t;
+
+ while ((t = p.nextToken()) != null) {
+ // force decoding/reading of scalar values too (booleans are fine, nulls too)
+ if (t == JsonToken.VALUE_STRING) {
+ p.getText();
+ } else if (t == JsonToken.VALUE_NUMBER_INT) {
+ p.getIntValue();
+ }
+ }
+ }
+}