Support reading/writing values in JSON strings without java.lang.String
Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/impl/src/main/java/org/eclipse/jsonp/JsonGeneratorImpl.java b/impl/src/main/java/org/eclipse/jsonp/JsonGeneratorImpl.java
index 964d9dd..dd64d2b 100644
--- a/impl/src/main/java/org/eclipse/jsonp/JsonGeneratorImpl.java
+++ b/impl/src/main/java/org/eclipse/jsonp/JsonGeneratorImpl.java
@@ -152,12 +152,7 @@
@Override
public JsonGenerator write(String name, String fieldValue) {
- if (currentContext.scope != Scope.IN_OBJECT) {
- throw new JsonGenerationException(
- JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
- }
- writeName(name);
- writeEscapedString(fieldValue);
+ write(name, (CharSequence) fieldValue);
return this;
}
@@ -338,7 +333,7 @@
break;
case STRING:
JsonString str = (JsonString)value;
- write(name, str.getString());
+ write(name, str.getChars());
break;
case NUMBER:
JsonNumber number = (JsonNumber)value;
@@ -480,6 +475,15 @@
return this;
}
+ void write(String name, CharSequence fieldValue) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeEscapedString(fieldValue);
+ }
+
protected void writeComma() {
if (isCommaAllowed()) {
writeChar(',');
@@ -530,7 +534,7 @@
// ^ ^ ^ ^
// | | | |
// begin end begin end
- void writeEscapedString(String string) {
+ void writeEscapedString(CharSequence string) {
writeChar('"');
int len = string.length();
for(int i = 0; i < len; i++) {
@@ -582,10 +586,15 @@
writeChar('"');
}
- void writeString(String str, int begin, int end) {
+ void writeString(CharSequence str, int begin, int end) {
while (begin < end) { // source begin and end indexes
int no = Math.min(buf.length - len, end - begin);
- str.getChars(begin, begin + no, buf, len);
+ if (str instanceof String) {
+ ((String)str).getChars(begin, begin + no, buf, len);
+ } else {
+ // if passed a non-string, assume this is deliberate
+ getChars(str, begin, begin + no, buf, len);
+ }
begin += no; // Increment source index
len += no; // Increment dest index
if (len >= buf.length) {
@@ -594,7 +603,7 @@
}
}
- void writeString(String str) {
+ void writeString(CharSequence str) {
writeString(str, 0, str.length());
}
@@ -669,6 +678,15 @@
return i+1;
}
+ void getChars(CharSequence str, int srcBegin, int srcEnd, char[] dst, int dstBegin) {
+ int length = srcEnd - srcBegin;
+ for (int i = 0 ; i < length ; i++) {
+ int srcIdx = srcBegin + i;
+ int dstIdx = dstBegin + i;
+ dst[dstIdx] = str.charAt(srcIdx);
+ }
+ }
+
/**
* Places characters representing the integer i into the
* character array buf. The characters are placed into
diff --git a/impl/src/main/java/org/eclipse/jsonp/JsonParserImpl.java b/impl/src/main/java/org/eclipse/jsonp/JsonParserImpl.java
index 43ec874..a6fe3d5 100644
--- a/impl/src/main/java/org/eclipse/jsonp/JsonParserImpl.java
+++ b/impl/src/main/java/org/eclipse/jsonp/JsonParserImpl.java
@@ -60,7 +60,7 @@
private final Stack stack = new Stack();
private final JsonTokenizer tokenizer;
-
+
public JsonParserImpl(Reader reader, BufferPool bufferPool) {
this(reader, bufferPool, false);
}
@@ -173,7 +173,7 @@
return getObject(new JsonObjectBuilderImpl(bufferPool));
case KEY_NAME:
case VALUE_STRING:
- return new JsonStringImpl(getString());
+ return new JsonStringImpl(getCharSequence());
case VALUE_NUMBER:
if (isDefinitelyInt()) {
return JsonNumberImpl.getJsonNumber(getInt());
@@ -321,6 +321,14 @@
throw parsingException(JsonToken.EOF, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL, SQUARECLOSE]");
}
+ private CharSequence getCharSequence() {
+ if (currentEvent == Event.KEY_NAME || currentEvent == Event.VALUE_STRING
+ || currentEvent == Event.VALUE_NUMBER) {
+ return tokenizer.getCharSequence();
+ }
+ throw new IllegalStateException(JsonMessages.PARSER_GETSTRING_ERR(currentEvent));
+ }
+
private JsonObject getObject(JsonObjectBuilder builder) {
while(hasNext()) {
JsonParser.Event e = next();
diff --git a/impl/src/main/java/org/eclipse/jsonp/JsonStringImpl.java b/impl/src/main/java/org/eclipse/jsonp/JsonStringImpl.java
index c1181b0..d75ae86 100644
--- a/impl/src/main/java/org/eclipse/jsonp/JsonStringImpl.java
+++ b/impl/src/main/java/org/eclipse/jsonp/JsonStringImpl.java
@@ -25,15 +25,15 @@
*/
final class JsonStringImpl implements JsonString {
- private final String value;
+ private final CharSequence value;
- JsonStringImpl(String value) {
+ JsonStringImpl(CharSequence value) {
this.value = value;
}
@Override
public String getString() {
- return value;
+ return value.toString();
}
@Override
diff --git a/impl/src/main/java/org/eclipse/jsonp/JsonTokenizer.java b/impl/src/main/java/org/eclipse/jsonp/JsonTokenizer.java
index 4f70d13..c1b980d 100644
--- a/impl/src/main/java/org/eclipse/jsonp/JsonTokenizer.java
+++ b/impl/src/main/java/org/eclipse/jsonp/JsonTokenizer.java
@@ -22,7 +22,9 @@
import jakarta.json.stream.JsonLocation;
import jakarta.json.stream.JsonParser;
import jakarta.json.stream.JsonParsingException;
-import java.io.*;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.Reader;
import java.math.BigDecimal;
import java.util.Arrays;
@@ -510,6 +512,11 @@
return new String(buf, storeBegin, storeEnd-storeBegin);
}
+ CharSequence getCharSequence() {
+ int len = storeEnd - storeBegin;
+ return new StringBuilder(len).append(buf, storeBegin, len);
+ }
+
BigDecimal getBigDecimal() {
if (bd == null) {
bd = new BigDecimal(buf, storeBegin, storeEnd-storeBegin);
@@ -531,7 +538,7 @@
return getBigDecimal().intValue();
}
}
-
+
long getLong() {
// no need to create BigDecimal for common integer values (1-18 digits)
int storeLen = storeEnd-storeBegin;
@@ -553,7 +560,7 @@
int storeLen = storeEnd-storeBegin;
return !fracOrExp && (storeLen <= 9 || (minus && storeLen <= 10));
}
-
+
// returns true for common long values (1-18 digits).
// So there are cases it will return false even though the number is long
boolean isDefinitelyLong() {
@@ -582,5 +589,5 @@
return new JsonParsingException(
JsonMessages.TOKENIZER_EXPECTED_CHAR(unexpected, location, expected), location);
}
-
+
}