Skip to content

Commit

Permalink
improve line comment support
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed May 9, 2023
1 parent e45357e commit 06ed3a5
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 36 deletions.
60 changes: 60 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,66 @@ static <T> T parseObject(byte[] bytes, Type type, JSONReader.Feature... features
}
}

/**
* Parses the json byte array as {@link T}. Returns
* {@code null} if received byte array is {@code null} or empty.
*
* @param chars the specified chars
* @param objectClass the specified actual type of {@link T}
* @param features the specified features is applied to parsing
* @return {@link T} or {@code null}
* @throws JSONException If a parsing error occurs
*/
@SuppressWarnings("unchecked")
static <T> T parseObject(char[] chars, Class<T> objectClass, JSONReader.Feature... features) {
if (chars == null || chars.length == 0) {
return null;
}

try (JSONReader reader = JSONReader.of(chars)) {
reader.context.config(features);
ObjectReader<T> objectReader = reader.getObjectReader(objectClass);
T object = objectReader.readObject(reader, objectClass, null, 0);
if (reader.resolveTasks != null) {
reader.handleResolveTasks(object);
}
if (reader.ch != EOI && (reader.context.features & IgnoreCheckClose.mask) == 0) {
throw new JSONException(reader.info("input not end"));
}
return object;
}
}

/**
* Parses the json byte array as {@link T}. Returns
* {@code null} if received byte array is {@code null} or empty.
*
* @param chars the specified chars
* @param type the specified actual type of {@link T}
* @param features the specified features is applied to parsing
* @return {@link T} or {@code null}
* @throws JSONException If a parsing error occurs
*/
@SuppressWarnings("unchecked")
static <T> T parseObject(char[] chars, Type type, JSONReader.Feature... features) {
if (chars == null || chars.length == 0) {
return null;
}

try (JSONReader reader = JSONReader.of(chars)) {
reader.context.config(features);
ObjectReader<T> objectReader = reader.getObjectReader(type);
T object = objectReader.readObject(reader, type, null, 0);
if (reader.resolveTasks != null) {
reader.handleResolveTasks(object);
}
if (reader.ch != EOI && (reader.context.features & IgnoreCheckClose.mask) == 0) {
throw new JSONException(reader.info("input not end"));
}
return object;
}
}

/**
* Parses the json byte array as {@link T}. Returns
* {@code null} if received byte array is {@code null} or empty.
Expand Down
11 changes: 8 additions & 3 deletions core/src/main/java/com/alibaba/fastjson2/JSONReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public ObjectReader checkAutoType(Class expectClass, long expectClassHash, long
return null;
}

static char char1(int c) {
final char char1(int c) {
switch (c) {
case '0':
return '\0';
Expand Down Expand Up @@ -328,9 +328,10 @@ static char char1(int c) {
case '@':
case '(':
case ')':
case '_':
return (char) c;
default:
throw new JSONException("unclosed.str.lit " + (char) c);
throw new JSONException(info("unclosed.str '\\" + (char) c));
}
}

Expand Down Expand Up @@ -1667,7 +1668,11 @@ public void read(Map object, long features) {

Object name;
if (match || typeRedirect) {
name = readFieldName();
if (ch >= '1' && ch <= '9') {
name = null;
} else {
name = readFieldName();
}
} else {
name = getFieldName();
match = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,10 @@ public final String getFieldName() {
@Override
public final String readFieldName() {
if (ch != '"' && ch != '\'') {
if ((context.features & Feature.AllowUnQuotedFieldNames.mask) != 0 && isFirstIdentifier(ch)) {
return readFieldNameUnquote();
}

return null;
}

Expand Down Expand Up @@ -1495,7 +1499,7 @@ public String readString() {
return null;
}
default:
throw new JSONException("TODO : " + ch);
throw new JSONException(info("illegal input : " + ch));
}
}
}
15 changes: 7 additions & 8 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java
Original file line number Diff line number Diff line change
Expand Up @@ -378,13 +378,8 @@ public final String readReference() {
next();
}

while (ch == '/') {
next();
if (ch == '/') {
skipLineComment();
} else {
throw new JSONException("input not support " + ch + ", offset " + offset);
}
while (ch == '/' && this.offset < this.chars.length && this.chars[this.offset] == '/') {
skipLineComment();
}
}

Expand Down Expand Up @@ -1731,6 +1726,10 @@ public final String readFieldName() {
}

if (ch != '"' && ch != '\'') {
if ((context.features & Feature.AllowUnQuotedFieldNames.mask) != 0 && isFirstIdentifier(ch)) {
return readFieldNameUnquote();
}

return null;
}

Expand Down Expand Up @@ -3828,7 +3827,7 @@ public String readString() {
return null;
}
default:
throw new JSONException("TODO : " + ch);
throw new JSONException(info("illegal input : " + ch));
}
}

Expand Down
33 changes: 11 additions & 22 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,8 @@ class JSONReaderUTF8
this.end = length;
next();

while (ch == '/') {
next();
if (ch == '/') {
skipLineComment();
} else {
throw new JSONException("input not support " + ch + ", offset " + offset);
}
while (ch == '/' && this.offset < this.bytes.length && this.bytes[this.offset] == '/') {
skipLineComment();
}
}

Expand All @@ -98,13 +93,8 @@ class JSONReaderUTF8
this.end = length;
next();

while (ch == '/') {
next();
if (ch == '/') {
skipLineComment();
} else {
throw new JSONException("input not support " + ch + ", offset " + offset);
}
while (ch == '/' && this.offset < this.bytes.length && this.bytes[this.offset] == '/') {
skipLineComment();
}
}

Expand All @@ -120,13 +110,8 @@ class JSONReaderUTF8
this.cacheItem = null;
next();

while (ch == '/') {
next();
if (ch == '/') {
skipLineComment();
} else {
throw new JSONException("input not support " + ch + ", offset " + offset);
}
while (ch == '/' && this.offset < this.bytes.length && this.bytes[this.offset] == '/') {
skipLineComment();
}
}

Expand Down Expand Up @@ -1448,6 +1433,10 @@ public String getFieldName() {
@Override
public String readFieldName() {
if (ch != '"' && ch != '\'') {
if ((context.features & Feature.AllowUnQuotedFieldNames.mask) != 0 && isFirstIdentifier(ch)) {
return readFieldNameUnquote();
}

return null;
}

Expand Down Expand Up @@ -4029,7 +4018,7 @@ public String readString() {
return null;
}
default:
throw new JSONException("TODO : " + ch);
throw new JSONException(info("illegal input : " + ch));
}
}

Expand Down
41 changes: 41 additions & 0 deletions core/src/test/java/com/alibaba/fastjson2/read/ObjectKeyTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.alibaba.fastjson2.read;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class ObjectKeyTest {
@Test
public void test() {
assertEquals(1, JSON.parseObject("{\"items\":{{}:{\"id\":123}}}", Bean.class).items.size());
assertEquals(1, JSON.parseObject("{\"items\":{1:{\"id\":123}}}", Bean.class).items.size());
assertEquals(1, JSON.parseObject("{\"items\":{true:{\"id\":123}}}", Bean.class).items.size());
assertEquals(1, JSON.parseObject("{\"items\":{false:{\"id\":123}}}", Bean.class).items.size());
assertEquals(1, JSON.parseObject("{\"items\":{null:{\"id\":123}}}", Bean.class).items.size());
}

@Test
public void test1() {
String s = "{items:{k1:{id:123}}}";
assertEquals(1, JSON.parseObject(s, Bean.class, JSONReader.Feature.AllowUnQuotedFieldNames).items.size());
byte[] bytes = s.getBytes();
assertEquals(1, JSON.parseObject(bytes, 0, bytes.length, StandardCharsets.UTF_8, Bean.class, JSONReader.Feature.AllowUnQuotedFieldNames).items.size());
assertEquals(1, JSON.parseObject(bytes, Bean.class, JSONReader.Feature.AllowUnQuotedFieldNames).items.size());
assertEquals(1, JSON.parseObject(s.toCharArray(), Bean.class, JSONReader.Feature.AllowUnQuotedFieldNames).items.size());
assertEquals(1, ((Bean) JSON.parseObject(s.toCharArray(), (Type) Bean.class, JSONReader.Feature.AllowUnQuotedFieldNames)).items.size());
}

public static class Bean {
public Map<String, Item> items;
}

public static class Item {
public int id;
}
}
Loading

0 comments on commit 06ed3a5

Please sign in to comment.