All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.wycst.wast.json.JSONDefaultParser Maven / Gradle / Ivy

Go to download

Wast is a high-performance Java toolset library package that includes JSON, YAML, CSV, HttpClient, JDBC and EL engines

There is a newer version: 0.0.20
Show newest version
/*
 * Copyright [2020-2024] [wangyunchao]
 *
 * Licensed 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 io.github.wycst.wast.json;

import io.github.wycst.wast.common.reflect.GenericParameterizedType;
import io.github.wycst.wast.common.utils.EnvUtils;
import io.github.wycst.wast.json.exceptions.JSONException;
import io.github.wycst.wast.json.options.ReadOption;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 

默认解析器,根据字符的开头前缀解析为Map、List、String *

去掉类型check问题,理论上最快。 * * @Author wangyunchao * @Date 2022/5/31 21:28 */ public final class JSONDefaultParser extends JSONGeneral { /** * return Map or List * * @param json * @param readOptions * @return Map or List */ public static Object parse(String json, ReadOption... readOptions) { json.getClass(); if (EnvUtils.JDK_9_PLUS) { byte[] bytes = (byte[]) JSONUnsafe.getStringValue(json); if (bytes.length == json.length()) { return parseInternal(AsciiStringSource.of(json, bytes), bytes, 0, bytes.length, null, readOptions); } else { char[] chars = json.toCharArray(); return parseInternal(UTF16ByteArraySource.of(json), chars, 0, chars.length, null, readOptions); } } char[] chars = (char[]) JSONUnsafe.getStringValue(json); return parseInternal(null, chars, 0, chars.length, null, readOptions); } /** * 解析buf返回Map或者List * * @param buf * @param readOptions * @return */ public static Object parse(char[] buf, ReadOption... readOptions) { if (EnvUtils.JDK_9_PLUS) { String json = new String(buf); byte[] bytes = (byte[]) JSONUnsafe.getStringValue(json); if (bytes.length == buf.length) { return parseInternal(AsciiStringSource.of(json, bytes), bytes, 0, bytes.length, null, readOptions); } else { return parseInternal(UTF16ByteArraySource.of(json), buf, 0, buf.length, null, readOptions); } } return parseInternal(null, buf, 0, buf.length, null, readOptions); } /** * 指定外层的map类型 * * @param json * @param mapCls * @param readOptions * @return */ static Map parseMap(String json, Class mapCls, ReadOption... readOptions) { json.getClass(); if (EnvUtils.JDK_9_PLUS) { byte[] bytes = (byte[]) JSONUnsafe.getStringValue(json); if (bytes.length == json.length()) { return (Map) parseInternal(AsciiStringSource.of(json, bytes), bytes, 0, bytes.length, createMapInstance(mapCls), readOptions); } else { char[] chars = json.toCharArray(); return (Map) parseInternal(UTF16ByteArraySource.of(json), chars, 0, chars.length, createMapInstance(mapCls), readOptions); } } char[] chars = (char[]) JSONUnsafe.getStringValue(json); return (Map) parseInternal(null, chars, 0, chars.length, createMapInstance(mapCls), readOptions); } /** * 指定外层的map类型 * * @param json * @param listCls * @param readOptions * @return */ static Collection parseCollection(String json, Class listCls, ReadOption... readOptions) { json.getClass(); if (EnvUtils.JDK_9_PLUS) { byte[] bytes = (byte[]) JSONUnsafe.getStringValue(json); if (bytes.length == json.length()) { return (Collection) parseInternal(AsciiStringSource.of(json, bytes), bytes, 0, bytes.length, createCollectionInstance(listCls), readOptions); } else { char[] chars = json.toCharArray(); return (Collection) parseInternal(UTF16ByteArraySource.of(json), chars, 0, chars.length, createCollectionInstance(listCls), readOptions); } } char[] chars = (char[]) JSONUnsafe.getStringValue(json); return (Collection) parseInternal(null, chars, 0, chars.length, createCollectionInstance(listCls), readOptions); } static Object parseInternal(CharSource source, char[] buf, int fromIndex, int toIndex, Object defaultValue, ReadOption... readOptions) { char beginChar = '\0'; while ((fromIndex < toIndex) && (beginChar = buf[fromIndex]) <= ' ') { fromIndex++; } while ((toIndex > fromIndex) && buf[toIndex - 1] <= ' ') { toIndex--; } JSONParseContext jsonParseContext = new JSONParseContext(); JSONOptions.readOptions(readOptions, jsonParseContext); try { boolean allowComment = jsonParseContext.allowComment; if (allowComment && beginChar == '/') { fromIndex = clearCommentAndWhiteSpaces(buf, fromIndex + 1, toIndex, jsonParseContext); beginChar = buf[fromIndex]; } Object result; switch (beginChar) { case '{': result = parseJSONObject(source, buf, fromIndex, toIndex, defaultValue == null ? new LinkedHashMap() : (Map) defaultValue, jsonParseContext); break; case '[': result = parseJSONArray(source, buf, fromIndex, toIndex, defaultValue == null ? new ArrayList(10) : (Collection) defaultValue, jsonParseContext); break; case '\'': case '"': result = JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, buf, fromIndex, toIndex, beginChar, null, jsonParseContext); break; default: throw new UnsupportedOperationException("Unsupported for begin character with '" + beginChar + "'"); } int endIndex = jsonParseContext.endIndex; if (allowComment) { /** Remove comments at the end of the declaration */ if (endIndex < toIndex - 1) { char commentStart = '\0'; while (endIndex + 1 < toIndex && (commentStart = buf[++endIndex]) <= ' ') ; if (commentStart == '/') { endIndex = clearCommentAndWhiteSpaces(buf, endIndex + 1, toIndex, jsonParseContext); } } } if (endIndex != toIndex - 1) { int wordNum = Math.min(50, buf.length - endIndex - 1); String errorContextTextAt = createErrorContextText(buf, endIndex + 1); throw new JSONException("Syntax error, at pos " + endIndex + ", context text by '" + errorContextTextAt + "', extra characters found, '" + new String(buf, endIndex + 1, wordNum) + " ...'"); } return result; } catch (Exception ex) { handleCatchException(ex, buf, toIndex); throw new JSONException("Error: " + ex.getMessage(), ex); } finally { jsonParseContext.clear(); } } static Collection parseJSONArray(CharSource source, char[] buf, int fromIndex, int toIndex, Collection list, JSONParseContext jsonParseContext) throws Exception { char ch; int i = fromIndex; for (; ; ) { while ((ch = buf[++i]) <= ' ') ; if (jsonParseContext.allowComment) { if (ch == '/') { ch = buf[i = clearCommentAndWhiteSpaces(buf, i + 1, toIndex, jsonParseContext)]; } } if (ch == ']') { if (list.size() > 0 && !jsonParseContext.allowLastEndComma) { throw new JSONException("Syntax error, at pos " + i + ", the closing symbol ']' is not allowed here."); } jsonParseContext.endIndex = i; return list; } Object value; switch (ch) { case '{': { value = parseJSONObject(source, buf, i, toIndex, new LinkedHashMap(), jsonParseContext); list.add(value); i = jsonParseContext.endIndex; break; } case '[': { // Multilayer collections are relatively rare and can easily cause waste of collection space. The specified initialization capacity is displayed as 2 value = parseJSONArray(source, buf, i, toIndex, new ArrayList(2), jsonParseContext); list.add(value); i = jsonParseContext.endIndex; break; } case '\'': case '"': { value = JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, buf, i, toIndex, ch, null, jsonParseContext); list.add(value); i = jsonParseContext.endIndex; break; } case 'n': value = JSONTypeDeserializer.NULL.deserialize(null, buf, i, toIndex, null, null, '\0', jsonParseContext); i = jsonParseContext.endIndex; list.add(value); break; case 't': value = JSONTypeDeserializer.BOOLEAN.parseTrue(buf, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; list.add(value); break; case 'f': value = JSONTypeDeserializer.BOOLEAN.parseFalse(buf, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; list.add(value); break; default: { value = JSONTypeDeserializer.NUMBER.deserialize(source, buf, i, toIndex, jsonParseContext.useBigDecimalAsDefault ? GenericParameterizedType.BigDecimalType : GenericParameterizedType.AnyType, null, ']', jsonParseContext); i = jsonParseContext.endIndex; list.add(value); // either continue or return char next = buf[++i]; if (next == ']') { jsonParseContext.endIndex = i; return list; } else { continue; } } } while ((ch = buf[++i]) <= ' ') ; if (jsonParseContext.allowComment) { if (ch == '/') { ch = buf[i = clearCommentAndWhiteSpaces(buf, i + 1, toIndex, jsonParseContext)]; } } if (ch == ',') { continue; } if (ch == ']') { jsonParseContext.endIndex = i; return list; } String errorContextTextAt = createErrorContextText(buf, i); throw new JSONException("Syntax error, at pos " + i + ", context text by '" + errorContextTextAt + "', unexpected '" + ch + "', expected ',' or ']'"); } } static Map parseJSONObject(CharSource source, char[] buf, int fromIndex, int toIndex, Map instance, JSONParseContext jsonParseContext) throws Exception { int i = fromIndex; char ch; boolean empty = true; boolean allowomment = jsonParseContext.allowComment; boolean disableCacheMapKey = jsonParseContext.disableCacheMapKey; for (; ; ) { while ((ch = buf[++i]) <= ' ') ; if (allowomment) { if (ch == '/') { ch = buf[i = clearCommentAndWhiteSpaces(buf, i + 1, toIndex, jsonParseContext)]; } } Serializable key; int fieldKeyFrom = i; if (ch == '"') { key = disableCacheMapKey ? (String) JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, buf, i, toIndex, '"', null, jsonParseContext) : parseMapKeyByCache(buf, i, toIndex, '"', jsonParseContext); i = jsonParseContext.endIndex; empty = false; ++i; } else { if (ch == '}') { if (!empty && !jsonParseContext.allowLastEndComma) { throw new JSONException("Syntax error, at pos " + i + ", the closing symbol '}' is not allowed here."); } jsonParseContext.endIndex = i; return instance; } if (ch == '\'') { if (jsonParseContext.allowSingleQuotes) { while (i + 1 < toIndex && (buf[++i] != '\'' || buf[i - 1] == '\\')) ; empty = false; ++i; key = parseKeyOfMap(buf, fieldKeyFrom, i, false); } else { throw new JSONException("Syntax error, at pos " + i + ", the single quote symbol ' is not allowed here."); } } else { if (jsonParseContext.allowUnquotedFieldNames) { while (i + 1 < toIndex && buf[++i] != ':') ; empty = false; key = parseKeyOfMap(buf, fieldKeyFrom, i, true); } else { int j = i; boolean isNullKey = false; key = null; if (ch == 'n' && buf[++i] == 'u' && buf[++i] == 'l' && buf[++i] == 'l') { isNullKey = true; ++i; } if (!isNullKey) { String errorContextTextAt = createErrorContextText(buf, j); throw new JSONException("Syntax error, at pos " + j + ", context text by '" + errorContextTextAt + "', unexpected '" + ch + "', expected '\"' or use option ReadOption.AllowUnquotedFieldNames "); } } } } while ((ch = buf[i]) <= ' ') { ++i; } if (allowomment) { if (ch == '/') { ch = buf[i = clearCommentAndWhiteSpaces(buf, i + 1, toIndex, jsonParseContext)]; } } if (ch == ':') { while ((ch = buf[++i]) <= ' ') ; if (allowomment) { if (ch == '/') { ch = buf[i = clearCommentAndWhiteSpaces(buf, i + 1, toIndex, jsonParseContext)]; } } Object value; switch (ch) { case '{': { value = parseJSONObject(source, buf, i, toIndex, new LinkedHashMap(), jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; } case '[': { // 2 [ array value = parseJSONArray(source, buf, i, toIndex, new ArrayList(10), jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; } case '"': case '\'': { value = JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, buf, i, toIndex, ch, null, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; } case 'n': value = JSONTypeDeserializer.NULL.deserialize(null, buf, i, toIndex, null, null, '\0', jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; case 't': value = JSONTypeDeserializer.BOOLEAN.parseTrue(buf, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; case 'f': value = JSONTypeDeserializer.BOOLEAN.parseFalse(buf, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; default: { value = JSONTypeDeserializer.NUMBER.deserialize(source, buf, i, toIndex, jsonParseContext.useBigDecimalAsDefault ? GenericParameterizedType.BigDecimalType : GenericParameterizedType.AnyType, null, '}', jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); char next = buf[++i]; if (next == '}') { jsonParseContext.endIndex = i; return instance; } else { continue; } } } // clear white space characters while ((ch = buf[++i]) <= ' ') ; // clear comment and whiteSpaces if (allowomment) { if (ch == '/') { ch = buf[i = clearCommentAndWhiteSpaces(buf, i + 1, toIndex, jsonParseContext)]; } } if (ch == ',') { continue; } if (ch == '}') { jsonParseContext.endIndex = i; return instance; } String errorContextTextAt = createErrorContextText(buf, i); throw new JSONException("Syntax error, at pos " + i + ", context text by '" + errorContextTextAt + "', unexpected '" + ch + "', expected ',' or '}'"); } else { throw new JSONException("Syntax error, at pos " + i + ", unexpected '" + ch + "', token ':' is expected."); } } } // static String parseJSONString(CharSource charSource, char[] buf, int from, int toIndex, char endCh, JSONParseContext jsonParseContext) { // int beginIndex = from + 1; // JSONCharArrayWriter writer = null; // if (charSource != null) { // String source = charSource.input(); // int endIndex = source.indexOf(endCh, beginIndex); // if (!jsonParseContext.checkEscapeUseChar(source, beginIndex, endIndex)) { // jsonParseContext.endIndex = endIndex; // return new String(buf, beginIndex, endIndex - beginIndex); // } // // must exist \\ in range {beginIndex, endIndex} // writer = getContextWriter(jsonParseContext); // do { // int escapeIndex = jsonParseContext.getEscapeOffset(); // beginIndex = escapeNext(buf, buf[escapeIndex + 1], escapeIndex, beginIndex, writer, jsonParseContext); // if (beginIndex > endIndex) { // endIndex = source.indexOf(endCh, endIndex + 1); // } // } while (jsonParseContext.checkEscapeUseChar(source, beginIndex, endIndex)); // // jsonParseContext.endIndex = endIndex; // writer.write(charSource.input(), beginIndex, endIndex - beginIndex); // return writer.toString(); // } // return (String) JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(charSource, buf, from, toIndex, endCh, GenericParameterizedType.StringType, jsonParseContext); // char ch, next; // int i = beginIndex; // int len; // boolean escape = false; // for (; ; ++i) { // while ((ch = buf[i]) != '\\' && ch != endCh) { // ++i; // } // // ch is \\ or " // if (ch == '\\') { // next = buf[i + 1]; // if (writer == null) { // writer = getContextWriter(jsonParseContext); // escape = true; // } // beginIndex = escapeNext(buf, next, i, beginIndex, writer, jsonParseContext); // i = jsonParseContext.endIndex; // } else { // jsonParseContext.endIndex = i; // len = i - beginIndex; // if (escape) { // writer.write(buf, beginIndex, len); // return writer.toString(); // } else { // return new String(buf, beginIndex, len); // } // } // } // } static String parseMapKeyByCache(char[] buf, int from, int toIndex, char endCh, JSONParseContext jsonParseContext) { int beginIndex = from + 1; char ch; int i = from; int len; JSONCharArrayWriter writer = null; boolean escape = false; boolean ascii = true; for (; ; ) { long hashValue = ESCAPE; while ((ch = buf[++i]) != '\\' && ch != endCh) { if (ch > 0xFF) { hashValue = (hashValue << 16) | ch; ascii = false; } else { hashValue = hashValue << 8 | ch; } } if (ch == '\\') { if (writer == null) { writer = getContextWriter(jsonParseContext); } escape = true; beginIndex = escapeNext(buf, buf[i + 1], i, beginIndex, writer, jsonParseContext); i = jsonParseContext.endIndex; } else { jsonParseContext.endIndex = i; len = i - beginIndex; if (escape) { writer.write(buf, beginIndex, len); return writer.toString(); } else { if (ascii && len <= 8) { return jsonParseContext.getCacheEightCharsKey(buf, beginIndex, len, hashValue); } return jsonParseContext.getCacheKey(buf, beginIndex, len, hashValue); } } } } // bytes ##################################################################################################### static Object parseInternal(CharSource source, byte[] bytes, int fromIndex, int toIndex, Object defaultValue, ReadOption... readOptions) { byte beginByte = '\0'; while ((fromIndex < toIndex) && (beginByte = bytes[fromIndex]) <= ' ') { fromIndex++; } while ((toIndex > fromIndex) && bytes[toIndex - 1] <= ' ') { toIndex--; } JSONParseContext jsonParseContext = new JSONParseContext(); JSONOptions.readOptions(readOptions, jsonParseContext); try { boolean allowComment = jsonParseContext.allowComment; if (allowComment && beginByte == '/') { fromIndex = clearCommentAndWhiteSpaces(bytes, fromIndex + 1, toIndex, jsonParseContext); beginByte = bytes[fromIndex]; } Object result; switch (beginByte) { case '{': result = parseJSONObject(source, bytes, fromIndex, toIndex, defaultValue == null ? new LinkedHashMap() : (Map) defaultValue, jsonParseContext); break; case '[': result = parseJSONArray(source, bytes, fromIndex, toIndex, defaultValue == null ? new ArrayList() : (Collection) defaultValue, jsonParseContext); break; case '\'': case '"': result = JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, bytes, fromIndex, toIndex, beginByte, GenericParameterizedType.StringType, jsonParseContext); break; default: throw new UnsupportedOperationException("Unsupported for begin character with '" + beginByte + "'"); } int endIndex = jsonParseContext.endIndex; if (allowComment) { if (endIndex < toIndex - 1) { char commentStart = '\0'; while (endIndex + 1 < toIndex && (commentStart = (char) bytes[++endIndex]) <= ' ') ; if (commentStart == '/') { endIndex = clearCommentAndWhiteSpaces(bytes, endIndex + 1, toIndex, jsonParseContext); } } } if (endIndex != toIndex - 1) { int wordNum = Math.min(50, bytes.length - endIndex - 1); String errorContextTextAt = createErrorContextText(bytes, endIndex + 1); throw new JSONException("Syntax error, at pos " + endIndex + ", context text by '" + errorContextTextAt + "', extra characters found, '" + new String(bytes, endIndex + 1, wordNum) + " ...'"); } return result; } catch (Exception ex) { handleCatchException(ex, bytes, toIndex); throw new JSONException("Error: " + ex.getMessage(), ex); } finally { jsonParseContext.clear(); } } static Collection parseJSONArray(CharSource source, byte[] bytes, int fromIndex, int toIndex, Collection list, JSONParseContext jsonParseContext) throws Exception { byte b; int i = fromIndex; for (; ; ) { while ((b = bytes[++i]) <= ' ') ; if (jsonParseContext.allowComment) { if (b == '/') { b = bytes[i = clearCommentAndWhiteSpaces(bytes, i + 1, toIndex, jsonParseContext)]; } } if (b == ']') { if (list.size() > 0 && !jsonParseContext.allowLastEndComma) { throw new JSONException("Syntax error, at pos " + i + ", the closing symbol ']' is not allowed here."); } jsonParseContext.endIndex = i; return list; } Object value; switch (b) { case '{': { value = parseJSONObject(source, bytes, i, toIndex, new LinkedHashMap(), jsonParseContext); list.add(value); i = jsonParseContext.endIndex; break; } case '[': { value = parseJSONArray(source, bytes, i, toIndex, new ArrayList(), jsonParseContext); list.add(value); i = jsonParseContext.endIndex; break; } case '\'': case '"': { value = JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, bytes, i, toIndex, b, GenericParameterizedType.StringType, jsonParseContext); list.add(value); i = jsonParseContext.endIndex; break; } case 'n': value = JSONTypeDeserializer.parseNull(bytes, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; list.add(value); break; case 't': value = JSONTypeDeserializer.parseTrue(bytes, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; list.add(value); break; case 'f': value = JSONTypeDeserializer.parseFalse(bytes, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; list.add(value); break; default: { value = JSONTypeDeserializer.NUMBER.deserialize(source, bytes, i, toIndex, jsonParseContext.useBigDecimalAsDefault ? GenericParameterizedType.BigDecimalType : GenericParameterizedType.AnyType, null, END_ARRAY, jsonParseContext); i = jsonParseContext.endIndex; list.add(value); byte next = bytes[++i]; if (next == END_ARRAY) { jsonParseContext.endIndex = i; return list; } else { continue; } } } while ((b = bytes[++i]) <= ' ') ; if (jsonParseContext.allowComment) { if (b == '/') { b = bytes[i = clearCommentAndWhiteSpaces(bytes, i + 1, toIndex, jsonParseContext)]; } } if (b == ',') { continue; } if (b == ']') { jsonParseContext.endIndex = i; return list; } String errorContextTextAt = createErrorContextText(bytes, i); throw new JSONException("Syntax error, at pos " + i + ", context text by '" + errorContextTextAt + "', unexpected '" + b + "', expected ',' or ']'"); } } static Map parseJSONObject(CharSource source, byte[] bytes, int fromIndex, int toIndex, Map instance, JSONParseContext jsonParseContext) throws Exception { byte b; boolean empty = true, allowomment = jsonParseContext.allowComment, disableCacheMapKey = jsonParseContext.disableCacheMapKey; int i = fromIndex; for (; ; ) { while ((b = bytes[++i]) <= ' ') ; if (allowomment) { if (b == '/') { b = bytes[i = clearCommentAndWhiteSpaces(bytes, i + 1, toIndex, jsonParseContext)]; } } Serializable key; int fieldKeyFrom = i; if (b == '"') { key = disableCacheMapKey ? JSONTypeDeserializer.parseMapKey(bytes, i, toIndex, '"', jsonParseContext) : JSONTypeDeserializer.parseMapKeyByCache(bytes, i, toIndex, '"', jsonParseContext); i = jsonParseContext.endIndex; empty = false; ++i; } else { if (b == '}') { if (!empty && !jsonParseContext.allowLastEndComma) { throw new JSONException("Syntax error, at pos " + i + ", the closing symbol '}' is not allowed here."); } jsonParseContext.endIndex = i; return instance; } if (b == '\'') { if (jsonParseContext.allowSingleQuotes) { while (i + 1 < toIndex && (bytes[++i] != '\'' || bytes[i - 1] == '\\')) ; empty = false; ++i; key = parseKeyOfMap(bytes, fieldKeyFrom, i, false); } else { throw new JSONException("Syntax error, at pos " + i + ", the single quote symbol ' is not allowed here."); } } else { if (jsonParseContext.allowUnquotedFieldNames) { while (i + 1 < toIndex && bytes[++i] != ':') ; empty = false; key = parseKeyOfMap(bytes, fieldKeyFrom, i, true); } else { int j = i; boolean isNullKey = false; key = null; if (b == 'n' && bytes[++i] == 'u' && bytes[++i] == 'l' && bytes[++i] == 'l') { isNullKey = true; ++i; } if (!isNullKey) { String errorContextTextAt = createErrorContextText(bytes, j); throw new JSONException("Syntax error, at pos " + j + ", context text by '" + errorContextTextAt + "', unexpected '" + b + "', expected '\"' or use option ReadOption.AllowUnquotedFieldNames "); } } } } while ((b = bytes[i]) <= ' ') { ++i; } if (allowomment) { if (b == '/') { b = bytes[i = clearCommentAndWhiteSpaces(bytes, i + 1, toIndex, jsonParseContext)]; } } if (b == ':') { while ((b = bytes[++i]) <= ' ') ; if (jsonParseContext.allowComment) { if (b == '/') { b = bytes[i = clearCommentAndWhiteSpaces(bytes, i + 1, toIndex, jsonParseContext)]; } } Object value; switch (b) { case '{': { value = parseJSONObject(source, bytes, i, toIndex, new LinkedHashMap(), jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; } case '[': { value = parseJSONArray(source, bytes, i, toIndex, new ArrayList(), jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; } case '"': case '\'': { value = JSONTypeDeserializer.CHAR_SEQUENCE_STRING.deserializeString(source, bytes, i, toIndex, b, GenericParameterizedType.StringType, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; } case 'n': value = JSONTypeDeserializer.parseNull(bytes, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; case 't': value = JSONTypeDeserializer.parseTrue(bytes, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; case 'f': value = JSONTypeDeserializer.parseFalse(bytes, i, toIndex, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); break; default: { value = JSONTypeDeserializer.NUMBER.deserialize(source, bytes, i, toIndex, jsonParseContext.useBigDecimalAsDefault ? GenericParameterizedType.BigDecimalType : GenericParameterizedType.AnyType, null, END_OBJECT, jsonParseContext); i = jsonParseContext.endIndex; instance.put(key, value); byte next = bytes[++i]; if (next == END_OBJECT) { jsonParseContext.endIndex = i; return instance; } else { continue; } } } while ((b = bytes[++i]) <= ' ') ; if (allowomment) { if (b == '/') { b = bytes[i = clearCommentAndWhiteSpaces(bytes, i + 1, toIndex, jsonParseContext)]; } } if (b == COMMA) { continue; } if (b == END_OBJECT) { jsonParseContext.endIndex = i; return instance; } String errorContextTextAt = createErrorContextText(bytes, i); throw new JSONException("Syntax error, at pos " + i + ", context text by '" + errorContextTextAt + "', unexpected token '" + (char) b + "', expected ',' or '}'"); } else { throw new JSONException("Syntax error, at pos " + i + ", unexpected '" + (char) b + "', colon ':' is expected."); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy