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/02/28 11:37:56 UTC
[7/7] groovy git commit: GROOVY-8379: Rework groovy-json
FastStringUtils (closes #667)
GROOVY-8379: Rework groovy-json FastStringUtils (closes #667)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/5a3f9996
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/5a3f9996
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/5a3f9996
Branch: refs/heads/master
Commit: 5a3f99960e84003bd885ce433fe0cdd493ccb4d7
Parents: b449116
Author: paulk <pa...@asert.com.au>
Authored: Sun Feb 25 20:11:03 2018 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Feb 28 21:37:34 2018 +1000
----------------------------------------------------------------------
gradle/binarycompatibility.gradle | 2 +-
settings.gradle | 1 +
subprojects/groovy-json-direct/build.gradle | 22 +
.../jsondirect/DirectFastStringService.java | 47 ++
.../DirectFastStringServiceFactory.java | 86 ++
....apache.groovy.json.FastStringServiceFactory | 19 +
.../DirectFastStringServiceTest.groovy | 39 +
.../java/groovy/json/DefaultJsonGenerator.java | 4 +-
.../src/main/java/groovy/json/JsonOutput.java | 4 +-
.../src/main/java/groovy/json/JsonSlurper.java | 8 +-
.../java/groovy/json/internal/ArrayUtils.java | 32 -
.../groovy/json/internal/BaseJsonParser.java | 230 -----
.../java/groovy/json/internal/ByteScanner.java | 70 --
.../main/java/groovy/json/internal/Cache.java | 40 -
.../java/groovy/json/internal/CacheType.java | 30 -
.../main/java/groovy/json/internal/CharBuf.java | 842 -------------------
.../java/groovy/json/internal/CharScanner.java | 512 -----------
.../groovy/json/internal/CharSequenceValue.java | 278 ------
.../groovy/json/internal/CharacterSource.java | 81 --
.../src/main/java/groovy/json/internal/Chr.java | 213 -----
.../main/java/groovy/json/internal/Dates.java | 184 ----
.../java/groovy/json/internal/Exceptions.java | 178 ----
.../groovy/json/internal/FastStringUtils.java | 191 -----
.../src/main/java/groovy/json/internal/IO.java | 91 --
.../groovy/json/internal/JsonFastParser.java | 334 --------
.../json/internal/JsonParserCharArray.java | 386 ---------
.../groovy/json/internal/JsonParserLax.java | 677 ---------------
.../JsonParserUsingCharacterSource.java | 298 -------
.../groovy/json/internal/JsonStringDecoder.java | 38 -
.../main/java/groovy/json/internal/LazyMap.java | 205 -----
.../java/groovy/json/internal/LazyValueMap.java | 247 ------
.../java/groovy/json/internal/MapItemValue.java | 82 --
.../java/groovy/json/internal/NumberValue.java | 216 -----
.../json/internal/ReaderCharacterSource.java | 264 ------
.../java/groovy/json/internal/SimpleCache.java | 72 --
.../src/main/java/groovy/json/internal/Sys.java | 84 --
.../main/java/groovy/json/internal/Type.java | 28 -
.../main/java/groovy/json/internal/Value.java | 63 --
.../groovy/json/internal/ValueContainer.java | 174 ----
.../java/groovy/json/internal/ValueList.java | 123 ---
.../java/groovy/json/internal/ValueMap.java | 46 -
.../java/groovy/json/internal/ValueMapImpl.java | 147 ----
.../groovy/json/DefaultFastStringService.java | 36 +
.../json/DefaultFastStringServiceFactory.java | 26 +
.../apache/groovy/json/FastStringService.java | 33 +
.../groovy/json/FastStringServiceFactory.java | 28 +
.../apache/groovy/json/internal/ArrayUtils.java | 32 +
.../groovy/json/internal/BaseJsonParser.java | 230 +++++
.../groovy/json/internal/ByteScanner.java | 70 ++
.../org/apache/groovy/json/internal/Cache.java | 40 +
.../apache/groovy/json/internal/CacheType.java | 30 +
.../apache/groovy/json/internal/CharBuf.java | 842 +++++++++++++++++++
.../groovy/json/internal/CharScanner.java | 512 +++++++++++
.../groovy/json/internal/CharSequenceValue.java | 278 ++++++
.../groovy/json/internal/CharacterSource.java | 81 ++
.../org/apache/groovy/json/internal/Chr.java | 213 +++++
.../org/apache/groovy/json/internal/Dates.java | 184 ++++
.../apache/groovy/json/internal/Exceptions.java | 178 ++++
.../groovy/json/internal/FastStringUtils.java | 85 ++
.../org/apache/groovy/json/internal/IO.java | 91 ++
.../groovy/json/internal/JsonFastParser.java | 334 ++++++++
.../json/internal/JsonParserCharArray.java | 386 +++++++++
.../groovy/json/internal/JsonParserLax.java | 677 +++++++++++++++
.../JsonParserUsingCharacterSource.java | 298 +++++++
.../groovy/json/internal/JsonStringDecoder.java | 38 +
.../apache/groovy/json/internal/LazyMap.java | 205 +++++
.../groovy/json/internal/LazyValueMap.java | 247 ++++++
.../groovy/json/internal/MapItemValue.java | 82 ++
.../groovy/json/internal/NumberValue.java | 219 +++++
.../json/internal/ReaderCharacterSource.java | 264 ++++++
.../groovy/json/internal/SimpleCache.java | 72 ++
.../org/apache/groovy/json/internal/Sys.java | 84 ++
.../org/apache/groovy/json/internal/Type.java | 28 +
.../org/apache/groovy/json/internal/Value.java | 63 ++
.../groovy/json/internal/ValueContainer.java | 174 ++++
.../apache/groovy/json/internal/ValueList.java | 123 +++
.../apache/groovy/json/internal/ValueMap.java | 46 +
.../groovy/json/internal/ValueMapImpl.java | 147 ++++
....apache.groovy.json.FastStringServiceFactory | 19 +
.../test/groovy/groovy/json/CharBufTest.groovy | 2 +-
.../groovy/json/CustomJsonGeneratorTest.groovy | 2 +-
.../src/test/groovy/groovy/json/IOTest.groovy | 4 +-
.../groovy/groovy/json/JsonSlurperTest.groovy | 2 +-
.../groovy/json/internal/ArrayUtilsTest.groovy | 27 -
.../groovy/json/internal/CharScannerTest.groovy | 288 -------
.../groovy/groovy/json/internal/ChrTest.groovy | 152 ----
.../groovy/json/internal/DatesTest.groovy | 48 --
.../json/internal/FastStringUtilsTest.groovy | 54 --
.../FastStringUtilsUnsafeDisabledTest.groovy | 60 --
.../groovy/json/internal/LazyMapTest.groovy | 52 --
.../internal/ReaderCharacterSourceTest.groovy | 77 --
.../json/DefaultFastStringServiceTest.groovy | 35 +
.../groovy/json/internal/ArrayUtilsTest.groovy | 27 +
.../groovy/json/internal/CharScannerTest.groovy | 288 +++++++
.../apache/groovy/json/internal/ChrTest.groovy | 152 ++++
.../groovy/json/internal/DatesTest.groovy | 47 ++
.../groovy/json/internal/LazyMapTest.groovy | 52 ++
.../internal/ReaderCharacterSourceTest.groovy | 77 ++
98 files changed, 7401 insertions(+), 7228 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/gradle/binarycompatibility.gradle
----------------------------------------------------------------------
diff --git a/gradle/binarycompatibility.gradle b/gradle/binarycompatibility.gradle
index 7e4caff..3dfdbdd 100644
--- a/gradle/binarycompatibility.gradle
+++ b/gradle/binarycompatibility.gradle
@@ -35,7 +35,7 @@ task checkBinaryCompatibility {
check.dependsOn(checkBinaryCompatibility)
// for comparing between versions with different modules, set excludeModules to differing modules, e.g.
-def excludeModules = ['performance', 'groovy-macro', 'tests-vm8']
+def excludeModules = ['performance', 'groovy-macro', 'tests-vm8', 'groovy-json-direct']
//def excludeModules = []
Set projectsToCheck = allprojects.findAll{ !(it.name in excludeModules) }
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/settings.gradle
----------------------------------------------------------------------
diff --git a/settings.gradle b/settings.gradle
index 5df4d51..fe0915d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -24,6 +24,7 @@ def subprojects = ['groovy-ant',
'groovy-groovysh',
'groovy-jmx',
'groovy-json',
+ 'groovy-json-direct',
'groovy-jsr223',
'groovy-nio',
'groovy-servlet',
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json-direct/build.gradle
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json-direct/build.gradle b/subprojects/groovy-json-direct/build.gradle
new file mode 100644
index 0000000..68b6ed2
--- /dev/null
+++ b/subprojects/groovy-json-direct/build.gradle
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+dependencies {
+ compile project(':groovy-json')
+ testCompile project(':groovy-test')
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringService.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringService.java b/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringService.java
new file mode 100644
index 0000000..0d7d4ad
--- /dev/null
+++ b/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringService.java
@@ -0,0 +1,47 @@
+/*
+ * 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.groovy.jsondirect;
+
+import org.apache.groovy.json.FastStringService;
+
+import static org.apache.groovy.jsondirect.DirectFastStringServiceFactory.STRING_VALUE_FIELD_OFFSET;
+import static org.apache.groovy.jsondirect.DirectFastStringServiceFactory.WRITE_TO_FINAL_FIELDS;
+import static org.apache.groovy.jsondirect.DirectFastStringServiceFactory.UNSAFE;
+
+/**
+ * Internal class for fast processing of Strings during JSON parsing - direct field writing version.
+ * Works for JDK 7 and 8 but uses the Unsafe mechanism of Java.
+ */
+public class DirectFastStringService implements FastStringService {
+ @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);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringServiceFactory.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringServiceFactory.java b/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringServiceFactory.java
new file mode 100644
index 0000000..90f0626
--- /dev/null
+++ b/subprojects/groovy-json-direct/src/main/java/org/apache/groovy/jsondirect/DirectFastStringServiceFactory.java
@@ -0,0 +1,86 @@
+/*
+ * 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.groovy.jsondirect;
+
+import org.apache.groovy.json.FastStringService;
+import org.apache.groovy.json.FastStringServiceFactory;
+import sun.misc.Unsafe;
+
+import java.lang.reflect.Field;
+
+public class DirectFastStringServiceFactory implements FastStringServiceFactory {
+ static final Unsafe UNSAFE;
+ static final long STRING_VALUE_FIELD_OFFSET;
+ private static final boolean ENABLED;
+
+ 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");
+ }
+
+ @Override
+ public FastStringService getService() {
+ if (STRING_VALUE_FIELD_OFFSET != -1L && valueFieldIsCharArray()) {
+ return new DirectFastStringService();
+ }
+ // safe to return null here because then we'll get the default provider
+ return null;
+ }
+
+ /**
+ * 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[]);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json-direct/src/main/resources/META-INF/services/org.apache.groovy.json.FastStringServiceFactory
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json-direct/src/main/resources/META-INF/services/org.apache.groovy.json.FastStringServiceFactory b/subprojects/groovy-json-direct/src/main/resources/META-INF/services/org.apache.groovy.json.FastStringServiceFactory
new file mode 100644
index 0000000..cbb3713
--- /dev/null
+++ b/subprojects/groovy-json-direct/src/main/resources/META-INF/services/org.apache.groovy.json.FastStringServiceFactory
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+org.apache.groovy.jsondirect.DirectFastStringServiceFactory
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json-direct/src/test/groovy/org/apache/groovy/jsondirect/DirectFastStringServiceTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json-direct/src/test/groovy/org/apache/groovy/jsondirect/DirectFastStringServiceTest.groovy b/subprojects/groovy-json-direct/src/test/groovy/org/apache/groovy/jsondirect/DirectFastStringServiceTest.groovy
new file mode 100644
index 0000000..fe05828
--- /dev/null
+++ b/subprojects/groovy-json-direct/src/test/groovy/org/apache/groovy/jsondirect/DirectFastStringServiceTest.groovy
@@ -0,0 +1,39 @@
+/*
+ * 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.groovy.jsondirect
+
+import org.apache.groovy.json.FastStringService
+
+class DirectFastStringServiceTest extends GroovyTestCase {
+
+ FastStringService service = new DirectFastStringServiceFactory().service
+
+ void testToCharArray() {
+ if (!service) return
+ def str = "some test"
+ assert service.toCharArray(str) == str.toCharArray()
+ }
+
+ void testNoCopyStringFromChars() {
+ if (!service) return
+ def source = "äöüliu"
+ def chars = source.toCharArray()
+ assert service.noCopyStringFromChars(chars) == source
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/DefaultJsonGenerator.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/DefaultJsonGenerator.java b/subprojects/groovy-json/src/main/java/groovy/json/DefaultJsonGenerator.java
index 6510d4d..1e530e2 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/DefaultJsonGenerator.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/DefaultJsonGenerator.java
@@ -18,8 +18,8 @@
*/
package groovy.json;
-import groovy.json.internal.CharBuf;
-import groovy.json.internal.Chr;
+import org.apache.groovy.json.internal.CharBuf;
+import org.apache.groovy.json.internal.Chr;
import groovy.lang.Closure;
import groovy.util.Expando;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java b/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
index 63bbf1d..a650915 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/JsonOutput.java
@@ -18,8 +18,8 @@
*/
package groovy.json;
-import groovy.json.internal.CharBuf;
-import groovy.json.internal.Chr;
+import org.apache.groovy.json.internal.CharBuf;
+import org.apache.groovy.json.internal.Chr;
import groovy.lang.Closure;
import groovy.util.Expando;
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/JsonSlurper.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/JsonSlurper.java b/subprojects/groovy-json/src/main/java/groovy/json/JsonSlurper.java
index 8808a05..dd931f0 100644
--- a/subprojects/groovy-json/src/main/java/groovy/json/JsonSlurper.java
+++ b/subprojects/groovy-json/src/main/java/groovy/json/JsonSlurper.java
@@ -18,10 +18,10 @@
*/
package groovy.json;
-import groovy.json.internal.JsonFastParser;
-import groovy.json.internal.JsonParserCharArray;
-import groovy.json.internal.JsonParserLax;
-import groovy.json.internal.JsonParserUsingCharacterSource;
+import org.apache.groovy.json.internal.JsonFastParser;
+import org.apache.groovy.json.internal.JsonParserCharArray;
+import org.apache.groovy.json.internal.JsonParserLax;
+import org.apache.groovy.json.internal.JsonParserUsingCharacterSource;
import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport;
import org.codehaus.groovy.runtime.ResourceGroovyMethods;
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/ArrayUtils.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/ArrayUtils.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/ArrayUtils.java
deleted file mode 100644
index 7bd54a5..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/ArrayUtils.java
+++ /dev/null
@@ -1,32 +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 class ArrayUtils {
-
- public static char[] copyRange(char[] source, int startIndex, int endIndex) {
- int len = endIndex - startIndex;
- char[] copy = new char[len];
- System.arraycopy(source, startIndex, copy, 0, Math.min(source.length - startIndex, len));
- return copy;
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/BaseJsonParser.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/BaseJsonParser.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/BaseJsonParser.java
deleted file mode 100644
index da20ec0..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/BaseJsonParser.java
+++ /dev/null
@@ -1,230 +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 groovy.json.JsonParser;
-import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport;
-import org.codehaus.groovy.runtime.ResourceGroovyMethods;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.Charset;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Base JSON parser.
- * Scaled down version of Boon JsonParser with features
- * removed that are JDK 1.7 dependent or Groovy duplicated functionality.
- *
- * @author Rick Hightower
- */
-public abstract class BaseJsonParser implements JsonParser {
-
- protected static final int COLON = ':';
- protected static final int COMMA = ',';
- protected static final int CLOSED_CURLY = '}';
- protected static final int CLOSED_BRACKET = ']';
-
- protected static final int LETTER_E = 'e';
- protected static final int LETTER_BIG_E = 'E';
-
- protected static final int MINUS = '-';
- protected static final int PLUS = '+';
-
- protected static final int DECIMAL_POINT = '.';
-
- protected static final int ALPHA_0 = '0';
- protected static final int ALPHA_1 = '1';
- protected static final int ALPHA_2 = '2';
- protected static final int ALPHA_3 = '3';
- protected static final int ALPHA_4 = '4';
- protected static final int ALPHA_5 = '5';
- protected static final int ALPHA_6 = '6';
- protected static final int ALPHA_7 = '7';
- protected static final int ALPHA_8 = '8';
- protected static final int ALPHA_9 = '9';
-
- protected static final int DOUBLE_QUOTE = '"';
-
- protected static final int ESCAPE = '\\';
-
- protected static final boolean internKeys = Boolean.parseBoolean(System.getProperty("groovy.json.internKeys", "false"));
- protected static final ConcurrentHashMap<String, String> internedKeysCache;
-
- private static final Charset UTF_8 = Charset.forName("UTF-8");
-
- protected String charset = UTF_8.name();
-
- private CharBuf fileInputBuf;
-
- protected int bufSize = 256;
-
- static {
- if (internKeys) {
- internedKeysCache = new ConcurrentHashMap<String, String>();
- } else {
- internedKeysCache = null;
- }
- }
-
- protected String charDescription(int c) {
- String charString;
- if (c == ' ') {
- charString = "[SPACE]";
- } else if (c == '\t') {
- charString = "[TAB]";
-
- } else if (c == '\n') {
- charString = "[NEWLINE]";
-
- } else {
- charString = "'" + (char) c + "'";
- }
-
- charString = charString + " with an int value of " + ((int) c);
- return charString;
- }
-
- public void setCharset(String charset) {
- this.charset = charset;
- }
-
- public Object parse(String jsonString) {
- return parse(FastStringUtils.toCharArray(jsonString));
- }
-
- public Object parse(byte[] bytes) {
- return parse(bytes, charset);
- }
-
- public Object parse(byte[] bytes, String charset) {
- try {
- return parse(new String(bytes, charset));
- } catch (UnsupportedEncodingException e) {
- return Exceptions.handle(Object.class, e);
- }
- }
-
- public Object parse(CharSequence charSequence) {
- return parse(FastStringUtils.toCharArray(charSequence));
- }
-
- public Object parse(Reader reader) {
- fileInputBuf = IO.read(reader, fileInputBuf, bufSize);
- return parse(fileInputBuf.readForRecycle());
- }
-
- public Object parse(InputStream input) {
- return parse(input, charset);
- }
-
- public Object parse(InputStream input, String charset) {
- try {
- return parse(new InputStreamReader(input, charset));
- } catch (UnsupportedEncodingException e) {
- return Exceptions.handle(Object.class, e);
- }
- }
-
- public Object parse(File file, String charset) {
- Reader reader = null;
- try {
- if (charset == null || charset.length() == 0) {
- reader = ResourceGroovyMethods.newReader(file);
- } else {
- reader = ResourceGroovyMethods.newReader(file, charset);
- }
- return parse(reader);
- } catch (IOException ioe) {
- throw new JsonException("Unable to process file: " + file.getPath(), ioe);
- } finally {
- if (reader != null) {
- DefaultGroovyMethodsSupport.closeWithWarning(reader);
- }
- }
- }
-
- protected static boolean isDecimalChar(int currentChar) {
- switch (currentChar) {
- case MINUS:
- case PLUS:
- case LETTER_E:
- case LETTER_BIG_E:
- case DECIMAL_POINT:
- return true;
- }
- return false;
- }
-
- protected static boolean isDelimiter(int c) {
- return c == COMMA || c == CLOSED_CURLY || c == CLOSED_BRACKET;
- }
-
- protected static final boolean isNumberDigit(int c) {
- return c >= ALPHA_0 && c <= ALPHA_9;
- }
-
- protected static final boolean isDoubleQuote(int c) {
- return c == DOUBLE_QUOTE;
- }
-
- protected static final boolean isEscape(int c) {
- return c == ESCAPE;
- }
-
- protected static boolean hasEscapeChar(char[] array, int index, int[] indexHolder) {
- char currentChar;
- for (; index < array.length; index++) {
- currentChar = array[index];
- if (isDoubleQuote(currentChar)) {
- indexHolder[0] = index;
- return false;
- } else if (isEscape(currentChar)) {
- indexHolder[0] = index;
- return true;
- }
- }
-
- indexHolder[0] = index;
- return false;
- }
-
- int[] indexHolder = new int[1];
-
- protected static int findEndQuote(final char[] array, int index) {
- char currentChar;
- boolean escape = false;
-
- for (; index < array.length; index++) {
- currentChar = array[index];
- if (isDoubleQuote(currentChar)) {
- if (!escape) {
- break;
- }
- }
- escape = isEscape(currentChar) && !escape;
- }
- return index;
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/ByteScanner.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/ByteScanner.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/ByteScanner.java
deleted file mode 100644
index 51219b2..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/ByteScanner.java
+++ /dev/null
@@ -1,70 +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 static groovy.json.internal.Exceptions.die;
-
-/**
- * @author Richard Hightower
- */
-public class ByteScanner {
-
- /**
- * Turns a single nibble into an ascii HEX digit.
- *
- * @param nibble the nibble to serializeObject.
- * @return the encoded nibble (1/2 byte).
- */
- protected static int encodeNibbleToHexAsciiCharByte(final int nibble) {
- switch (nibble) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- case 0x08:
- case 0x09:
- return nibble + 0x30; // 0x30('0') - 0x39('9')
- case 0x0A:
- case 0x0B:
- case 0x0C:
- case 0x0D:
- case 0x0E:
- case 0x0F:
- return nibble + 0x57; // 0x41('a') - 0x46('f')
- default:
- die("illegal nibble: " + nibble);
- return -1;
- }
- }
-
- /**
- * Turn a single bytes into two hex character representation.
- *
- * @param decoded the byte to serializeObject.
- * @param encoded the array to which each encoded nibbles are now ascii hex representations.
- */
- public static void encodeByteIntoTwoAsciiCharBytes(final int decoded, final byte[] encoded) {
- encoded[0] = (byte) encodeNibbleToHexAsciiCharByte((decoded >> 4) & 0x0F);
- encoded[1] = (byte) encodeNibbleToHexAsciiCharByte(decoded & 0x0F);
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/Cache.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/Cache.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/Cache.java
deleted file mode 100644
index 9eff815..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/Cache.java
+++ /dev/null
@@ -1,40 +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;
-
-/**
- * Cache
- *
- * @param <KEY> key
- * @param <VALUE> value
- * @author Rick Hightower
- */
-public interface Cache<KEY, VALUE> {
-
- void put(KEY key, VALUE value);
-
- VALUE get(KEY key);
-
- VALUE getSilent(KEY key);
-
- void remove(KEY key);
-
- int size();
-}
-
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/CacheType.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/CacheType.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/CacheType.java
deleted file mode 100644
index 8ecf99b..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/CacheType.java
+++ /dev/null
@@ -1,30 +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 enum CacheType {
-
- LRU,
- LFU,
- FIFO
-}
-
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/CharBuf.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharBuf.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/CharBuf.java
deleted file mode 100644
index f7e1b29..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharBuf.java
+++ /dev/null
@@ -1,842 +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.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-/**
- * @author Rick Hightower
- */
-public class CharBuf extends Writer implements CharSequence {
-
- protected int capacity = 16;
- protected int location = 0;
-
- protected char[] buffer;
-
- public CharBuf(char[] buffer) {
- __init__(buffer);
- }
-
- private void __init__(char[] buffer) {
- this.buffer = buffer;
- this.capacity = buffer.length;
- }
-
- public CharBuf(byte[] bytes) {
- this.buffer = null;
- try {
- String str = new String(bytes, "UTF-8");
- __init__(FastStringUtils.toCharArray(str));
- } catch (UnsupportedEncodingException e) {
- Exceptions.handle(e);
- }
- }
-
- public static CharBuf createExact(final int capacity) {
- return new CharBuf(capacity) {
- public CharBuf add(char[] chars) {
- Chr._idx(buffer, location, chars);
- location += chars.length;
- return this;
- }
- };
- }
-
- public static CharBuf create(int capacity) {
- return new CharBuf(capacity);
- }
-
- public static CharBuf create(char[] buffer) {
- return new CharBuf(buffer);
- }
-
- protected CharBuf(int capacity) {
- this.capacity = capacity;
- init();
- }
-
- protected CharBuf() {
- init();
- }
-
- public void write(char[] cbuf, int off, int len) {
- if (off == 0 && cbuf.length == len) {
- this.add(cbuf);
- } else {
- char[] buffer = ArrayUtils.copyRange(cbuf, off, off + len);
- this.add(buffer);
- }
- }
-
- public void flush() throws IOException {
- }
-
- public void close() throws IOException {
- }
-
- public void init() {
- buffer = new char[capacity];
- }
-
- public final CharBuf add(String str) {
- add(FastStringUtils.toCharArray(str));
- return this;
- }
-
- public final CharBuf addString(String str) {
- add(FastStringUtils.toCharArray(str));
- return this;
- }
-
- public final CharBuf add(int i) {
- add(Integer.toString(i));
- return this;
- }
-
- private Cache<Integer, char[]> icache;
-
- public final CharBuf addInt(int i) {
- switch (i) {
- case 0:
- addChar('0');
- return this;
- case 1:
- addChar('1');
- return this;
- case -1:
- addChar('-');
- addChar('1');
- return this;
- }
-
- addInt(Integer.valueOf(i));
- return this;
- }
-
- public final CharBuf addInt(Integer key) {
- if (icache == null) {
- icache = new SimpleCache<Integer, char[]>(20);
- }
- char[] chars = icache.get(key);
-
- if (chars == null) {
- String str = Integer.toString(key);
- chars = FastStringUtils.toCharArray(str);
- icache.put(key, chars);
- }
-
- addChars(chars);
- return this;
- }
-
- final char[] trueChars = "true".toCharArray();
- final char[] falseChars = "false".toCharArray();
-
- public final CharBuf add(boolean b) {
- addChars(b ? trueChars : falseChars);
- return this;
- }
-
- public final CharBuf addBoolean(boolean b) {
- add(Boolean.toString(b));
- return this;
- }
-
- public final CharBuf add(byte i) {
- add(Byte.toString(i));
- return this;
- }
-
- public final CharBuf addByte(byte i) {
- addInt(i);
- return this;
- }
-
- public final CharBuf add(short i) {
- add(Short.toString(i));
- return this;
- }
-
- public final CharBuf addShort(short i) {
- addInt(i);
- return this;
- }
-
- public final CharBuf add(long l) {
- add(Long.toString(l));
- return this;
- }
-
- public final CharBuf add(double d) {
- add(Double.toString(d));
- return this;
- }
-
- private Cache<Double, char[]> dcache;
-
- public final CharBuf addDouble(double d) {
- addDouble(Double.valueOf(d));
- return this;
- }
-
- public final CharBuf addDouble(Double key) {
- if (dcache == null) {
- dcache = new SimpleCache<Double, char[]>(20);
- }
- char[] chars = dcache.get(key);
-
- if (chars == null) {
- String str = Double.toString(key);
- chars = FastStringUtils.toCharArray(str);
- dcache.put(key, chars);
- }
-
- add(chars);
- return this;
- }
-
- public final CharBuf add(float d) {
- add(Float.toString(d));
- return this;
- }
-
- private Cache<Float, char[]> fcache;
-
- public final CharBuf addFloat(float d) {
- addFloat(Float.valueOf(d));
- return this;
- }
-
- public final CharBuf addFloat(Float key) {
- if (fcache == null) {
- fcache = new SimpleCache<Float, char[]>(20);
- }
- char[] chars = fcache.get(key);
-
- if (chars == null) {
- String str = Float.toString(key);
- chars = FastStringUtils.toCharArray(str);
- fcache.put(key, chars);
- }
-
- add(chars);
-
- return this;
- }
-
- public final CharBuf addChar(byte i) {
- add((char) i);
- return this;
- }
-
- public final CharBuf addChar(int i) {
- add((char) i);
- return this;
- }
-
- public final CharBuf addChar(short i) {
- add((char) i);
- return this;
- }
-
- public final CharBuf addChar(final char ch) {
- int _location = location;
- char[] _buffer = buffer;
- int _capacity = capacity;
-
- if (1 + _location > _capacity) {
- _buffer = Chr.grow(_buffer);
- _capacity = _buffer.length;
- }
-
- _buffer[_location] = ch;
- _location++;
-
- location = _location;
- buffer = _buffer;
- capacity = _capacity;
- return this;
- }
-
- public CharBuf addLine(String str) {
- add(str.toCharArray());
- add('\n');
- return this;
- }
-
- public CharBuf addLine(CharSequence str) {
- add(str.toString());
- add('\n');
- return this;
- }
-
- public CharBuf add(char[] chars) {
- if (chars.length + location > capacity) {
- buffer = Chr.grow(buffer, buffer.length * 2 + chars.length);
- capacity = buffer.length;
- }
-
- Chr._idx(buffer, location, chars);
- location += chars.length;
- return this;
- }
-
- public final CharBuf addChars(char[] chars) {
- if (chars.length + location > capacity) {
- buffer = Chr.grow(buffer, buffer.length * 2 + chars.length);
- capacity = buffer.length;
- }
-
- System.arraycopy(chars, 0, buffer, location, chars.length);
- location += chars.length;
- return this;
- }
-
- public final CharBuf addQuoted(char[] chars) {
- int _location = location;
- char[] _buffer = buffer;
- int _capacity = capacity;
-
- int sizeNeeded = chars.length + 2 + _location;
- if (sizeNeeded > _capacity) {
- _buffer = Chr.grow(_buffer, sizeNeeded * 2);
- _capacity = _buffer.length;
- }
- _buffer[_location] = '"';
- _location++;
-
- System.arraycopy(chars, 0, _buffer, _location, chars.length);
-
- _location += (chars.length);
- _buffer[_location] = '"';
- _location++;
-
- location = _location;
- buffer = _buffer;
- capacity = _capacity;
- return this;
- }
-
- public final CharBuf addJsonEscapedString(String jsonString) {
- return addJsonEscapedString(jsonString, false);
- }
-
- public final CharBuf addJsonEscapedString(String jsonString, boolean disableUnicodeEscaping) {
- char[] charArray = FastStringUtils.toCharArray(jsonString);
- return addJsonEscapedString(charArray, disableUnicodeEscaping);
- }
-
- private static boolean shouldEscape(int c, boolean disableUnicodeEscaping) {
- if (c < 32) { /* less than space is a control char */
- return true;
- } else if (c == 34) { /* double quote */
- return true;
- } else if (c == 92) { /* backslash */
- return true;
- } else if (!disableUnicodeEscaping && c > 126) { /* non-ascii char range */
- return true;
- }
-
- return false;
- }
-
- private static boolean hasAnyJSONControlChars(final char[] charArray, boolean disableUnicodeEscaping) {
- int index = 0;
- char c;
- while (true) {
- c = charArray[index];
- if (shouldEscape(c, disableUnicodeEscaping)) {
- return true;
- }
- if (++index >= charArray.length) return false;
- }
- }
-
- public final CharBuf addJsonEscapedString(final char[] charArray) {
- return addJsonEscapedString(charArray, false);
- }
-
- public final CharBuf addJsonEscapedString(final char[] charArray, boolean disableUnicodeEscaping) {
- if (charArray.length == 0) return this;
- if (hasAnyJSONControlChars(charArray, disableUnicodeEscaping)) {
- return doAddJsonEscapedString(charArray, disableUnicodeEscaping);
- } else {
- return this.addQuoted(charArray);
- }
- }
-
- final byte[] encoded = new byte[2];
-
- final byte[] charTo = new byte[2];
-
- private CharBuf doAddJsonEscapedString(char[] charArray, boolean disableUnicodeEscaping) {
- char[] _buffer = buffer;
- int _location = this.location;
-
- final byte[] _encoded = encoded;
-
- final byte[] _charTo = charTo;
- /* We are making a bet that not all chars will be unicode. */
- int ensureThisMuch = charArray.length * 6 + 2;
-
- int sizeNeeded = (ensureThisMuch) + _location;
- if (sizeNeeded > capacity) {
- int growBy = (_buffer.length * 2) < sizeNeeded ? sizeNeeded : (_buffer.length * 2);
- _buffer = Chr.grow(buffer, growBy);
- capacity = _buffer.length;
- }
-
- _buffer[_location] = '"';
- _location++;
-
- int index = 0;
- while (true) {
- char c = charArray[index];
-
- if (shouldEscape(c, disableUnicodeEscaping)) {
- /* We are covering our bet with a safety net.
- otherwise we would have to have 5x buffer
- allocated for control chars */
- if (_location + 5 > _buffer.length) {
- _buffer = Chr.grow(_buffer, 20);
- }
-
- switch (c) {
- case '\"':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = '"';
- _location++;
- break;
- case '\\':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = '\\';
- _location++;
- break;
- //There is not requirement to escape solidus so we will not.
-// case '/':
-// _buffer[_location] = '\\';
-// _location ++;
-// _buffer[_location] = '/';
-// _location ++;
-// break;
-
- case '\b':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = 'b';
- _location++;
- break;
- case '\f':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = 'f';
- _location++;
- break;
- case '\n':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = 'n';
- _location++;
- break;
- case '\r':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = 'r';
- _location++;
- break;
- case '\t':
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = 't';
- _location++;
- break;
- default:
- _buffer[_location] = '\\';
- _location++;
- _buffer[_location] = 'u';
- _location++;
- if (c <= 255) {
- _buffer[_location] = '0';
- _location++;
- _buffer[_location] = '0';
- _location++;
- ByteScanner.encodeByteIntoTwoAsciiCharBytes(c, _encoded);
- for (int b : _encoded) {
- _buffer[_location] = (char) b;
- _location++;
- }
- } else {
- _charTo[1] = (byte) (c);
- _charTo[0] = (byte) (c >>> 8);
-
- for (int charByte : _charTo) {
- ByteScanner.encodeByteIntoTwoAsciiCharBytes(charByte, _encoded);
- for (int b : _encoded) {
- _buffer[_location] = (char) b;
- _location++;
- }
- }
- }
- }
- } else {
- _buffer[_location] = c;
- _location++;
- }
-
- if (++index >= charArray.length) break;
- }
- _buffer[_location] = '"';
- _location++;
-
- buffer = _buffer;
- location = _location;
-
- return this;
- }
-
- public final CharBuf addJsonFieldName(String str) {
- return addJsonFieldName(str, false);
- }
-
- public final CharBuf addJsonFieldName(String str, boolean disableUnicodeEscaping) {
- return addJsonFieldName(FastStringUtils.toCharArray(str), disableUnicodeEscaping);
- }
-
- private static final char[] EMPTY_STRING_CHARS = Chr.array('"', '"');
-
- public final CharBuf addJsonFieldName(char[] chars) {
- return addJsonFieldName(chars, false);
- }
-
- public final CharBuf addJsonFieldName(char[] chars, boolean disableUnicodeEscaping) {
- if (chars.length > 0) {
- addJsonEscapedString(chars, disableUnicodeEscaping);
- } else {
- addChars(EMPTY_STRING_CHARS);
- }
- addChar(':');
- return this;
- }
-
- public final CharBuf addQuoted(String str) {
- final char[] chars = FastStringUtils.toCharArray(str);
- addQuoted(chars);
- return this;
- }
-
- public CharBuf add(char[] chars, final int length) {
- if (length + location < capacity) {
- Chr._idx(buffer, location, chars, length);
- } else {
- buffer = Chr.grow(buffer, buffer.length * 2 + length);
- Chr._idx(buffer, location, chars);
- capacity = buffer.length;
- }
- location += length;
- return this;
- }
-
- public CharBuf add(byte[] chars) {
- if (chars.length + location < capacity) {
- Chr._idx(buffer, location, chars);
- } else {
- buffer = Chr.grow(buffer, buffer.length * 2 + chars.length);
- Chr._idx(buffer, location, chars);
- capacity = buffer.length;
- }
- location += chars.length;
- return this;
- }
-
- public CharBuf add(byte[] bytes, int start, int end) {
- int charsLength = end - start;
- if (charsLength + location > capacity) {
- buffer = Chr.grow(buffer, buffer.length * 2 + charsLength);
- }
- Chr._idx(buffer, location, bytes, start, end);
- capacity = buffer.length;
- location += charsLength;
- return this;
- }
-
- public final CharBuf add(char ch) {
- if (1 + location < capacity) {
- buffer[location] = ch;
- } else {
- buffer = Chr.grow(buffer);
- buffer[location] = ch;
- capacity = buffer.length;
- }
- location += 1;
- return this;
- }
-
- public int length() {
- return len();
- }
-
- public char charAt(int index) {
- return buffer[index];
- }
-
- public CharSequence subSequence(int start, int end) {
- return new String(buffer, start, end - start);
- }
-
- public String toString() {
- return new String(buffer, 0, location);
- }
-
- public String toDebugString() {
- return "CharBuf{" +
- "capacity=" + capacity +
- ", location=" + location +
- '}';
- }
-
- public String toStringAndRecycle() {
- String str = new String(buffer, 0, location);
- location = 0;
- return str;
- }
-
- public int len() {
- return location;
- }
-
- public char[] toCharArray() {
- return this.buffer;
- }
-
- public void _len(int location) {
- this.location = location;
- }
-
- public char[] readForRecycle() {
- this.location = 0;
- return this.buffer;
- }
-
- public void recycle() {
- this.location = 0;
- }
-
- public double doubleValue() {
- return CharScanner.parseDouble(this.buffer, 0, location);
- }
-
- public float floatValue() {
- return CharScanner.parseFloat(this.buffer, 0, location);
- }
-
- public int intValue() {
- return CharScanner.parseIntFromTo(buffer, 0, location);
- }
-
- public long longValue() {
- return CharScanner.parseLongFromTo(buffer, 0, location);
- }
-
- public byte byteValue() {
- return (byte) intValue();
- }
-
- public short shortValue() {
- return (short) intValue();
- }
-
- public Number toIntegerWrapper() {
- if (CharScanner.isInteger(buffer, 0, location)) {
- return intValue();
- } else {
- return longValue();
- }
- }
-
- static final char[] nullChars = "null".toCharArray();
-
- public final void addNull() {
- this.add(nullChars);
- }
-
- public void removeLastChar() {
- if (location > 0) {
- location--;
- }
- }
-
- public void removeLastChar(char expect) {
- if (location == 0 || buffer[location-1] != expect) {
- return;
- }
- removeLastChar();
- }
-
- private Cache<BigDecimal, char[]> bigDCache;
-
- public CharBuf addBigDecimal(BigDecimal key) {
- if (bigDCache == null) {
- bigDCache = new SimpleCache<BigDecimal, char[]>(20);
- }
- char[] chars = bigDCache.get(key);
-
- if (chars == null) {
- String str = key.toString();
- chars = FastStringUtils.toCharArray(str);
- bigDCache.put(key, chars);
- }
-
- add(chars);
-
- return this;
- }
-
- private Cache<BigInteger, char[]> bigICache;
-
- public CharBuf addBigInteger(BigInteger key) {
- if (bigICache == null) {
- bigICache = new SimpleCache<BigInteger, char[]>(20);
- }
- char[] chars = bigICache.get(key);
-
- if (chars == null) {
- String str = key.toString();
- chars = FastStringUtils.toCharArray(str);
- bigICache.put(key, chars);
- }
-
- add(chars);
-
- return this;
- }
-
- private Cache<Long, char[]> lcache;
-
- public final CharBuf addLong(long l) {
- addLong(Long.valueOf(l));
- return this;
- }
-
- public final CharBuf addLong(Long key) {
- if (lcache == null) {
- lcache = new SimpleCache<Long, char[]>(20);
- }
- char[] chars = lcache.get(key);
-
- if (chars == null) {
- String str = Long.toString(key);
- chars = FastStringUtils.toCharArray(str);
- lcache.put(key, chars);
- }
-
- add(chars);
-
- return this;
- }
-
- public final CharBuf decodeJsonString(char[] chars) {
- return decodeJsonString(chars, 0, chars.length);
- }
-
- public final CharBuf decodeJsonString(char[] chars, int start, int to) {
- int len = to - start;
-
- char[] buffer = this.buffer;
- int location = this.location;
-
- if (len > capacity) {
- buffer = Chr.grow(buffer, buffer.length * 2 + len);
- capacity = buffer.length;
- }
-
- for (int index = start; index < to; index++) {
- char c = chars[index];
- if (c == '\\') {
- if (index < to) {
- index++;
- c = chars[index];
- switch (c) {
-
- case 'n':
- buffer[location++] = '\n';
- break;
-
- case '/':
- buffer[location++] = '/';
- break;
-
- case '"':
- buffer[location++] = '"';
- break;
-
- case 'f':
- buffer[location++] = '\f';
- break;
-
- case 't':
- buffer[location++] = '\t';
- break;
-
- case '\\':
- buffer[location++] = '\\';
- break;
-
- case 'b':
- buffer[location++] = '\b';
- break;
-
- case 'r':
- buffer[location++] = '\r';
- break;
-
- case 'u':
- if (index + 4 < to) {
- String hex = new String(chars, index + 1, 4);
- char unicode = (char) Integer.parseInt(hex, 16);
- buffer[location++] = unicode;
- index += 4;
- }
- break;
-
- default:
- throw new JsonException("Unable to decode string");
- }
- }
- } else {
- buffer[location++] = c;
- }
- }
-
- this.buffer = buffer;
- this.location = location;
-
- return this;
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/CharScanner.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharScanner.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/CharScanner.java
deleted file mode 100644
index 596c648..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharScanner.java
+++ /dev/null
@@ -1,512 +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.math.BigDecimal;
-
-import static groovy.json.internal.Exceptions.die;
-import static groovy.json.internal.Exceptions.handle;
-
-/**
- * @author Richard Hightower
- */
-public class CharScanner {
-
- protected static final int COMMA = ',';
- protected static final int CLOSED_CURLY = '}';
- protected static final int CLOSED_BRACKET = ']';
- protected static final int LETTER_E = 'e';
- protected static final int LETTER_BIG_E = 'E';
- protected static final int DECIMAL_POINT = '.';
- protected static final int ALPHA_0 = '0';
- protected static final int ALPHA_9 = '9';
- protected static final int MINUS = '-';
- protected static final int PLUS = '+';
-
- static final String MIN_LONG_STR_NO_SIGN = String.valueOf(Long.MIN_VALUE);
- static final String MAX_LONG_STR = String.valueOf(Long.MAX_VALUE);
- static final String MIN_INT_STR_NO_SIGN = String.valueOf(Integer.MIN_VALUE);
- static final String MAX_INT_STR = String.valueOf(Integer.MAX_VALUE);
-
- private static double powersOf10[] = {
- 1.0,
- 10.0,
- 100.0,
- 1000.0,
- 10000.0,
- 100000.0,
- 1000000.0,
- 10000000.0,
- 100000000.0,
- 1000000000.0,
- 10000000000.0,
- 100000000000.0,
- 1000000000000.0,
- 10000000000000.0,
- 100000000000000.0,
- 1000000000000000.0,
- 10000000000000000.0,
- 100000000000000000.0,
- 1000000000000000000.0,
- };
-
- public static boolean isDigit(int c) {
- return c >= ALPHA_0 && c <= ALPHA_9;
- }
-
- public static boolean isDecimalDigit(int c) {
- return isDigit(c) || isDecimalChar(c);
- }
-
- public static boolean isDecimalChar(int currentChar) {
- switch (currentChar) {
- case MINUS:
- case PLUS:
- case LETTER_E:
- case LETTER_BIG_E:
- case DECIMAL_POINT:
- return true;
- }
- return false;
- }
-
- public static boolean hasDecimalChar(char[] chars, boolean negative) {
- int index = 0;
-
- if (negative) index++;
-
- for (; index < chars.length; index++) {
- switch (chars[index]) {
- case MINUS:
- case PLUS:
- case LETTER_E:
- case LETTER_BIG_E:
- case DECIMAL_POINT:
- return true;
- }
- }
- return false;
- }
-
- public static boolean isLong(char[] digitChars) {
- return isLong(digitChars, 0, digitChars.length);
- }
-
- public static boolean isLong(char[] digitChars, int offset, int len) {
- String cmpStr = digitChars[offset] == '-' ? MIN_LONG_STR_NO_SIGN : MAX_LONG_STR;
- int cmpLen = cmpStr.length();
- if (len < cmpLen) return true;
- if (len > cmpLen) return false;
-
- for (int i = 0; i < cmpLen; ++i) {
- int diff = digitChars[offset + i] - cmpStr.charAt(i);
- if (diff != 0) {
- return (diff < 0);
- }
- }
- return true;
- }
-
- public static boolean isInteger(char[] digitChars) {
- return isInteger(digitChars, 0, digitChars.length);
- }
-
- public static boolean isInteger(char[] digitChars, int offset, int len) {
- String cmpStr = (digitChars[offset] == '-') ? MIN_INT_STR_NO_SIGN : MAX_INT_STR;
- int cmpLen = cmpStr.length();
- if (len < cmpLen) return true;
- if (len > cmpLen) return false;
-
- for (int i = 0; i < cmpLen; ++i) {
- int diff = digitChars[offset + i] - cmpStr.charAt(i);
- if (diff != 0) {
- return (diff < 0);
- }
- }
- return true;
- }
-
- public static int parseInt(char[] digitChars) {
- return parseIntFromTo(digitChars, 0, digitChars.length);
- }
-
- public static int parseIntFromTo(char[] digitChars, int offset, int to) {
- try {
- int num;
- boolean negative = false;
- char c = digitChars[offset];
- if (c == '-') {
- offset++;
- negative = true;
- }
- if (offset >= to) {
- die();
- }
- num = (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- if (++offset < to) {
- num = (num * 10) + (digitChars[offset] - '0');
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return negative ? num * -1 : num;
- } catch (Exception ex) {
- return handle(int.class, ex);
- }
- }
-
- public static int parseIntFromToIgnoreDot(char[] digitChars, int offset, int to) {
- int num;
- boolean negative = false;
- char c = digitChars[offset];
- if (c == '-') {
- offset++;
- negative = true;
- }
- if (offset >= to) {
- die();
- }
- c = digitChars[offset];
- num = (c - '0');
- offset++;
-
- for (; offset < to; offset++) {
- c = digitChars[offset];
- if (c != '.') {
- num = (num * 10) + (c - '0');
- }
- }
-
- return negative ? num * -1 : num;
- }
-
- public static long parseLongFromToIgnoreDot(char[] digitChars, int offset, int to) {
- long num;
- boolean negative = false;
- char c = digitChars[offset];
- if (c == '-') {
- offset++;
- negative = true;
- }
- if (offset >= to) {
- die();
- }
- c = digitChars[offset];
- num = (c - '0');
- offset++;
-
- for (; offset < to; offset++) {
- c = digitChars[offset];
- if (c != '.') {
- num = (num * 10) + (c - '0');
- }
- }
-
- return negative ? num * -1 : num;
- }
-
- public static long parseLongFromTo(char[] digitChars, int offset, int to) {
- long num;
- boolean negative = false;
- char c = digitChars[offset];
- if (c == '-') {
- offset++;
- negative = true;
- }
- if (offset >= to) {
- die();
- }
- c = digitChars[offset];
- num = (c - '0');
- offset++;
-
- long digit;
-
- for (; offset < to; offset++) {
- c = digitChars[offset];
- digit = (c - '0');
- num = (num * 10) + digit;
- }
-
- return negative ? num * -1 : num;
- }
-
- public static long parseLong(char[] digitChars) {
- return parseLongFromTo(digitChars, 0, digitChars.length);
- }
-
- public static Number parseJsonNumber(char[] buffer) {
- return parseJsonNumber(buffer, 0, buffer.length);
- }
-
- public static Number parseJsonNumber(char[] buffer, int from, int to) {
- return parseJsonNumber(buffer, from, to, null);
- }
-
- public static boolean isNumberDigit(int c) {
- return c >= ALPHA_0 && c <= ALPHA_9;
- }
-
- protected static boolean isDelimiter(int c) {
- return c == COMMA || c == CLOSED_CURLY || c == CLOSED_BRACKET;
- }
-
- public static Number parseJsonNumber(char[] buffer, int from, int max, int size[]) {
- Number value = null;
- boolean simple = true;
- int digitsPastPoint = 0;
-
- int index = from;
-
- if (buffer[index] == '-') {
- index++;
- }
- if (index >= max) {
- die();
- }
-
- boolean foundDot = false;
- for (; index < max; index++) {
- char ch = buffer[index];
- if (isNumberDigit(ch)) {
- if (foundDot) {
- digitsPastPoint++;
- }
- } else if (ch <= 32 || isDelimiter(ch)) {
- break;
- } else if (ch == '.') {
- if (foundDot) {
- die("unexpected character " + ch);
- }
- foundDot = true;
- } else if (ch == 'E' || ch == 'e' || ch == '-' || ch == '+') {
- simple = false;
- } else {
- die("unexpected character " + ch);
- }
- }
-
- if (digitsPastPoint >= powersOf10.length - 1) {
- simple = false;
- }
-
- final int length = index - from;
-
- if (!foundDot && simple) {
- if (isInteger(buffer, from, length)) {
- value = parseIntFromTo(buffer, from, index);
- } else {
- value = parseLongFromTo(buffer, from, index);
- }
- } else {
- value = new BigDecimal(buffer, from, length);
- }
-
- if (size != null) {
- size[0] = index;
- }
-
- return value;
- }
-
- public static BigDecimal parseBigDecimal(char[] buffer) {
- return new BigDecimal(buffer);
- }
-
- public static float parseFloat(char[] buffer, int from, int to) {
- return (float) parseDouble(buffer, from, to);
- }
-
- public static double parseDouble(char[] buffer, int from, int to) {
- double value;
- boolean simple = true;
- int digitsPastPoint = 0;
-
- int index = from;
-
- if (buffer[index] == '-') {
- index++;
- }
-
- boolean foundDot = false;
- for (; index < to; index++) {
- char ch = buffer[index];
- if (isNumberDigit(ch)) {
- if (foundDot) {
- digitsPastPoint++;
- }
- } else if (ch == '.') {
- if (foundDot) {
- die("unexpected character " + ch);
- }
- foundDot = true;
- } else if (ch == 'E' || ch == 'e' || ch == '-' || ch == '+') {
- simple = false;
- } else {
- die("unexpected character " + ch);
- }
- }
-
- if (digitsPastPoint >= powersOf10.length - 1) {
- simple = false;
- }
-
- final int length = index - from;
-
- if (!foundDot && simple) {
- if (isInteger(buffer, from, length)) {
- value = parseIntFromTo(buffer, from, index);
- } else {
- value = parseLongFromTo(buffer, from, index);
- }
- } else if (foundDot && simple) {
- long lvalue;
-
- if (length < powersOf10.length) {
- if (isInteger(buffer, from, length)) {
- lvalue = parseIntFromToIgnoreDot(buffer, from, index);
- } else {
- lvalue = parseLongFromToIgnoreDot(buffer, from, index);
- }
-
- double power = powersOf10[digitsPastPoint];
- value = lvalue / power;
- } else {
- value = Double.parseDouble(new String(buffer, from, length));
- }
- } else {
- value = Double.parseDouble(new String(buffer, from, index - from));
- }
-
- return value;
- }
-
- public static int skipWhiteSpace(char[] array, int index, final int length) {
- int c;
- for (; index < length; index++) {
- c = array[index];
- if (c > 32) {
- return index;
- }
- }
- return index;
- }
-
- public static char[] readNumber(char[] array, int idx, final int len) {
- final int startIndex = idx;
-
- while (true) {
- if (!CharScanner.isDecimalDigit(array[idx])) {
- break;
- } else {
- idx++;
- if (idx >= len) break;
- }
- }
-
- return ArrayUtils.copyRange(array, startIndex, idx);
- }
-
- public static String errorDetails(String message, char[] array, int index, int ch) {
- CharBuf buf = CharBuf.create(255);
-
- buf.addLine(message);
-
- buf.addLine("");
- buf.addLine("The current character read is " + debugCharDescription(ch));
-
- buf.addLine(message);
-
- int line = 0;
- int lastLineIndex = 0;
-
- for (int i = 0; i < index && i < array.length; i++) {
- if (array[i] == '\n') {
- line++;
- lastLineIndex = i + 1;
- }
- }
-
- int count = 0;
-
- for (int i = lastLineIndex; i < array.length; i++, count++) {
- if (array[i] == '\n') {
- break;
- }
- }
-
- buf.addLine("line number " + (line + 1));
- buf.addLine("index number " + index);
-
- try {
- buf.addLine(new String(array, lastLineIndex, count));
- } catch (Exception ex) {
- try {
- int start = index = (index - 10 < 0) ? 0 : index - 10;
-
- buf.addLine(new String(array, start, index));
- } catch (Exception ex2) {
- buf.addLine(new String(array, 0, array.length));
- }
- }
- for (int i = 0; i < (index - lastLineIndex); i++) {
- buf.add('.');
- }
- buf.add('^');
-
- return buf.toString();
- }
-
- public static String debugCharDescription(int c) {
- String charString;
- if (c == ' ') {
- charString = "[SPACE]";
- } else if (c == '\t') {
- charString = "[TAB]";
- } else if (c == '\n') {
- charString = "[NEWLINE]";
- } else {
- charString = "'" + (char) c + "'";
- }
-
- charString = charString + " with an int value of " + ((int) c);
- return charString;
- }
-}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5a3f9996/subprojects/groovy-json/src/main/java/groovy/json/internal/CharSequenceValue.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharSequenceValue.java b/subprojects/groovy-json/src/main/java/groovy/json/internal/CharSequenceValue.java
deleted file mode 100644
index 6b0477f..0000000
--- a/subprojects/groovy-json/src/main/java/groovy/json/internal/CharSequenceValue.java
+++ /dev/null
@@ -1,278 +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.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Date;
-
-import static groovy.json.internal.CharScanner.isInteger;
-import static groovy.json.internal.CharScanner.parseIntFromTo;
-import static groovy.json.internal.CharScanner.parseLongFromTo;
-import static groovy.json.internal.Exceptions.die;
-
-/**
- * @author Rick Hightower
- */
-public class CharSequenceValue implements Value, CharSequence {
-
- private final Type type;
- private final boolean checkDate;
- private final boolean decodeStrings;
-
- private char[] buffer;
- private boolean chopped;
- private int startIndex;
- private int endIndex;
- private Object value;
-
- public CharSequenceValue(boolean chop, Type type, int startIndex, int endIndex, char[] buffer,
- boolean encoded, boolean checkDate) {
- this.type = type;
- this.checkDate = checkDate;
- this.decodeStrings = encoded;
-
- if (chop) {
- try {
- this.buffer = ArrayUtils.copyRange(buffer, startIndex, endIndex);
- } catch (Exception ex) {
- Exceptions.handle(ex);
- }
- this.startIndex = 0;
- this.endIndex = this.buffer.length;
- this.chopped = true;
- } else {
- this.startIndex = startIndex;
- this.endIndex = endIndex;
- this.buffer = buffer;
- }
- }
-
- public String toString() {
- if (startIndex == 0 && endIndex == buffer.length) {
- return FastStringUtils.noCopyStringFromChars(buffer);
- } else {
- return new String(buffer, startIndex, (endIndex - startIndex));
- }
- }
-
- public final Object toValue() {
- return value != null ? value : (value = doToValue());
- }
-
- public <T extends Enum> T toEnum(Class<T> cls) {
- switch (type) {
- case STRING:
- return toEnum(cls, stringValue());
- case INTEGER:
- return toEnum(cls, intValue());
- case NULL:
- return null;
- }
- die("toEnum " + cls + " value was " + stringValue());
- return null;
- }
-
- public static <T extends Enum> T toEnum(Class<T> cls, String value) {
- try {
- return (T) Enum.valueOf(cls, value);
- } catch (Exception ex) {
- return (T) Enum.valueOf(cls, value.toUpperCase().replace('-', '_'));
- }
- }
-
- public static <T extends Enum> T toEnum(Class<T> cls, int value) {
- T[] enumConstants = cls.getEnumConstants();
- for (T e : enumConstants) {
- if (e.ordinal() == value) {
- return e;
- }
- }
- die("Can't convert ordinal value " + value + " into enum of type " + cls);
- return null;
- }
-
- public boolean isContainer() {
- return false;
- }
-
- private Object doToValue() {
- switch (type) {
- case DOUBLE:
- return doubleValue();
- case INTEGER:
- if (isInteger(buffer, startIndex, endIndex - startIndex)) {
- return intValue();
- } else {
- return longValue();
- }
- case STRING:
- if (checkDate) {
- Date date = null;
- if (Dates.isISO8601QuickCheck(buffer, startIndex, endIndex)) {
- if (Dates.isJsonDate(buffer, startIndex, endIndex)) {
- date = Dates.fromJsonDate(buffer, startIndex, endIndex);
- } else if (Dates.isISO8601(buffer, startIndex, endIndex)) {
- date = Dates.fromISO8601(buffer, startIndex, endIndex);
- } else {
- return stringValue();
- }
-
- if (date == null) {
- return stringValue();
- } else {
- return date;
- }
- }
- }
- return stringValue();
- }
- die();
- return null;
- }
-
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof Value)) return false;
-
- CharSequenceValue value1 = (CharSequenceValue) o;
-
- if (endIndex != value1.endIndex) return false;
- if (startIndex != value1.startIndex) return false;
- if (!Arrays.equals(buffer, value1.buffer)) return false;
- if (type != value1.type) return false;
- return value != null ? value.equals(value1.value) : value1.value == null;
-
- }
-
- public int hashCode() {
- int result = type != null ? type.hashCode() : 0;
- result = 31 * result + (buffer != null ? Arrays.hashCode(buffer) : 0);
- result = 31 * result + startIndex;
- result = 31 * result + endIndex;
- result = 31 * result + (value != null ? value.hashCode() : 0);
- return result;
- }
-
- public final int length() {
- return buffer.length;
- }
-
- public final char charAt(int index) {
- return buffer[index];
- }
-
- public final CharSequence subSequence(int start, int end) {
- return new CharSequenceValue(false, type, start, end, buffer, decodeStrings, checkDate);
- }
-
- public BigDecimal bigDecimalValue() {
- return new BigDecimal(buffer, startIndex, endIndex - startIndex);
- }
-
- public BigInteger bigIntegerValue() {
- return new BigInteger(toString());
- }
-
- public String stringValue() {
- if (this.decodeStrings) {
- return JsonStringDecoder.decodeForSure(buffer, startIndex, endIndex);
- } else {
- return toString();
- }
- }
-
- public String stringValueEncoded() {
- return JsonStringDecoder.decode(buffer, startIndex, endIndex);
- }
-
- public Date dateValue() {
- if (type == Type.STRING) {
-
- if (Dates.isISO8601QuickCheck(buffer, startIndex, endIndex)) {
-
- if (Dates.isJsonDate(buffer, startIndex, endIndex)) {
- return Dates.fromJsonDate(buffer, startIndex, endIndex);
-
- } else if (Dates.isISO8601(buffer, startIndex, endIndex)) {
- return Dates.fromISO8601(buffer, startIndex, endIndex);
- } else {
- throw new JsonException("Unable to convert " + stringValue() + " to date ");
- }
- } else {
- throw new JsonException("Unable to convert " + stringValue() + " to date ");
- }
- } else {
- return new Date(Dates.utc(longValue()));
- }
- }
-
- public int intValue() {
- int sign = 1;
- if (buffer[startIndex] == '-') {
- startIndex++;
- sign = -1;
- }
- return parseIntFromTo(buffer, startIndex, endIndex) * sign;
- }
-
- public long longValue() {
- if (isInteger(buffer, startIndex, endIndex - startIndex)) {
- return parseIntFromTo(buffer, startIndex, endIndex);
- } else {
- return parseLongFromTo(buffer, startIndex, endIndex);
- }
- }
-
- public byte byteValue() {
- return (byte) intValue();
- }
-
- public short shortValue() {
- return (short) intValue();
- }
-
- public double doubleValue() {
- return CharScanner.parseDouble(this.buffer, startIndex, endIndex);
- }
-
- public boolean booleanValue() {
- return Boolean.parseBoolean(toString());
- }
-
- public float floatValue() {
- return CharScanner.parseFloat(this.buffer, startIndex, endIndex);
- }
-
- public final void chop() {
- if (!chopped) {
- this.chopped = true;
- this.buffer = ArrayUtils.copyRange(buffer, startIndex, endIndex);
- this.startIndex = 0;
- this.endIndex = this.buffer.length;
- }
- }
-
- public char charValue() {
- return buffer[startIndex];
- }
-}