diff --git a/README.md b/README.md
index 40bcbfdfd..09bc000e6 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,35 @@
-
+JSONC in Java [package org.json]
+===============================
-image credit: Ismael Pérez Ortiz
+# Fork
+This fork allows for using comments inside JSON as well as tries to preserve the order of the keys.
+
+# Usage
-JSON in Java [package org.json]
-===============================
-[](https://mvnrepository.com/artifact/org.json/json)
+Add a repository to pom.xml:
-**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20210307/json-20210307.jar)**
+```xml
+
+
+ stirante-nexus-snapshots
+ https://nexus.stirante.com/repository/maven-snapshots/
+
+
+```
+
+Add dependency to pom.xml:
+```xml
+
+
+ org.json
+ jsonc
+ v20200429-SNAPSHOT
+
+
+```
# Overview
diff --git a/pom.xml b/pom.xml
index 643bea532..8334a5270 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,11 +2,11 @@
4.0.0
org.json
- json
- 20210307
+ jsonc
+ v20210307-SNAPSHOT
bundle
- JSON in Java
+ JSONC in Java
JSON is a light-weight, language independent, data interchange format.
See http://www.JSON.org/
@@ -19,6 +19,8 @@
in Java. Perhaps someday the Java community will standardize on one. Until
then, choose carefully.
+ This version is modified to allow comments.
+
The license includes this restriction: "The software shall be used for good,
not evil." If your conscience cannot live with that, then choose a different
package.
@@ -31,10 +33,22 @@
9
+
+
+
+ stirante-nexus-releases
+ https://nexus.stirante.com/repository/maven-releases/
+
+
+ stirante-nexus-snapshots
+ https://nexus.stirante.com/repository/maven-snapshots/
+
+
+
- https://github.com/douglascrockford/JSON-java.git
- scm:git:git://github.com/douglascrockford/JSON-java.git
- scm:git:git@github.com:douglascrockford/JSON-java.git
+ scm:git:git@github.com:stirante/JSONC-java.git
+ scm:git:git@github.com:stirante/JSONC-java.git
+ scm:git:git@github.com:stirante/JSONC-java.git
@@ -69,6 +83,10 @@
Douglas Crockford
douglas@crockford.com
+
+ Piotr Brzozowski
+ brzozowski.s.piotr@gmail.com
+
@@ -151,20 +169,6 @@
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 1.5
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
org.sonatype.plugins
nexus-staging-maven-plugin
diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java
index 97a6df8d2..5fc83f66e 100644
--- a/src/main/java/org/json/JSONObject.java
+++ b/src/main/java/org/json/JSONObject.java
@@ -36,15 +36,8 @@ of this software and associated documentation files (the "Software"), to deal
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.ResourceBundle;
-import java.util.Set;
import java.util.regex.Pattern;
/**
@@ -161,7 +154,7 @@ public String toString() {
/**
* The map where the JSONObject's properties are kept.
*/
- private final Map map;
+ private final LinkedHashMap map;
/**
* It is sometimes more convenient and less ambiguous to have a
@@ -175,13 +168,9 @@ public String toString() {
* Construct an empty JSONObject.
*/
public JSONObject() {
- // HashMap is used on purpose to ensure that elements are unordered by
- // the specification.
- // JSON tends to be a portable transfer format to allows the container
- // implementations to rearrange their items for a faster element
- // retrieval based on associative access.
- // Therefore, an implementation mustn't rely on the order of the item.
- this.map = new HashMap();
+ // LinkedHashMap is used on purpose to ensure that elements are ordered the same way as they were inserted.
+ // It's not RFC compliant
+ this.map = new LinkedHashMap();
}
/**
@@ -286,9 +275,9 @@ public JSONObject(JSONTokener x) throws JSONException {
*/
public JSONObject(Map, ?> m) {
if (m == null) {
- this.map = new HashMap();
+ this.map = new LinkedHashMap();
} else {
- this.map = new HashMap(m.size());
+ this.map = new LinkedHashMap(m.size());
for (final Entry, ?> e : m.entrySet()) {
if(e.getKey() == null) {
throw new NullPointerException("Null key.");
@@ -457,7 +446,7 @@ public JSONObject(String baseName, Locale locale) throws JSONException {
* @param initialCapacity initial capacity of the internal map.
*/
protected JSONObject(int initialCapacity){
- this.map = new HashMap(initialCapacity);
+ this.map = new LinkedHashMap(initialCapacity);
}
/**
@@ -539,19 +528,7 @@ public static String doubleToString(double d) {
return "null";
}
-// Shave off trailing zeros and decimal point, if possible.
-
- String string = Double.toString(d);
- if (string.indexOf('.') > 0 && string.indexOf('e') < 0
- && string.indexOf('E') < 0) {
- while (string.endsWith("0")) {
- string = string.substring(0, string.length() - 1);
- }
- if (string.endsWith(".")) {
- string = string.substring(0, string.length() - 1);
- }
- }
- return string;
+ return Double.toString(d);
}
/**
@@ -1019,19 +996,7 @@ public static String numberToString(Number number) throws JSONException {
}
testValidity(number);
- // Shave off trailing zeros and decimal point, if possible.
-
- String string = number.toString();
- if (string.indexOf('.') > 0 && string.indexOf('e') < 0
- && string.indexOf('E') < 0) {
- while (string.endsWith("0")) {
- string = string.substring(0, string.length() - 1);
- }
- if (string.endsWith(".")) {
- string = string.substring(0, string.length() - 1);
- }
- }
- return string;
+ return number.toString();
}
/**
diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java
index e6821de32..e00371f0d 100644
--- a/src/main/java/org/json/JSONTokener.java
+++ b/src/main/java/org/json/JSONTokener.java
@@ -290,6 +290,19 @@ public String next(int n) throws JSONException {
public char nextClean() throws JSONException {
for (;;) {
char c = this.next();
+ if (c == '/') {
+ c = next();
+ if (c == '/') {
+ nextToEndOfLine();
+ back();
+ continue;
+ }
+ if (c == '*') {
+ nextToEndOfCommentBlock();
+ back();
+ continue;
+ }
+ }
if (c == 0 || c > ' ') {
return c;
}
@@ -297,6 +310,45 @@ public char nextClean() throws JSONException {
}
+ /**
+ * Scan to the next end of line char.
+ * @throws JSONException Thrown if there is an error reading the source string.
+ */
+ public void nextToEndOfLine() throws JSONException {
+ for (;;) {
+ char c = next();
+
+ if (c == 0 || c == '\r' || c == '\n') {
+ next();
+ return;
+ }
+ }
+ }
+
+
+ /**
+ * Get the next char in the string, skipping comments.
+ * @throws JSONException Thrown if there is an error reading the source string.
+ */
+ public void nextToEndOfCommentBlock() throws JSONException {
+ for (;;) {
+ char c = next();
+
+ if (c == 0) {
+ return;
+ }
+
+ if (c == '*') {
+ c = next();
+ if (c == '/') {
+ next();
+ return;
+ }
+ }
+ }
+ }
+
+
/**
* Return the characters up to the next close quote character.
* Backslash processing is done. The formal JSON format does not
diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java
index 0d5acdd2e..56dae6e75 100644
--- a/src/test/java/org/json/junit/JSONObjectTest.java
+++ b/src/test/java/org/json/junit/JSONObjectTest.java
@@ -803,7 +803,7 @@ public void jsonObjectAppend() {
@SuppressWarnings("boxing")
@Test
public void jsonObjectDoubleToString() {
- String [] expectedStrs = {"1", "1", "-23.4", "-2.345E68", "null", "null" };
+ String [] expectedStrs = {"1.0", "1.0", "-23.4", "-2.345E68", "null", "null" };
Double [] doubles = { 1.0, 00001.00000, -23.4, -23.45e67,
Double.NaN, Double.NEGATIVE_INFINITY };
for (int i = 0; i < expectedStrs.length; ++i) {
@@ -1210,13 +1210,10 @@ public void unexpectedDoubleToIntConversion() {
jsonObject.getDouble(key30) == 3);
assertTrue("3.1 should remain a double",
jsonObject.getDouble(key31) == 3.1);
-
- // turns 3.0 into 3.
+
String serializedString = jsonObject.toString();
JSONObject deserialized = new JSONObject(serializedString);
- assertTrue("3.0 is now an int", deserialized.get(key30) instanceof Integer);
- assertTrue("3.0 can still be interpreted as a double",
- deserialized.getDouble(key30) == 3.0);
+ assertTrue("3.0 remains a double", deserialized.get(key30) instanceof BigDecimal);
assertTrue("3.1 remains a double", deserialized.getDouble(key31) == 3.1);
}
@@ -1691,7 +1688,7 @@ public void jsonObjectNumberToString() {
// trailing .0 is truncated, so it doesn't quite match toString()
dVal = 5000000.0000000;
str = JSONObject.numberToString(dVal);
- assertTrue("expected 5000000 actual "+str, str.equals("5000000"));
+ assertTrue("expected 5000000.0 actual "+str, str.equals("5000000.0"));
}
/**
diff --git a/src/test/java/org/json/junit/JSONTokenerTest.java b/src/test/java/org/json/junit/JSONTokenerTest.java
index e8e0f98a9..bce4f0f98 100644
--- a/src/test/java/org/json/junit/JSONTokenerTest.java
+++ b/src/test/java/org/json/junit/JSONTokenerTest.java
@@ -119,6 +119,8 @@ public void testValid() {
checkValid("[1,2]",JSONArray.class);
checkValid("\n\n[1,2]\n\n",JSONArray.class);
checkValid("1 2", String.class);
+ checkValid(" {\"a\":1/*test comment*/}",JSONObject.class);
+ checkValid(" {\"a\":1//test comment\n}",JSONObject.class);
}
@Test