You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2018/05/19 14:08:23 UTC
[6/7] groovy git commit: GROOVY-8379: Rework groovy-json
FastStringUtils (closes #667)
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/CharacterSource.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharacterSource.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/CharacterSource.java
deleted file mode 100644
index 871cf13..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharacterSource.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-/**
- * @author Richard Hightower
- */
-public interface CharacterSource {
-
- /**
- * Skip white space.
- */
- void skipWhiteSpace();
-
- /**
- * returns the next character moving the file pointer or index to the next location.
- */
- int nextChar();
-
- /**
- * returns the current character without changing the IO pointer or index.
- */
- int currentChar();
-
- /**
- * Checks to see if there is a next character.
- */
- boolean hasChar();
-
- /**
- * Useful for finding constants in a string like true, false, etc.
- */
- boolean consumeIfMatch(char[] match);
-
- /**
- * This is mostly for debugging and testing.
- */
- int location();
-
- /**
- * Combines the operations of nextChar and hasChar.
- * Characters is -1 if not found which signifies end of file.
- * This might be preferable to avoid two method calls.
- */
- int safeNextChar();
-
- /**
- * Used to find strings and their ilk
- * Finds the next non-escaped char
- *
- * @param ch character to find
- * @param esc escape character to avoid next char if escaped
- * @return list of chars until this is found.
- */
- char[] findNextChar(int ch, int esc);
-
- boolean hadEscape();
-
- /**
- * Reads a number from the character source.
- */
- char[] readNumber();
-
- String errorDetails(String message);
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/Chr.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/Chr.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/Chr.java
deleted file mode 100644
index a5146b0..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/Chr.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-/**
- * @author Rick Hightower
- */
-public class Chr {
-
- public static char[] array(final char... array) {
- return array;
- }
-
- public static char[] chars(final String array) {
- return array.toCharArray();
- }
-
- public static boolean in(char value, char[] array) {
- for (char currentValue : array) {
- if (currentValue == value) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean in(int value, char[] array) {
- for (int currentValue : array) {
- if (currentValue == value) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean in(char value, int offset, char[] array) {
- for (int index = offset; index < array.length; index++) {
- char currentValue = array[index];
- if (currentValue == value) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean in(char value, int offset, int end, char[] array) {
- for (int index = offset; index < end; index++) {
- char currentValue = array[index];
- if (currentValue == value) {
- return true;
- }
- }
- return false;
- }
-
- public static char[] grow(char[] array, final int size) {
- char[] newArray = new char[array.length + size];
- arraycopy(array, 0, newArray, 0, array.length);
- return newArray;
- }
-
- public static char[] grow(char[] array) {
- char[] newArray = new char[array.length * 2];
- arraycopy(array, 0, newArray, 0, array.length);
- return newArray;
- }
-
- public static char[] copy(char[] array) {
- char[] newArray = new char[array.length];
- arraycopy(array, 0, newArray, 0, array.length);
- return newArray;
- }
-
- public static char[] copy(char[] array, int offset, int length) {
- char[] newArray = new char[length];
- arraycopy(array, offset, newArray, 0, length);
- return newArray;
- }
-
- public static char[] add(char[] array, char v) {
- char[] newArray = new char[array.length + 1];
- arraycopy(array, 0, newArray, 0, array.length);
- newArray[array.length] = v;
- return newArray;
- }
-
- public static char[] add(char[] array, String str) {
- return add(array, str.toCharArray());
- }
-
- public static char[] add(char[] array, StringBuilder stringBuilder) {
- return add(array, getCharsFromStringBuilder(stringBuilder));
- }
-
- public static char[] add(char[] array, char[] array2) {
- char[] newArray = new char[array.length + array2.length];
- arraycopy(array, 0, newArray, 0, array.length);
- arraycopy(array2, 0, newArray, array.length, array2.length);
- return newArray;
- }
-
- /* End universal methods. */
-
- private static char[] getCharsFromStringBuilder(StringBuilder sbuf) {
- final int length = sbuf.length();
- char[] array2 = new char[length];
- sbuf.getChars(0, length, array2, 0);
- return array2;
- }
-
- public static char[] lpad(final char[] in, final int size, char pad) {
- if (in.length >= size) {
- return in;
- }
-
- int delta = size - in.length;
- int index = 0;
- char[] newArray = new char[size];
-
- for (; index < delta; index++) {
- newArray[index] = pad;
- }
-
- for (int index2 = 0; index2 < in.length; index++, index2++) {
- newArray[index] = in[index2];
- }
-
- return newArray;
- }
-
- public static boolean contains(char[] chars, char c, int start, final int length) {
- final int to = length + start;
- for (int index = start; index < to; index++) {
- char ch = chars[index];
- if (ch == c) {
- return true;
- }
- }
- return false;
- }
-
- public static void _idx(char[] buffer, int location, byte[] chars) {
- int index2 = 0;
- int endLocation = (location + chars.length);
- for (int index = location; index < endLocation; index++, index2++) {
- buffer[index] = (char) chars[index2];
- }
- }
-
- public static void _idx(final char[] array, int startIndex, char[] input) {
- try {
- arraycopy(input, 0, array, startIndex, input.length);
- } catch (Exception ex) {
- Exceptions.handle(String.format("array size %d, startIndex %d, input length %d",
- array.length, startIndex, input.length), ex);
- }
- }
-
- private static void arraycopy(final char[] src, final int srcPos, final char[] dest, final int destPos, final int length) {
- System.arraycopy(src, srcPos, dest, destPos, length);
- }
-
- public static void _idx(final char[] array, int startIndex, char[] input, final int inputLength) {
- try {
- arraycopy(input, 0, array, startIndex, inputLength);
- } catch (Exception ex) {
- Exceptions.handle(String.format("array size %d, startIndex %d, input length %d",
- array.length, startIndex, input.length), ex);
- }
- }
-
- public static void _idx(char[] buffer, int location, byte[] chars, int start, int end) {
- int index2 = start;
- int endLocation = (location + (end - start));
- for (int index = location; index < endLocation; index++, index2++) {
- buffer[index] = (char) chars[index2];
- }
- }
-
- public static char[] add(char[]... strings) {
- int length = 0;
- for (char[] str : strings) {
- if (str == null) {
- continue;
- }
- length += str.length;
- }
- CharBuf builder = CharBuf.createExact(length);
- for (char[] str : strings) {
- if (str == null) {
- continue;
- }
- builder.add(str);
- }
- return builder.toCharArray();
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/Dates.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/Dates.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/Dates.java
deleted file mode 100644
index 5a07c6b..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/Dates.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * @author Rick Hightower
- */
-public class Dates {
-
- private static TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC");
-
- public static long utc(long time) {
- Calendar calendar = Calendar.getInstance();
- calendar.setTimeInMillis(time);
- calendar.setTimeZone(UTC_TIME_ZONE);
- return calendar.getTime().getTime();
- }
-
- private static Date internalDate(TimeZone tz, int year, int month, int day, int hour,
- int minute, int second, int miliseconds) {
-
- Calendar calendar = Calendar.getInstance();
-
- calendar.set(Calendar.YEAR, year);
- calendar.set(Calendar.MONTH, month - 1);
- calendar.set(Calendar.DAY_OF_MONTH, day);
- calendar.set(Calendar.HOUR_OF_DAY, hour);
- calendar.set(Calendar.MINUTE, minute);
- calendar.set(Calendar.SECOND, second);
- calendar.set(Calendar.MILLISECOND, miliseconds);
-
- calendar.setTimeZone(tz);
-
- return calendar.getTime();
- }
-
- public static Date toDate(TimeZone tz, int year, int month, int day,
- int hour, int minute, int second) {
- return internalDate(tz, year, month, day, hour, minute, second, 0);
- }
-
- public static Date toDate(TimeZone tz, int year, int month, int day,
- int hour, int minute, int second, int miliseconds) {
- return internalDate(tz, year, month, day, hour, minute, second, miliseconds);
- }
-
- static final int SHORT_ISO_8601_TIME_LENGTH = "1994-11-05T08:15:30Z".length();
- static final int LONG_ISO_8601_TIME_LENGTH = "1994-11-05T08:15:30-05:00".length();
- public static final int JSON_TIME_LENGTH = "2013-12-14T01:55:33.412Z".length();
-
- public static Date fromISO8601(char[] charArray, int from, int to) {
- try {
- if (isISO8601(charArray, from, to)) {
- int year = CharScanner.parseIntFromTo(charArray, from, from + 4);
- int month = CharScanner.parseIntFromTo(charArray, from + 5, from + 7);
- int day = CharScanner.parseIntFromTo(charArray, from + 8, from + 10);
- int hour = CharScanner.parseIntFromTo(charArray, from + 11, from + 13);
-
- int minute = CharScanner.parseIntFromTo(charArray, from + 14, from + 16);
-
- int second = CharScanner.parseIntFromTo(charArray, from + 17, from + 19);
- TimeZone tz = null;
-
- if (charArray[from + 19] == 'Z') {
- tz = TimeZone.getTimeZone("GMT");
- } else {
- String tzStr = "GMT" + String.valueOf(charArray, from + 19, 6);
- tz = TimeZone.getTimeZone(tzStr);
- }
- return toDate(tz, year, month, day, hour, minute, second);
- } else {
- return null;
- }
- } catch (Exception ex) {
- return null;
- }
- }
-
- public static Date fromJsonDate(char[] charArray, int from, int to) {
- try {
- if (isJsonDate(charArray, from, to)) {
- int year = CharScanner.parseIntFromTo(charArray, from, from + 4);
- int month = CharScanner.parseIntFromTo(charArray, from + 5, from + 7);
- int day = CharScanner.parseIntFromTo(charArray, from + 8, from + 10);
- int hour = CharScanner.parseIntFromTo(charArray, from + 11, from + 13);
-
- int minute = CharScanner.parseIntFromTo(charArray, from + 14, from + 16);
-
- int second = CharScanner.parseIntFromTo(charArray, from + 17, from + 19);
-
- int miliseconds = CharScanner.parseIntFromTo(charArray, from + 20, from + 23);
-
- TimeZone tz = TimeZone.getTimeZone("GMT");
-
- return toDate(tz, year, month, day, hour, minute, second, miliseconds);
- } else {
- return null;
- }
- } catch (Exception ex) {
- return null;
- }
- }
-
- public static boolean isISO8601(char[] charArray, int start, int to) {
- boolean valid = true;
- final int length = to - start;
-
- if (length == SHORT_ISO_8601_TIME_LENGTH) {
- valid &= (charArray[start + 19] == 'Z');
- } else if (length == LONG_ISO_8601_TIME_LENGTH) {
- valid &= (charArray[start + 19] == '-' || charArray[start + 19] == '+');
- valid &= (charArray[start + 22] == ':');
- } else {
- return false;
- }
-
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
- // "1 9 9 4 - 1 1 - 0 5 T 0 8 : 1 5 : 3 0 - 0 5 : 0 0
-
- valid &= (charArray[start + 4] == '-') &&
- (charArray[start + 7] == '-') &&
- (charArray[start + 10] == 'T') &&
- (charArray[start + 13] == ':') &&
- (charArray[start + 16] == ':');
-
- return valid;
- }
-
- public static boolean isISO8601QuickCheck(char[] charArray, int start, int to) {
- final int length = to - start;
-
- try {
- return length == JSON_TIME_LENGTH || length == LONG_ISO_8601_TIME_LENGTH
- || length == SHORT_ISO_8601_TIME_LENGTH || (length >= 17 && (charArray[start + 16] == ':'));
-
- } catch (Exception ex) {
- ex.printStackTrace();
- return false;
- }
- }
-
- public static boolean isJsonDate(char[] charArray, int start, int to) {
- boolean valid = true;
- final int length = to - start;
-
- if (length != JSON_TIME_LENGTH) {
- return false;
- }
-
- valid &= (charArray[start + 19] == '.' || charArray[start + 19] == '+');
-
- if (!valid) {
- return false;
- }
-
- valid &= (charArray[start + 4] == '-') &&
- (charArray[start + 7] == '-') &&
- (charArray[start + 10] == 'T') &&
- (charArray[start + 13] == ':') &&
- (charArray[start + 16] == ':');
-
- return valid;
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/Exceptions.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/Exceptions.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/Exceptions.java
deleted file mode 100644
index 6617031..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/Exceptions.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import groovy.json.JsonException;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.Collections;
-
-/**
- * @author Rick Hightower
- */
-public class Exceptions {
-
- public static boolean die() {
- throw new JsonInternalException("died");
- }
-
- public static boolean die(String message) {
- throw new JsonInternalException(message);
- }
-
- public static <T> T die(Class<T> clazz, String message) {
- throw new JsonInternalException(message);
- }
-
- public static void handle(java.lang.Exception e) {
- throw new JsonInternalException(e);
- }
-
- public static <T> T handle(Class<T> clazz, java.lang.Exception e) {
- if (e instanceof JsonInternalException) {
- throw (JsonInternalException) e;
- }
- throw new JsonInternalException(e);
- }
-
- public static <T> T handle(Class<T> clazz, String message, Throwable e) {
- throw new JsonInternalException(message, e);
- }
-
- public static void handle(String message, Throwable e) {
- throw new JsonInternalException(message, e);
- }
-
- public static class JsonInternalException extends JsonException {
-
- public JsonInternalException(String message) {
- super(message);
- }
-
- public JsonInternalException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public JsonInternalException(Throwable cause) {
- super("Wrapped Exception", cause);
- }
-
- public void printStackTrace(PrintStream s) {
- s.println(this.getMessage());
- if (getCause() != null) {
- s.println("This Exception was wrapped, the original exception\n" +
- "stack trace is:\n");
- getCause().printStackTrace(s);
- } else {
- super.printStackTrace(s);
- }
- }
-
- public String getMessage() {
- return super.getMessage() + (getCause() == null ? "" :
- getCauseMessage());
- }
-
- private String getCauseMessage() {
- return "\n CAUSE " + getCause().getClass().getName() + " :: " +
- getCause().getMessage();
- }
-
- public String getLocalizedMessage() {
- return this.getMessage();
- }
-
- public StackTraceElement[] getStackTrace() {
- if (getCause() != null) {
- return getCause().getStackTrace();
- } else {
- return super.getStackTrace();
- }
- }
-
- public Throwable getCause() {
- return super.getCause();
- }
-
- public void printStackTrace(PrintWriter s) {
- s.println(this.getMessage());
-
- if (getCause() != null) {
- s.println("This Exception was wrapped, the original exception\n" +
- "stack trace is:\n");
- getCause().printStackTrace(s);
- } else {
- super.printStackTrace(s);
- }
- }
-
- public void printStackTrace() {
- System.err.println(this.getMessage());
-
- if (getCause() != null) {
- System.err.println("This Exception was wrapped, the original exception\n" +
- "stack trace is:\n");
- getCause().printStackTrace();
- } else {
- super.printStackTrace();
- }
- }
- }
-
- public static String toString(Exception ex) {
- CharBuf buffer = CharBuf.create(255);
- buffer.addLine(ex.getLocalizedMessage());
-
- final StackTraceElement[] stackTrace = ex.getStackTrace();
- for (StackTraceElement element : stackTrace) {
- buffer.add(element.getClassName());
- sputs(buffer, "class", element.getClassName(),
- "method", element.getMethodName(), "line", element.getLineNumber());
- }
-
- return buffer.toString();
- }
-
- public static String sputs(CharBuf buf, Object... messages) {
- int index = 0;
- for (Object message : messages) {
- if (index != 0) {
- buf.add(' ');
- }
- index++;
-
- if (message == null) {
- buf.add("<NULL>");
- } else if (message.getClass().isArray()) {
- buf.add(Collections.singletonList(message).toString());
- } else {
- buf.add(message.toString());
- }
- }
- buf.add('\n');
-
- return buf.toString();
- }
-
- public static String sputs(Object... messages) {
- CharBuf buf = CharBuf.create(100);
- return sputs(buf, messages);
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/FastStringUtils.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/FastStringUtils.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/FastStringUtils.java
deleted file mode 100644
index 9986a1b..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/FastStringUtils.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import sun.misc.Unsafe;
-
-import java.lang.reflect.Field;
-
-/**
- * Internal class for fast processing of Strings during JSON parsing
- */
-public class FastStringUtils {
-
- public static final Unsafe UNSAFE;
- public static final long STRING_VALUE_FIELD_OFFSET;
- public static final long STRING_OFFSET_FIELD_OFFSET;
- public static final long STRING_COUNT_FIELD_OFFSET;
- public static final boolean ENABLED;
-
- private static final boolean WRITE_TO_FINAL_FIELDS = Boolean.parseBoolean(System.getProperty("groovy.json.faststringutils.write.to.final.fields", "false"));
- private static final boolean DISABLE = Boolean.parseBoolean(System.getProperty("groovy.json.faststringutils.disable", "false"));
-
- private static Unsafe loadUnsafe() {
- try {
- Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
- unsafeField.setAccessible(true);
- return (Unsafe) unsafeField.get(null);
-
- } catch (Exception e) {
- return null;
- }
- }
-
- static {
- UNSAFE = DISABLE ? null : loadUnsafe();
- ENABLED = UNSAFE != null;
- }
-
- private static long getFieldOffset(String fieldName) {
- if (ENABLED) {
- try {
- return UNSAFE.objectFieldOffset(String.class.getDeclaredField(fieldName));
- } catch (NoSuchFieldException e) {
- // field undefined
- }
- }
- return -1L;
- }
-
- static {
- STRING_VALUE_FIELD_OFFSET = getFieldOffset("value");
- STRING_OFFSET_FIELD_OFFSET = getFieldOffset("offset");
- STRING_COUNT_FIELD_OFFSET = getFieldOffset("count");
- }
-
- protected enum StringImplementation {
- /**
- * JDK 7 drops offset and count so there is special handling for later version of JDK 7.
- */
- DIRECT_CHARS {
- @Override
- public char[] toCharArray(String string) {
- return (char[]) UNSAFE.getObject(string, STRING_VALUE_FIELD_OFFSET);
- }
-
- @Override
- public String noCopyStringFromChars(char[] chars) {
- if (WRITE_TO_FINAL_FIELDS) {
- String string = new String();
- UNSAFE.putObject(string, STRING_VALUE_FIELD_OFFSET, chars);
- return string;
- } else {
- return new String(chars);
- }
- }
- },
- /**
- * JDK 4 and JDK 5 have offset and count fields.
- */
- OFFSET {
- @Override
- public char[] toCharArray(String string) {
- char[] value = (char[]) UNSAFE.getObject(string, STRING_VALUE_FIELD_OFFSET);
- int offset = UNSAFE.getInt(string, STRING_OFFSET_FIELD_OFFSET);
- int count = UNSAFE.getInt(string, STRING_COUNT_FIELD_OFFSET);
- if (offset == 0 && count == value.length) {
- // no need to copy
- return value;
- } else {
- return string.toCharArray();
- }
- }
-
- @Override
- public String noCopyStringFromChars(char[] chars) {
- if (WRITE_TO_FINAL_FIELDS) {
- String string = new String();
- UNSAFE.putObject(string, STRING_VALUE_FIELD_OFFSET, chars);
- UNSAFE.putInt(string, STRING_COUNT_FIELD_OFFSET, chars.length);
- return string;
- } else {
- return new String(chars);
- }
- }
- },
- UNKNOWN {
- @Override
- public char[] toCharArray(String string) {
- return string.toCharArray();
- }
-
- @Override
- public String noCopyStringFromChars(char[] chars) {
- return new String(chars);
- }
- };
-
- public abstract char[] toCharArray(String string);
-
- public abstract String noCopyStringFromChars(char[] chars);
- }
-
- public static StringImplementation STRING_IMPLEMENTATION = computeStringImplementation();
-
- private static StringImplementation computeStringImplementation() {
- if (STRING_VALUE_FIELD_OFFSET != -1L) {
- if (STRING_OFFSET_FIELD_OFFSET != -1L && STRING_COUNT_FIELD_OFFSET != -1L) {
- return StringImplementation.OFFSET;
- } else if (STRING_OFFSET_FIELD_OFFSET == -1L && STRING_COUNT_FIELD_OFFSET == -1L && valueFieldIsCharArray()) {
- return StringImplementation.DIRECT_CHARS;
- } else {
- // JDK 9
- // TODO: GROOVY-7716 workaround - find way to optimize JDK9 String (or rethink need for Unsafe usage)
- return StringImplementation.UNKNOWN;
- }
- } else {
- return StringImplementation.UNKNOWN;
- }
- }
-
- /**
- * JDK9 Compat Strings enhancement changed the internal representation of the value field from a char[]
- * to a byte[] (see http://openjdk.java.net/jeps/254).
- *
- * @return true if internal String value field is a char[], otherwise false
- */
- private static boolean valueFieldIsCharArray() {
- Object o = UNSAFE.getObject("", STRING_VALUE_FIELD_OFFSET);
- return (o instanceof char[]);
- }
-
- /**
- * @param string string to grab array from.
- * @return char array from string
- */
- public static char[] toCharArray(final String string) {
- return STRING_IMPLEMENTATION.toCharArray(string);
- }
-
- /**
- * @param charSequence to grab array from.
- * @return char array from char sequence
- */
- public static char[] toCharArray(final CharSequence charSequence) {
- return toCharArray(charSequence.toString());
- }
-
- /**
- * @param chars to shove array into.
- * @return new string with chars copied into it
- */
- public static String noCopyStringFromChars(final char[] chars) {
- return STRING_IMPLEMENTATION.noCopyStringFromChars(chars);
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/IO.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/IO.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/IO.java
deleted file mode 100644
index 4c2847f..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/IO.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-
-/**
- * @author Rick Hightower
- */
-public class IO {
-
- private static final int EOF = -1;
-
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-
- public static CharBuf read(Reader input, CharBuf charBuf, final int bufSize) {
- if (charBuf == null) {
- charBuf = CharBuf.create(bufSize);
- } else {
- charBuf.readForRecycle();
- }
-
- try {
- char[] buffer = charBuf.toCharArray();
- int size = input.read(buffer);
- if (size != -1) {
- charBuf._len(size);
- }
- if (size < 0) {
- return charBuf;
- }
-
- copy(input, charBuf);
- } catch (IOException e) {
- Exceptions.handle(e);
- } finally {
- try {
- input.close();
- } catch (IOException e) {
- Exceptions.handle(e);
- }
- }
-
- return charBuf;
- }
-
- public static int copy(Reader input, Writer output) {
- long count = copyLarge(input, output);
- if (count > Integer.MAX_VALUE) {
- return -1;
- }
- return (int) count;
- }
-
- public static long copyLarge(Reader reader, Writer writer) {
- return copyLarge(reader, writer, new char[DEFAULT_BUFFER_SIZE]);
- }
-
- public static long copyLarge(Reader reader, Writer writer, char[] buffer) {
- long count = 0;
- int n;
-
- try {
- while (EOF != (n = reader.read(buffer))) {
- writer.write(buffer, 0, n);
- count += n;
- }
- } catch (IOException e) {
- Exceptions.handle(e);
- }
- return count;
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonFastParser.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonFastParser.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonFastParser.java
deleted file mode 100644
index a2dfb1e..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonFastParser.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This works in index overlay mode or chop mode.
- * Chop mode reduces possibility of memory leak but causes a few more buffer copies as it chops up the buffer.
- *
- * @author Rick Hightower
- */
-public class JsonFastParser extends JsonParserCharArray {
-
- private final boolean useValues;
- private final boolean chop;
- private final boolean lazyChop;
- private final boolean checkDates;
-
- public JsonFastParser() {
- this(true);
- }
-
- public JsonFastParser(boolean useValues) {
- this(useValues, false);
- }
-
- public JsonFastParser(boolean useValues, boolean chop) {
- this(useValues, chop, !chop);
- }
-
- public JsonFastParser(boolean useValues, boolean chop, boolean lazyChop) {
- this(useValues, chop, lazyChop, true);
- }
-
- public JsonFastParser(boolean useValues, boolean chop, boolean lazyChop, boolean checkDates) {
- this.useValues = useValues;
- this.chop = chop;
- this.lazyChop = lazyChop;
- this.checkDates = checkDates;
- }
-
- protected final Value decodeJsonObjectLazyFinalParse() {
- char[] array = charArray;
-
- if (__currentChar == '{')
- __index++;
-
- ValueMap map = useValues ? new ValueMapImpl() : new LazyValueMap(lazyChop);
- Value value = new ValueContainer(map);
-
- objectLoop:
- for (; __index < array.length; __index++) {
- skipWhiteSpace();
- switch (__currentChar) {
-
- case '"':
- Value key = decodeStringOverlay();
- skipWhiteSpace();
-
- if (__currentChar != ':') {
-
- complain("expecting current character to be " + charDescription(__currentChar) + "\n");
- }
- __index++;
-
- Value item = decodeValueOverlay();
-
- skipWhiteSpace();
-
- MapItemValue miv = new MapItemValue(key, item);
-
- map.add(miv);
- }
-
- switch (__currentChar) {
- case '}':
- __index++;
- break objectLoop;
-
- case ',':
- continue;
-
- default:
-
- complain(
- "expecting '}' or ',' but got current char " + charDescription(__currentChar));
- }
- }
- return value;
- }
-
- protected Value decodeValue() {
- return decodeValueOverlay();
- }
-
- private Value decodeValueOverlay() {
- skipWhiteSpace();
-
- switch (__currentChar) {
- case '"':
- return decodeStringOverlay();
-
- case '{':
- return decodeJsonObjectLazyFinalParse();
-
- case 't':
- return decodeTrue() ? ValueContainer.TRUE : ValueContainer.FALSE;
-
- case 'f':
- return !decodeFalse() ? ValueContainer.FALSE : ValueContainer.TRUE;
-
- case 'n':
- return decodeNull() == null ? ValueContainer.NULL : ValueContainer.NULL;
-
- case '[':
- return decodeJsonArrayOverlay();
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '0':
- return decodeNumberOverlay(false);
-
- case '-':
- return decodeNumberOverlay(true);
-
- default:
- complain("Unable to determine the " +
- "current character, it is not a string, number, array, or object");
- return null;
- }
- }
-
- private Value decodeNumberOverlay(final boolean minus) {
- char[] array = charArray;
-
- final int startIndex = __index;
- int index = __index;
- char currentChar;
- boolean doubleFloat = false;
- boolean foundDot = false;
- boolean foundSign = false;
- boolean foundExp = false;
-
- if (minus && index + 1 < array.length) {
- index++;
- }
-
- while (true) {
- currentChar = array[index];
- if (isNumberDigit(currentChar)) {
- //noop
- } else if (currentChar <= 32) { //white
- break;
- } else if (isDelimiter(currentChar)) {
- break;
- } else if (isDecimalChar(currentChar)) {
- switch (currentChar) {
- case DECIMAL_POINT:
- if (foundDot || foundExp) { complain("unexpected character " + currentChar); }
- foundDot = true;
- break;
- case LETTER_E:
- case LETTER_BIG_E:
- if (foundExp) { complain("unexpected character " + currentChar); }
- foundExp = true;
- break;
- case MINUS:
- case PLUS:
- if (foundSign || !foundExp) { complain("unexpected character " + currentChar); }
- if (foundExp && array[index - 1] != LETTER_E && array[index - 1] != LETTER_BIG_E) {
- complain("unexpected character " + currentChar);
- }
- foundSign = true;
- break;
- }
- doubleFloat = true;
- } else {
- complain("unexpected character " + currentChar);
- }
- index++;
- if (index >= array.length) break;
- }
-
- // Handle the case where the exponential number ends without the actual exponent
- if (foundExp) {
- char prevChar = array[index - 1];
- if (prevChar == LETTER_E || prevChar == LETTER_BIG_E || prevChar == MINUS || prevChar == PLUS) {
- complain("unexpected character " + currentChar);
- }
- }
-
- __index = index;
- __currentChar = currentChar;
-
- Type type = doubleFloat ? Type.DOUBLE : Type.INTEGER;
-
- return new NumberValue(chop, type, startIndex, __index, this.charArray);
- }
-
- private Value decodeStringOverlay() {
- char[] array = charArray;
- int index = __index;
- char currentChar = charArray[index];
-
- if (index < array.length && currentChar == '"') {
- index++;
- }
-
- final int startIndex = index;
-
- boolean encoded = hasEscapeChar(array, index, indexHolder);
- index = indexHolder[0];
-
- if (encoded) {
- index = findEndQuote(array, index);
- }
-
- Value value = new CharSequenceValue(chop, Type.STRING, startIndex, index, array, encoded, checkDates);
-
- if (index < array.length) {
- index++;
- }
-
- __index = index;
- return value;
- }
-
- private Value decodeJsonArrayOverlay() {
- char[] array = charArray;
- if (__currentChar == '[') {
- __index++;
- }
-
- skipWhiteSpace();
-
- /* the list might be empty */
- if (__currentChar == ']') {
- __index++;
- return new ValueContainer(new ArrayList());
- }
-
- List<Object> list;
-
- if (useValues) {
- list = new ArrayList<Object>();
- } else {
- list = new ValueList(lazyChop);
- }
-
- Value value = new ValueContainer(list);
-
- Value item;
- char c;
- int lastIndex;
- boolean foundEnd = false;
-
- arrayLoop:
- for (; __index < array.length; __index++) {
- item = decodeValueOverlay();
-
- list.add(item);
- c = currentChar();
- switch (c) {
- case ',':
- continue;
- case ']':
- __index++;
- foundEnd = true;
- break arrayLoop;
- }
-
- lastIndex = __index;
- skipWhiteSpace();
- c = currentChar();
-
- switch (c) {
- case ',':
- continue;
- case ']':
- if (__index == lastIndex) {
- complain("missing ]");
- }
- foundEnd = true;
- __index++;
- break arrayLoop;
- default:
- complain(
- String.format("expecting a ',' or a ']', " +
- " but got \nthe current character of %s " +
- " on array size of %s \n", charDescription(__currentChar), list.size())
- );
- }
- }
-
- if (!foundEnd) {
- complain("Did not find end of Json Array");
- }
- return value;
- }
-
- protected final Object decodeFromChars(char[] cs) {
- Value value = ((Value) super.decodeFromChars(cs));
- if (value.isContainer()) {
- return value.toValue();
- } else {
- return value;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserCharArray.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserCharArray.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserCharArray.java
deleted file mode 100644
index 85120d1..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserCharArray.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import groovy.json.JsonException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Converts an input JSON String into Java objects works with String or char array
- * as input. Produces an Object which can be any of the basic JSON types mapped
- * to Java.
- * <p/>
- *
- * @author Rick Hightower
- */
-public class JsonParserCharArray extends BaseJsonParser {
-
- protected char[] charArray;
- protected int __index;
- protected char __currentChar;
-
- private int lastIndex;
-
- protected Object decodeFromChars(char[] cs) {
- __index = 0;
- charArray = cs;
- lastIndex = cs.length - 1;
- return decodeValue();
- }
-
- protected final boolean hasMore() {
- return __index < lastIndex;
- }
-
- protected final boolean hasCurrent() {
- return __index <= lastIndex;
- }
-
- protected final void skipWhiteSpace() {
- int ix = __index;
-
- if (hasCurrent()) {
- this.__currentChar = this.charArray[ix];
- }
-
- if (__currentChar <= 32) {
- ix = skipWhiteSpaceFast(this.charArray, ix);
- this.__currentChar = this.charArray[ix];
- __index = ix;
- }
- }
-
- protected final char nextChar() {
- try {
- if (hasMore()) {
- __index++;
- return __currentChar = charArray[__index];
- } else {
- // TODO move unicode 0 to separate file to avoid doc parsing issues
- return '\u0000';
- }
- } catch (Exception ex) {
- throw new JsonException(exceptionDetails("unable to advance character"), ex);
- }
- }
-
- protected String exceptionDetails(String message) {
- return CharScanner.errorDetails(message, charArray, __index, __currentChar);
- }
-
- private static int skipWhiteSpaceFast(char[] array, int index) {
- char c;
- for (; index < array.length; index++) {
- c = array[index];
- if (c > 32) {
- return index;
- }
- }
- return index - 1;
- }
-
- protected final Object decodeJsonObject() {
- if (__currentChar == '{') {
- __index++;
- }
-
- LazyMap map = new LazyMap();
-
- for (; __index < this.charArray.length; __index++) {
- skipWhiteSpace();
-
- if (__currentChar == '"') {
- String key = decodeString();
-
- if (internKeys) {
- String keyPrime = internedKeysCache.get(key);
- if (keyPrime == null) {
- key = key.intern();
- internedKeysCache.put(key, key);
- } else {
- key = keyPrime;
- }
- }
-
- skipWhiteSpace();
-
- if (__currentChar != ':') {
- complain("expecting current character to be " + charDescription(__currentChar) + "\n");
- }
- __index++;
-
- skipWhiteSpace();
-
- Object value = decodeValueInternal();
-
- skipWhiteSpace();
- map.put(key, value);
- }
-
- if (__currentChar == '}') {
- __index++;
- break;
- } else if (__currentChar == ',') {
- continue;
- } else {
- complain(
- "expecting '}' or ',' but got current char " + charDescription(__currentChar));
- }
- }
-
- return map;
- }
-
- protected final void complain(String complaint) {
- throw new JsonException(exceptionDetails(complaint));
- }
-
- protected Object decodeValue() {
- return decodeValueInternal();
- }
-
- private Object decodeValueInternal() {
- Object value = null;
- skipWhiteSpace();
-
- switch (__currentChar) {
- case '"':
- value = decodeString();
- break;
-
- case 't':
- value = decodeTrue();
- break;
-
- case 'f':
- value = decodeFalse();
- break;
-
- case 'n':
- value = decodeNull();
- break;
-
- case '[':
- value = decodeJsonArray();
- break;
-
- case '{':
- value = decodeJsonObject();
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- value = decodeNumber();
- break;
- case '-':
- value = decodeNumber();
- break;
-
- default:
- throw new JsonException(exceptionDetails("Unable to determine the " +
- "current character, it is not a string, number, array, or object"));
- }
-
- return value;
- }
-
- int[] endIndex = new int[1];
-
- private Object decodeNumber() {
- Number num = CharScanner.parseJsonNumber(charArray, __index, charArray.length, endIndex);
- __index = endIndex[0];
-
- return num;
- }
-
- protected static final char[] NULL = Chr.chars("null");
-
- protected final Object decodeNull() {
- if (__index + NULL.length <= charArray.length) {
- if (charArray[__index] == 'n' &&
- charArray[++__index] == 'u' &&
- charArray[++__index] == 'l' &&
- charArray[++__index] == 'l') {
- __index++;
- return null;
- }
- }
- throw new JsonException(exceptionDetails("null not parse properly"));
- }
-
- protected static final char[] TRUE = Chr.chars("true");
-
- protected final boolean decodeTrue() {
- if (__index + TRUE.length <= charArray.length) {
- if (charArray[__index] == 't' &&
- charArray[++__index] == 'r' &&
- charArray[++__index] == 'u' &&
- charArray[++__index] == 'e') {
-
- __index++;
- return true;
- }
- }
-
- throw new JsonException(exceptionDetails("true not parsed properly"));
- }
-
- protected static char[] FALSE = Chr.chars("false");
-
- protected final boolean decodeFalse() {
- if (__index + FALSE.length <= charArray.length) {
- if (charArray[__index] == 'f' &&
- charArray[++__index] == 'a' &&
- charArray[++__index] == 'l' &&
- charArray[++__index] == 's' &&
- charArray[++__index] == 'e') {
- __index++;
- return false;
- }
- }
- throw new JsonException(exceptionDetails("false not parsed properly"));
- }
-
- private CharBuf builder = CharBuf.create(20);
-
- private String decodeString() {
- char[] array = charArray;
- int index = __index;
- char currentChar = array[index];
-
- if (index < array.length && currentChar == '"') {
- index++;
- }
-
- final int startIndex = index;
-
- boolean encoded = hasEscapeChar(array, index, indexHolder);
- index = indexHolder[0];
-
- String value = null;
- if (encoded) {
- index = findEndQuote(array, index);
- value = builder.decodeJsonString(array, startIndex, index).toString();
- builder.recycle();
- } else {
- value = new String(array, startIndex, (index - startIndex));
- }
-
- if (index < charArray.length) {
- index++;
- }
- __index = index;
- return value;
- }
-
- protected final List decodeJsonArray() {
- ArrayList<Object> list = null;
-
- boolean foundEnd = false;
- char[] charArray = this.charArray;
-
- try {
- if (__currentChar == '[') {
- __index++;
- }
-
- int lastIndex;
-
- skipWhiteSpace();
-
- /* the list might be empty */
- if (__currentChar == ']') {
- __index++;
- return new ArrayList();
- }
-
- list = new ArrayList();
-
- while (this.hasMore()) {
- Object arrayItem = decodeValueInternal();
-
- list.add(arrayItem);
-
- char c = charArray[__index];
-
- if (c == ',') {
- __index++;
- continue;
- } else if (c == ']') {
- __index++;
- foundEnd = true;
- break;
- }
-
- lastIndex = __index;
- skipWhiteSpace();
-
- c = charArray[__index];
-
- if (c == ',') {
- __index++;
- continue;
- } else if (c == ']' && lastIndex != __index) {
- __index++;
- foundEnd = true;
- break;
- } else {
- String charString = charDescription(c);
-
- complain(
- String.format("expecting a ',' or a ']', " +
- " but got \nthe current character of %s " +
- " on array index of %s \n", charString, list.size())
- );
- }
- }
- } catch (Exception ex) {
- if (ex instanceof JsonException) {
- throw (JsonException) ex;
- }
- throw new JsonException(exceptionDetails("issue parsing JSON array"), ex);
- }
- if (!foundEnd) {
- complain("Did not find end of Json Array");
- }
- return list;
- }
-
- protected final char currentChar() {
- if (__index > lastIndex) {
- return 0;
- } else {
- return charArray[__index];
- }
- }
-
- public Object parse(char[] chars) {
- return this.decodeFromChars(chars);
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserLax.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserLax.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserLax.java
deleted file mode 100644
index cde56b9..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserLax.java
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Richard Hightower
- */
-public class JsonParserLax extends JsonParserCharArray {
-
- private final boolean useValues;
- private final boolean chop;
- private final boolean lazyChop;
- private final boolean defaultCheckDates;
-
- public JsonParserLax() {
- this(true);
- }
-
- public JsonParserLax(boolean useValues) {
- this(useValues, false);
- }
-
- public JsonParserLax(boolean useValues, boolean chop) {
- this(useValues, chop, !chop);
- }
-
- public JsonParserLax(boolean useValues, boolean chop, boolean lazyChop) {
- this(useValues, chop, lazyChop, true);
- }
-
- public JsonParserLax(boolean useValues, boolean chop, boolean lazyChop, boolean defaultCheckDates) {
- this.useValues = useValues;
- this.chop = chop;
- this.lazyChop = lazyChop;
- this.defaultCheckDates = defaultCheckDates;
- }
-
- private Value decodeJsonObjectLax() {
- if (__currentChar == '{')
- this.nextChar();
-
- ValueMap map = useValues ? new ValueMapImpl() : new LazyValueMap(lazyChop);
- Value value = new ValueContainer(map);
-
- skipWhiteSpace();
- int startIndexOfKey = __index;
- Value key;
- MapItemValue miv;
- Value item;
-
- done:
- for (; __index < this.charArray.length; __index++) {
- skipWhiteSpace();
-
- switch (__currentChar) {
- case ':':
- char startChar = charArray[startIndexOfKey];
- if (startChar == ',') {
- startIndexOfKey++;
- }
-
- key = extractLaxString(startIndexOfKey, __index - 1, false, false);
- __index++; //skip :
-
- item = decodeValueInternal();
- skipWhiteSpace();
-
- miv = new MapItemValue(key, item);
-
- map.add(miv);
-
- startIndexOfKey = __index;
- if (__currentChar == '}') {
- __index++;
- break done;
- }
-
- break;
-
- case '\'':
- key = decodeStringSingle();
-
- //puts ("key with quote", key);
-
- skipWhiteSpace();
-
- if (__currentChar != ':') {
- complain("expecting current character to be ':' but got " + charDescription(__currentChar) + "\n");
- }
- __index++;
- item = decodeValueInternal();
-
- //puts ("key", "#" + key + "#", value);
-
- skipWhiteSpace();
-
- miv = new MapItemValue(key, item);
-
- map.add(miv);
- startIndexOfKey = __index;
- if (__currentChar == '}') {
- __index++;
- break done;
- }
-
- break;
-
- case '"':
- key = decodeStringDouble();
-
- //puts ("key with quote", key);
-
- skipWhiteSpace();
-
- if (__currentChar != ':') {
- complain("expecting current character to be ':' but got " + charDescription(__currentChar) + "\n");
- }
- __index++;
- item = decodeValueInternal();
-
- //puts ("key", "#" + key + "#", value);
-
- skipWhiteSpace();
-
- miv = new MapItemValue(key, item);
-
- map.add(miv);
- startIndexOfKey = __index;
- if (__currentChar == '}') {
- __index++;
- break done;
- }
-
- break;
- }
-
- switch (__currentChar) {
- case '}':
- __index++;
- break done;
-
- case '/': /* */ //
- handleComment();
- startIndexOfKey = __index;
- break;
-
- case '#':
- handleBashComment();
- startIndexOfKey = __index;
- break;
- }
- }
-
- return value;
- }
-
- private Value extractLaxString(int startIndexOfKey, int end, boolean encoded, boolean checkDate) {
- char startChar;
- startIndexLookup:
- for (; startIndexOfKey < __index && startIndexOfKey < charArray.length; startIndexOfKey++) {
- startChar = charArray[startIndexOfKey];
- switch (startChar) {
- case ' ':
- case '\n':
- case '\t':
- continue;
-
- default:
- break startIndexLookup;
- }
- }
-
- char endChar;
- int endIndex = end >= charArray.length ? charArray.length - 1 : end;
- endIndexLookup:
- for (; endIndex >= startIndexOfKey + 1 && endIndex >= 0; endIndex--) {
- endChar = charArray[endIndex];
- switch (endChar) {
- case ' ':
- case '\n':
- case '\t':
- case '}':
- continue;
- case ',':
- case ';':
- continue;
-
- case ']':
- continue;
- default:
- break endIndexLookup;
- }
- }
- return new CharSequenceValue(chop, Type.STRING, startIndexOfKey, endIndex + 1, this.charArray, encoded, checkDate);
- }
-
- protected final Object decodeValue() {
- return this.decodeValueInternal();
- }
-
- private Value decodeValueInternal() {
- Value value = null;
-
- for (; __index < charArray.length; __index++) {
- skipWhiteSpace();
-
- switch (__currentChar) {
- case '\n':
- break;
-
- case '\r':
- break;
-
- case ' ':
- break;
-
- case '\t':
- break;
-
- case '\b':
- break;
-
- case '\f':
- break;
-
- case '/': /* */ //
- handleComment();
- break;
-
- case '#':
- handleBashComment();
- break;
-
- case '"':
- value = decodeStringDouble();
- break;
-
- case '\'':
- value = decodeStringSingle();
- break;
-
- case 't':
- if (isTrue()) {
- return decodeTrue() ? ValueContainer.TRUE : ValueContainer.FALSE;
- } else {
- value = decodeStringLax();
- }
- break;
-
- case 'f':
- if (isFalse()) {
- return !decodeFalse() ? ValueContainer.FALSE : ValueContainer.TRUE;
- } else {
- value = decodeStringLax();
- }
- break;
-
- case 'n':
- if (isNull()) {
- return decodeNull() == null ? ValueContainer.NULL : ValueContainer.NULL;
- } else {
- value = decodeStringLax();
- }
-
- break;
-
- case '[':
- value = decodeJsonArrayLax();
- break;
-
- case '{':
- value = decodeJsonObjectLax();
- break;
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '0':
- return decodeNumberLax(false);
-
- case '-':
- return decodeNumberLax(true);
-
- default:
- value = decodeStringLax();
- }
-
- if (value != null) {
- return value;
- }
- }
-
- return null;
- }
-
- private void handleBashComment() {
- for (; __index < charArray.length; __index++) {
- __currentChar = charArray[__index];
-
- if (__currentChar == '\n') {
- __index++;
- return;
- }
- }
- }
-
- private void handleComment() {
- if (hasMore()) {
- __index++;
- __currentChar = charArray[__index];
-
- switch (__currentChar) {
- case '*':
- for (; __index < charArray.length; __index++) {
- __currentChar = charArray[__index];
-
- if (__currentChar == '*') {
- if (hasMore()) {
- __index++;
- __currentChar = charArray[__index];
- if (__currentChar == '/') {
- if (hasMore()) {
- __index++;
- return;
- }
- }
- } else {
- complain("missing close of comment");
- }
- }
- }
-
- case '/':
- for (; __index < charArray.length; __index++) {
- __currentChar = charArray[__index];
-
- if (__currentChar == '\n') {
- if (hasMore()) {
- __index++;
- return;
- } else {
- return;
- }
- }
- }
- }
- }
- }
-
- /**
- * Decodes a number from a JSON value. If at any point it is determined that
- * the value is not a valid number the value is treated as a {@code String}.
- *
- * @param minus indicate whether the number is negative
- * @return a number, or {@code String} if not a valid number
- */
- protected final Value decodeNumberLax(boolean minus) {
- char[] array = charArray;
-
- final int startIndex = __index;
- int index = __index;
- char currentChar;
- boolean doubleFloat = false;
- boolean foundDot = false;
- boolean foundSign = false;
- boolean foundExp = false;
-
- if (minus && index + 1 < array.length) {
- index++;
- }
-
- while (true) {
- currentChar = array[index];
- if (isNumberDigit(currentChar)) {
- //noop
- } else if (currentChar <= 32) { //white
- break;
- } else if (isDelimiter(currentChar)) {
- break;
- } else if (isDecimalChar(currentChar)) {
- switch (currentChar) {
- case DECIMAL_POINT:
- if (foundDot || foundExp) { return decodeStringLax(); }
- foundDot = true;
- break;
- case LETTER_E:
- case LETTER_BIG_E:
- if (foundExp) { return decodeStringLax(); }
- foundExp = true;
- break;
- case MINUS:
- case PLUS:
- if (foundSign || !foundExp) { return decodeStringLax(); }
- if (foundExp && array[index - 1] != LETTER_E && array[index - 1] != LETTER_BIG_E) {
- return decodeStringLax();
- }
- foundSign = true;
- break;
- }
- doubleFloat = true;
- } else {
- return decodeStringLax();
- }
- index++;
- if (index >= array.length) break;
- }
-
- // Handle the case where the exponential number ends without the actual exponent
- if (foundExp) {
- char prevChar = array[index - 1];
- if (prevChar == LETTER_E || prevChar == LETTER_BIG_E || prevChar == MINUS || prevChar == PLUS) {
- return decodeStringLax();
- }
- }
-
- __index = index;
- __currentChar = currentChar;
-
- Type type = doubleFloat ? Type.DOUBLE : Type.INTEGER;
-
- return new NumberValue(chop, type, startIndex, __index, this.charArray);
- }
-
- private boolean isNull() {
- if (__index + NULL.length <= charArray.length) {
- if (charArray[__index] == 'n' &&
- charArray[__index + 1] == 'u' &&
- charArray[__index + 2] == 'l' &&
- charArray[__index + 3] == 'l') {
- return true;
- }
- }
- return false;
- }
-
- private boolean isTrue() {
- if (__index + TRUE.length <= charArray.length) {
- if (charArray[__index] == 't' &&
- charArray[__index + 1] == 'r' &&
- charArray[__index + 2] == 'u' &&
- charArray[__index + 3] == 'e') {
- return true;
-
- }
- }
- return false;
- }
-
- private boolean isFalse() {
- if (__index + FALSE.length <= charArray.length) {
- if (charArray[__index] == 'f' &&
- charArray[__index + 1] == 'a' &&
- charArray[__index + 2] == 'l' &&
- charArray[__index + 3] == 's' &&
- charArray[__index + 4] == 'e') {
- return true;
- }
- }
- return false;
- }
-
- private Value decodeStringLax() {
- int index = __index;
- char currentChar = charArray[__index];
- final int startIndex = __index;
- boolean encoded = false;
- char[] charArray = this.charArray;
-
- for (; index < charArray.length; index++) {
- currentChar = charArray[index];
-
- if (isDelimiter(currentChar)) break;
- else if (currentChar == '\\') break;
- }
-
- Value value = this.extractLaxString(startIndex, index, encoded, defaultCheckDates);
-
- __index = index;
- return value;
- }
-
- private Value decodeStringDouble() {
- __currentChar = charArray[__index];
-
- if (__index < charArray.length && __currentChar == '"') {
- __index++;
- }
-
- final int startIndex = __index;
-
- boolean escape = false;
- boolean encoded = false;
-
- done:
- for (; __index < this.charArray.length; __index++) {
- __currentChar = charArray[__index];
- switch (__currentChar) {
-
- case '"':
- if (!escape) {
- break done;
- } else {
- escape = false;
- continue;
- }
-
- case '\\':
- escape = !escape;
- encoded = true;
- continue;
- }
- escape = false;
- }
-
- Value value = new CharSequenceValue(chop, Type.STRING, startIndex, __index, this.charArray, encoded, defaultCheckDates);
-
- if (__index < charArray.length) {
- __index++;
- }
-
- return value;
- }
-
- private Value decodeStringSingle() {
- __currentChar = charArray[__index];
-
- if (__index < charArray.length && __currentChar == '\'') {
- __index++;
- }
-
- final int startIndex = __index;
-
- boolean escape = false;
- boolean encoded = false;
- int minusCount = 0;
- int colonCount = 0;
-
- done:
- for (; __index < this.charArray.length; __index++) {
- __currentChar = charArray[__index];
- switch (__currentChar) {
- case '\'':
- if (!escape) {
- break done;
- } else {
- escape = false;
- continue;
- }
-
- case '\\':
- encoded = true;
- escape = true;
- continue;
-
- case '-':
- minusCount++;
- break;
-
- case ':':
- colonCount++;
- break;
- }
- escape = false;
- }
-
- boolean checkDates = defaultCheckDates && !encoded && minusCount >= 2 && colonCount >= 2;
-
- Value value = new CharSequenceValue(chop, Type.STRING, startIndex, __index, this.charArray, encoded, checkDates);
-
- if (__index < charArray.length) {
- __index++;
- }
-
- return value;
- }
-
- private Value decodeJsonArrayLax() {
- if (__currentChar == '[') {
- __index++;
- }
-
- skipWhiteSpace();
-
- if (__currentChar == ']') {
- __index++;
- return new ValueContainer(new ArrayList());
- }
-
- List<Object> list;
-
- if (useValues) {
- list = new ArrayList<Object>();
- } else {
- list = new ValueList(lazyChop);
- }
-
- Value value = new ValueContainer(list);
-
- do {
- skipWhiteSpace();
-
- Object arrayItem = decodeValueInternal();
-
- list.add(arrayItem);
-
- boolean doStop = false;
-
- done:
- do { // Find either next array element or end of array while ignoring comments
- skipWhiteSpace();
-
- switch (__currentChar) {
- case '/':
- handleComment();
- continue;
- case '#':
- handleBashComment();
- continue;
- case ',':
- __index++;
- break done;
- case ']':
- __index++;
- doStop = true;
- break done;
- default:
- String charString = charDescription(__currentChar);
-
- complain(
- String.format("expecting a ',' or a ']', " +
- " but got \nthe current character of %s " +
- " on array index of %s \n", charString, list.size())
- );
- }
- } while (this.hasMore());
-
- if (doStop) break;
-
- } while (this.hasMore());
-
- return value;
- }
-
- protected final Object decodeFromChars(char[] cs) {
- Value value = ((Value) super.decodeFromChars(cs));
- if (value.isContainer()) {
- return value.toValue();
- } else {
- return value;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/25e2a386/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserUsingCharacterSource.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserUsingCharacterSource.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserUsingCharacterSource.java
deleted file mode 100644
index 47a470f..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/JsonParserUsingCharacterSource.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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 groovy.json.internal;
-
-import groovy.json.JsonException;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Converts an input JSON String into Java objects works with String or char array
- * as input. Produces an Object which can be any of the basic JSON types mapped
- * to Java.
- * <p/>
- *
- * @author Rick Hightower
- */
-public class JsonParserUsingCharacterSource extends BaseJsonParser {
-
- private CharacterSource characterSource;
-
- protected String exceptionDetails(String message) {
- return characterSource.errorDetails(message);
- }
-
- protected final Object decodeJsonObject() {
- LazyMap map = new LazyMap();
-
- try {
- CharacterSource characterSource = this.characterSource;
-
- if (characterSource.currentChar() == '{') {
- characterSource.nextChar();
- }
-
- while (characterSource.hasChar()) {
- characterSource.skipWhiteSpace();
-
- if (characterSource.currentChar() == DOUBLE_QUOTE) {
- String key = decodeString();
- //puts ("key", key);
-
- if (internKeys) {
- String keyPrime = internedKeysCache.get(key);
- if (keyPrime == null) {
- key = key.intern();
- internedKeysCache.put(key, key);
- } else {
- key = keyPrime;
- }
- }
-
- characterSource.skipWhiteSpace();
- if (characterSource.currentChar() != COLON) {
- complain("expecting current character to be : but was " + charDescription(characterSource.currentChar()) + "\n");
- }
-
- characterSource.nextChar();
- characterSource.skipWhiteSpace();
-
- Object value = decodeValue();
-
- //puts ("key", key, "value", value);
-
- characterSource.skipWhiteSpace();
-
- map.put(key, value);
- }
-
- int ch = characterSource.currentChar();
- if (ch == '}') {
- characterSource.nextChar();
- break;
- } else if (ch == ',') {
- characterSource.nextChar();
- continue;
- } else {
- complain(
- "expecting '}' or ',' but got current char " + charDescription(ch));
- }
- }
- } catch (Exception ex) {
- throw new JsonException(exceptionDetails("Unable to parse JSON object"), ex);
- }
-
- return map;
- }
-
- protected final void complain(String complaint) {
- throw new JsonException(exceptionDetails(complaint));
- }
-
- private Object decodeValue() {
- CharacterSource characterSource = this.characterSource;
- Object value = null;
- characterSource.skipWhiteSpace();
-
- switch (characterSource.currentChar()) {
- case '"':
- value = decodeString();
- break;
-
- case 't':
- value = decodeTrue();
- break;
-
- case 'f':
- value = decodeFalse();
- break;
-
- case 'n':
- value = decodeNull();
- break;
-
- case '[':
- value = decodeJsonArray();
- break;
-
- case '{':
- value = decodeJsonObject();
- break;
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- value = decodeNumber(false);
- break;
-
- case '-':
- value = decodeNumber(true);
- break;
-
- default:
- throw new JsonException(exceptionDetails("Unable to determine the " +
- "current character, it is not a string, number, array, or object"));
- }
-
- return value;
- }
-
- private Object decodeNumber(boolean negative) {
- char[] chars = characterSource.readNumber();
- Object value = null;
-
- if (CharScanner.hasDecimalChar(chars, negative)) {
- value = CharScanner.parseBigDecimal(chars);
- } else if (CharScanner.isInteger(chars)) {
- value = CharScanner.parseInt(chars);
- } else if (CharScanner.isLong(chars)) {
- value = CharScanner.parseLong(chars);
- }
-
- return value;
- }
-
- protected static final char[] NULL = Chr.chars("null");
-
- protected final Object decodeNull() {
- if (!characterSource.consumeIfMatch(NULL)) {
- throw new JsonException(exceptionDetails("null not parse properly"));
- }
- return null;
- }
-
- protected static final char[] TRUE = Chr.chars("true");
-
- protected final boolean decodeTrue() {
- if (characterSource.consumeIfMatch(TRUE)) {
- return true;
- } else {
- throw new JsonException(exceptionDetails("true not parsed properly"));
- }
- }
-
- protected static char[] FALSE = Chr.chars("false");
-
- protected final boolean decodeFalse() {
- if (characterSource.consumeIfMatch(FALSE)) {
- return false;
- } else {
- throw new JsonException(exceptionDetails("false not parsed properly"));
- }
- }
-
- private CharBuf builder = CharBuf.create(20);
-
- private String decodeString() {
- CharacterSource characterSource = this.characterSource;
-
- characterSource.nextChar();
-
- char[] chars = characterSource.findNextChar('"', '\\');
-
- String value = null;
- if (characterSource.hadEscape()) {
- value = builder.decodeJsonString(chars).toString();
- builder.recycle();
- } else {
- value = new String(chars);
- }
-
- return value;
- }
-
- protected final List decodeJsonArray() {
- ArrayList<Object> list = null;
-
- boolean foundEnd = false;
- try {
- CharacterSource characterSource = this.characterSource;
-
- if (this.characterSource.currentChar() == '[') {
- characterSource.nextChar();
- }
-
- characterSource.skipWhiteSpace();
-
- /* the list might be empty */
- if (this.characterSource.currentChar() == ']') {
- characterSource.nextChar();
- return new ArrayList();
- }
-
- list = new ArrayList();
-
- do {
- characterSource.skipWhiteSpace();
-
- Object arrayItem = decodeValue();
-
- list.add(arrayItem);
-
- characterSource.skipWhiteSpace();
-
- int c = characterSource.currentChar();
-
- if (c == COMMA) {
- characterSource.nextChar();
- continue;
- } else if (c == CLOSED_BRACKET) {
- foundEnd = true;
- characterSource.nextChar();
- break;
- } else {
- String charString = charDescription(c);
-
- complain(
- String.format("expecting a ',' or a ']', " +
- " but got \nthe current character of %s " +
- " on array index of %s \n", charString, list.size())
- );
-
- }
- } while (characterSource.hasChar());
- } catch (Exception ex) {
- throw new JsonException(exceptionDetails("Unexpected issue"), ex);
- }
-
- if (!foundEnd) {
- throw new JsonException(exceptionDetails("Could not find end of JSON array"));
- }
- return list;
- }
-
- public Object parse(Reader reader) {
- characterSource = new ReaderCharacterSource(reader);
- return this.decodeValue();
- }
-
- public Object parse(char[] chars) {
- return parse(new StringReader(new String(chars)));
- }
-}