Package com.dslplatform.json
Class JsonReader<TContext>
- java.lang.Object
-
- com.dslplatform.json.JsonReader<TContext>
-
- Type Parameters:
TContext- context passed to deserialized object instances
public final class JsonReader<TContext> extends java.lang.ObjectObject for processing JSON from byte[] and InputStream. DSL-JSON works on byte level (instead of char level). Deserialized instances can obtain TContext information provided with this reader.JsonReader can be reused by calling process methods.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceJsonReader.BindObject<T>Existing instances can be provided as target for deserialization.static classJsonReader.DoublePrecisionprivate static classJsonReader.EmptyEOFExceptionstatic classJsonReader.ErrorInfostatic interfaceJsonReader.ReadJsonObject<T extends JsonObject>static interfaceJsonReader.ReadObject<T>Custom objects can be deserialized based on the implementation specified through this interface.static classJsonReader.UnknownNumberParsingprivate static classJsonReader.WithObjectReader<T extends JsonObject>private static classJsonReader.WithReader<T>
-
Field Summary
Fields Modifier and Type Field Description protected byte[]bufferprivate intbufferLenWithExtraSpaceprotected char[]charsTContextcontextprivate intcurrentIndexprivate longcurrentPositionprotected intdoubleLengthLimitprotected JsonReader.DoublePrecisiondoublePrecisionprivate static java.io.EOFExceptioneofprivate java.lang.StringBuildererrorprivate java.util.FormattererrorFormatterprotected JsonReader.ErrorInfoerrorInfoprivate StringCachekeyCacheprivate bytelastprivate intlastNameLenprivate intlengthprotected intmaxNumberDigitsprivate intmaxStringBufferprivate intnameEndprivate byte[]originalBufferprivate intoriginalBufferLenWithExtraSpaceprivate intreadLimitprivate java.io.InputStreamstreamprivate char[]tmpprivate inttokenStartprivate TypeLookuptypeLookupprotected JsonReader.UnknownNumberParsingunknownNumbersprivate StringCachevaluesCacheprivate static boolean[]WHITESPACE
-
Constructor Summary
Constructors Modifier Constructor Description (package private)JsonReader(byte[] buffer, int length, TContext context, char[] tmp, StringCache keyCache, StringCache valuesCache, TypeLookup typeLookup, JsonReader.ErrorInfo errorInfo, JsonReader.DoublePrecision doublePrecision, JsonReader.UnknownNumberParsing unknownNumbers, int maxNumberDigits, int maxStringBuffer)privateJsonReader(char[] tmp, byte[] buffer, int length, TContext context, StringCache keyCache, StringCache valuesCache, TypeLookup typeLookup, JsonReader.ErrorInfo errorInfo, JsonReader.DoublePrecision doublePrecision, JsonReader.UnknownNumberParsing unknownNumbers, int maxNumberDigits, int maxStringBuffer)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description (package private) booleanallWhitespace(int start, int end)java.lang.StringBufferappendString(java.lang.StringBuffer buffer)java.lang.StringBuilderappendString(java.lang.StringBuilder builder)intcalcHash()private intcalcHashAndCopyName(long hash, int ci)intcalcWeakHash()private intcalcWeakHashAndCopyName(int hash, int ci)voidcheckArrayEnd()Check if the last read token is an array endvoidcheckObjectEnd()Check if the last read token is an object endvoidcomma()Will advance to next token and check if it's comma<T extends JsonObject>
java.util.ArrayList<T>deserializeCollection(JsonReader.ReadJsonObject<T> readObject)<T extends JsonObject>
voiddeserializeCollection(JsonReader.ReadJsonObject<T> readObject, java.util.Collection<T> res)<T,S extends T>
java.util.ArrayList<T>deserializeCollection(JsonReader.ReadObject<S> readObject)<T,S extends T>
voiddeserializeCollection(JsonReader.ReadObject<S> readObject, java.util.Collection<T> res)<T extends JsonObject>
java.util.ArrayList<T>deserializeNullableCollection(JsonReader.ReadJsonObject<T> readObject)<T extends JsonObject>
voiddeserializeNullableCollection(JsonReader.ReadJsonObject<T> readObject, java.util.Collection<T> res)<T,S extends T>
java.util.ArrayList<T>deserializeNullableCollection(JsonReader.ReadObject<S> readObject)<T,S extends T>
voiddeserializeNullableCollection(JsonReader.ReadObject<S> readObject, java.util.Collection<T> res)voidendArray()Will advance to next token and check if it's array endvoidendObject()Will advance to next token and check it it's object endintfillName()intfillNameWeakHash()(package private) intfindNonWhitespace(int end)intgetCurrentIndex()intgetLastHash()java.lang.StringgetLastName()bytegetNextToken()Read next token (byte) from input JSON.intgetTokenStart()private inthexToInt(byte value)(package private) booleanisEndOfStream()<T extends JsonObject>
java.util.Iterator<T>iterateOver(JsonReader.ReadJsonObject<T> reader)<T> java.util.Iterator<T>iterateOver(JsonReader.ReadObject<T> reader)bytelast()Which was last byte read from the JSON input.intlength()Valid length of the input buffer.ParsingExceptionnewParseError(java.lang.String description)ParsingExceptionnewParseError(java.lang.String description, int positionOffset)ParsingExceptionnewParseErrorAt(java.lang.String description, int positionOffset)ParsingExceptionnewParseErrorAt(java.lang.String description, int positionOffset, java.lang.Exception cause)ParsingExceptionnewParseErrorFormat(java.lang.String shortDescription, int positionOffset, java.lang.String longDescriptionFormat, java.lang.Object... arguments)ParsingExceptionnewParseErrorWith(java.lang.String shortDescription, int positionOffset, java.lang.String longDescriptionPrefix, java.lang.String longDescriptionMessage, java.lang.Object argument, java.lang.String longDescriptionSuffix)ParsingExceptionnewParseErrorWith(java.lang.String description, java.lang.Object argument)<T> Tnext(JsonReader.BindObject<T> binder, T instance)Will advance to next token and bind the JSON to provided instance<T> Tnext(JsonReader.ReadObject<T> reader)Will advance to next token and read the JSON into specified type<T> Tnext(java.lang.Class<T> manifest)Will advance to next token and read the JSON into specified type<T> Tnext(java.lang.Class<T> manifest, T instance)Will advance to next token and bind the JSON to provided instance(package private) intparseString()java.lang.StringpositionDescription()java.lang.StringpositionDescription(int offset)private voidpositionDescription(int offset, java.lang.StringBuilder error)longpositionInStream()longpositionInStream(int offset)(package private) char[]prepareBuffer(int start, int len)private intprepareNextBlock()JsonReader<TContext>process(byte[] newBuffer, int newLength)Bind byte[] buffer for processing.JsonReader<TContext>process(java.io.InputStream stream)Bind input stream for processing.byteread()Read next byte from the JSON input.<T> T[]readArray(JsonReader.ReadObject<T> readObject, T[] emptyArray)byte[]readBase64()<T> java.util.ArrayList<T>readCollection(JsonReader.ReadObject<T> readObject)private static intreadFully(byte[] buffer, java.io.InputStream stream, int offset)java.lang.StringreadKey()Read key value of JSON input.<K,V>
java.util.LinkedHashMap<K,V>readMap(JsonReader.ReadObject<K> readKey, JsonReader.ReadObject<V> readValue)java.lang.StringreadNext()Deprecated.private java.lang.ObjectreadNull(java.lang.Class<?> manifest)char[]readNumber()Deprecated.<T> java.util.LinkedHashSet<T>readSet(JsonReader.ReadObject<T> readObject)char[]readSimpleQuote()Read simple "ascii string" into temporary buffer.java.lang.StringreadSimpleString()Read simple ascii string.java.lang.StringreadString()Read string from JSON input.(package private) voidreset()Reset reader after processing input It will release reference to provided byte[] or InputStream input(package private) voidreset(int size)Deprecated.voidreset(java.io.InputStream stream)Deprecated.intscanNumber()voidsemicolon()Will advance to next token and check if it's semicolonbyteskip()Skip to next non-whitespace token (byte) Will not allocate memory while skipping over JSON input.private byteskipString()voidstartArray()Will advance to next token and check if it's array startvoidstartAttribute(java.lang.String name)voidstartObject()Will advance to next token and check if it's object startjava.lang.StringtoString()booleanwasFalse()Checks if 'false' value is at current position.booleanwasLastName(byte[] name)booleanwasLastName(java.lang.String name)booleanwasNull()Checks if 'null' value is at current position.booleanwasTrue()Checks if 'true' value is at current position.private booleanwasWhiteSpace()(package private) booleanwithStackTrace()
-
-
-
Field Detail
-
WHITESPACE
private static final boolean[] WHITESPACE
-
tokenStart
private int tokenStart
-
nameEnd
private int nameEnd
-
currentIndex
private int currentIndex
-
currentPosition
private long currentPosition
-
last
private byte last
-
length
private int length
-
tmp
private final char[] tmp
-
context
public final TContext context
-
buffer
protected byte[] buffer
-
chars
protected char[] chars
-
stream
private java.io.InputStream stream
-
readLimit
private int readLimit
-
bufferLenWithExtraSpace
private int bufferLenWithExtraSpace
-
keyCache
private final StringCache keyCache
-
valuesCache
private final StringCache valuesCache
-
typeLookup
private final TypeLookup typeLookup
-
originalBuffer
private final byte[] originalBuffer
-
originalBufferLenWithExtraSpace
private final int originalBufferLenWithExtraSpace
-
errorInfo
protected final JsonReader.ErrorInfo errorInfo
-
doublePrecision
protected final JsonReader.DoublePrecision doublePrecision
-
doubleLengthLimit
protected final int doubleLengthLimit
-
unknownNumbers
protected final JsonReader.UnknownNumberParsing unknownNumbers
-
maxNumberDigits
protected final int maxNumberDigits
-
maxStringBuffer
private final int maxStringBuffer
-
eof
private static final java.io.EOFException eof
-
error
private final java.lang.StringBuilder error
-
errorFormatter
private final java.util.Formatter errorFormatter
-
lastNameLen
private int lastNameLen
-
-
Constructor Detail
-
JsonReader
private JsonReader(char[] tmp, byte[] buffer, int length, @Nullable TContext context, @Nullable StringCache keyCache, @Nullable StringCache valuesCache, @Nullable TypeLookup typeLookup, JsonReader.ErrorInfo errorInfo, JsonReader.DoublePrecision doublePrecision, JsonReader.UnknownNumberParsing unknownNumbers, int maxNumberDigits, int maxStringBuffer)
-
JsonReader
JsonReader(byte[] buffer, int length, @Nullable TContext context, char[] tmp, @Nullable StringCache keyCache, @Nullable StringCache valuesCache, @Nullable TypeLookup typeLookup, JsonReader.ErrorInfo errorInfo, JsonReader.DoublePrecision doublePrecision, JsonReader.UnknownNumberParsing unknownNumbers, int maxNumberDigits, int maxStringBuffer)
-
-
Method Detail
-
reset
@Deprecated public final void reset(java.io.InputStream stream) throws java.io.IOExceptionDeprecated.Will be removed. Exists only for backward compatibility- Parameters:
stream- process stream- Throws:
java.io.IOException- error reading from stream
-
reset
@Deprecated final void reset(int size)
Deprecated.Will be removed. Exists only for backward compatibility- Parameters:
size- size of byte[] input to use
-
reset
final void reset()
Reset reader after processing input It will release reference to provided byte[] or InputStream input
-
process
public final JsonReader<TContext> process(@Nullable java.io.InputStream stream) throws java.io.IOException
Bind input stream for processing. Stream will be processed in byte[] chunks. If stream is null, reference to stream will be released.- Parameters:
stream- set input stream- Returns:
- itself
- Throws:
java.io.IOException- unable to read from stream
-
process
public final JsonReader<TContext> process(@Nullable byte[] newBuffer, int newLength)
Bind byte[] buffer for processing. If this method is used in combination with process(InputStream) this buffer will be used for processing chunks of stream. If null is sent for byte[] buffer, new length for valid input will be set for existing buffer.- Parameters:
newBuffer- new buffer to use for processingnewLength- length of buffer which can be used- Returns:
- itself
-
length
public final int length()
Valid length of the input buffer.- Returns:
- size of JSON input
-
toString
public java.lang.String toString()
- Overrides:
toStringin classjava.lang.Object
-
readFully
private static int readFully(byte[] buffer, java.io.InputStream stream, int offset) throws java.io.IOException- Throws:
java.io.IOException
-
withStackTrace
boolean withStackTrace()
-
read
public final byte read() throws java.io.IOExceptionRead next byte from the JSON input. If buffer has been read in full IOException will be thrown- Returns:
- next byte
- Throws:
java.io.IOException- when end of JSON input
-
prepareNextBlock
private int prepareNextBlock() throws java.io.IOException- Throws:
java.io.IOException
-
isEndOfStream
final boolean isEndOfStream() throws java.io.IOException- Throws:
java.io.IOException
-
last
public final byte last()
Which was last byte read from the JSON input. JsonReader doesn't allow to go back, but it remembers previously read byte- Returns:
- which was the last byte read
-
positionDescription
public java.lang.String positionDescription()
-
positionDescription
public java.lang.String positionDescription(int offset)
-
positionDescription
private void positionDescription(int offset, java.lang.StringBuilder error)
-
newParseError
public final ParsingException newParseError(java.lang.String description)
-
newParseError
public final ParsingException newParseError(java.lang.String description, int positionOffset)
-
newParseErrorAt
public final ParsingException newParseErrorAt(java.lang.String description, int positionOffset)
-
newParseErrorAt
public final ParsingException newParseErrorAt(java.lang.String description, int positionOffset, java.lang.Exception cause)
-
newParseErrorFormat
public final ParsingException newParseErrorFormat(java.lang.String shortDescription, int positionOffset, java.lang.String longDescriptionFormat, java.lang.Object... arguments)
-
newParseErrorWith
public final ParsingException newParseErrorWith(java.lang.String description, @Nullable java.lang.Object argument)
-
newParseErrorWith
public final ParsingException newParseErrorWith(java.lang.String shortDescription, int positionOffset, java.lang.String longDescriptionPrefix, java.lang.String longDescriptionMessage, @Nullable java.lang.Object argument, java.lang.String longDescriptionSuffix)
-
getTokenStart
public final int getTokenStart()
-
getCurrentIndex
public final int getCurrentIndex()
-
readNumber
@Deprecated public final char[] readNumber()
Deprecated.will be removed. not used anymore- Returns:
- parsed chars from a number
-
scanNumber
public final int scanNumber()
-
prepareBuffer
final char[] prepareBuffer(int start, int len) throws ParsingException- Throws:
ParsingException
-
allWhitespace
final boolean allWhitespace(int start, int end)
-
findNonWhitespace
final int findNonWhitespace(int end)
-
readSimpleString
public final java.lang.String readSimpleString() throws ParsingExceptionRead simple ascii string. Will not use values cache to create instance.- Returns:
- parsed string
- Throws:
ParsingException- unable to parse string
-
readSimpleQuote
public final char[] readSimpleQuote() throws ParsingExceptionRead simple "ascii string" into temporary buffer. String length must be obtained through getTokenStart and getCurrentToken- Returns:
- temporary buffer
- Throws:
ParsingException- unable to parse string
-
readString
public final java.lang.String readString() throws java.io.IOExceptionRead string from JSON input. If values cache is used, string will be looked up from the cache.String value must start and end with a double quote (").
- Returns:
- parsed string
- Throws:
java.io.IOException- error reading string input
-
appendString
public final java.lang.StringBuilder appendString(java.lang.StringBuilder builder) throws java.io.IOException- Throws:
java.io.IOException
-
appendString
public final java.lang.StringBuffer appendString(java.lang.StringBuffer buffer) throws java.io.IOException- Throws:
java.io.IOException
-
parseString
final int parseString() throws java.io.IOException- Throws:
java.io.IOException
-
hexToInt
private int hexToInt(byte value) throws ParsingException- Throws:
ParsingException
-
wasWhiteSpace
private boolean wasWhiteSpace()
-
getNextToken
public final byte getNextToken() throws java.io.IOExceptionRead next token (byte) from input JSON. Whitespace will be skipped and next non-whitespace byte will be returned.- Returns:
- next non-whitespace byte in the JSON input
- Throws:
java.io.IOException- unable to get next byte (end of stream, ...)
-
positionInStream
public final long positionInStream()
-
positionInStream
public final long positionInStream(int offset)
-
fillName
public final int fillName() throws java.io.IOException- Throws:
java.io.IOException
-
fillNameWeakHash
public final int fillNameWeakHash() throws java.io.IOException- Throws:
java.io.IOException
-
calcHash
public final int calcHash() throws java.io.IOException- Throws:
java.io.IOException
-
calcWeakHash
public final int calcWeakHash() throws java.io.IOException- Throws:
java.io.IOException
-
getLastHash
public final int getLastHash()
-
calcHashAndCopyName
private int calcHashAndCopyName(long hash, int ci) throws java.io.IOException- Throws:
java.io.IOException
-
calcWeakHashAndCopyName
private int calcWeakHashAndCopyName(int hash, int ci) throws java.io.IOException- Throws:
java.io.IOException
-
wasLastName
public final boolean wasLastName(java.lang.String name)
-
wasLastName
public final boolean wasLastName(byte[] name)
-
getLastName
public final java.lang.String getLastName() throws java.io.IOException- Throws:
java.io.IOException
-
skipString
private byte skipString() throws java.io.IOException- Throws:
java.io.IOException
-
skip
public final byte skip() throws java.io.IOExceptionSkip to next non-whitespace token (byte) Will not allocate memory while skipping over JSON input.- Returns:
- next non-whitespace byte
- Throws:
java.io.IOException- unable to read next byte (end of stream, invalid JSON, ...)
-
readNext
@Deprecated public java.lang.String readNext() throws java.io.IOExceptionDeprecated.will be removed- Returns:
- not used anymore
- Throws:
java.io.IOException- throws if invalid JSON detected
-
readBase64
public final byte[] readBase64() throws java.io.IOException- Throws:
java.io.IOException
-
readKey
public final java.lang.String readKey() throws java.io.IOExceptionRead key value of JSON input. If key cache is used, it will be looked up from there.- Returns:
- parsed key value
- Throws:
java.io.IOException- unable to parse string input
-
wasNull
public final boolean wasNull() throws ParsingExceptionChecks if 'null' value is at current position. This means last read byte was 'n' and 'ull' are next three bytes. If last byte was n but next three are not 'ull' it will throw since that is not a valid JSON construct.- Returns:
- true if 'null' value is at current position
- Throws:
ParsingException- invalid 'null' value detected
-
wasTrue
public final boolean wasTrue() throws ParsingExceptionChecks if 'true' value is at current position. This means last read byte was 't' and 'rue' are next three bytes. If last byte was t but next three are not 'rue' it will throw since that is not a valid JSON construct.- Returns:
- true if 'true' value is at current position
- Throws:
ParsingException- invalid 'true' value detected
-
wasFalse
public final boolean wasFalse() throws ParsingExceptionChecks if 'false' value is at current position. This means last read byte was 'f' and 'alse' are next four bytes. If last byte was f but next four are not 'alse' it will throw since that is not a valid JSON construct.- Returns:
- true if 'false' value is at current position
- Throws:
ParsingException- invalid 'false' value detected
-
comma
public final void comma() throws java.io.IOExceptionWill advance to next token and check if it's comma- Throws:
java.io.IOException- it's not comma
-
semicolon
public final void semicolon() throws java.io.IOExceptionWill advance to next token and check if it's semicolon- Throws:
java.io.IOException- it's not semicolon
-
startArray
public final void startArray() throws java.io.IOExceptionWill advance to next token and check if it's array start- Throws:
java.io.IOException- it's not array start
-
endArray
public final void endArray() throws java.io.IOExceptionWill advance to next token and check if it's array end- Throws:
java.io.IOException- it's not array end
-
startObject
public final void startObject() throws java.io.IOExceptionWill advance to next token and check if it's object start- Throws:
java.io.IOException- it's not object start
-
endObject
public final void endObject() throws java.io.IOExceptionWill advance to next token and check it it's object end- Throws:
java.io.IOException- it's not object end
-
startAttribute
public final void startAttribute(java.lang.String name) throws java.io.IOException- Throws:
java.io.IOException
-
checkArrayEnd
public final void checkArrayEnd() throws java.io.IOExceptionCheck if the last read token is an array end- Throws:
java.io.IOException- it's not array end
-
checkObjectEnd
public final void checkObjectEnd() throws java.io.IOExceptionCheck if the last read token is an object end- Throws:
java.io.IOException- it's not object end
-
readNull
@Nullable private java.lang.Object readNull(java.lang.Class<?> manifest) throws java.io.IOException
- Throws:
java.io.IOException
-
next
@Nullable public final <T> T next(java.lang.Class<T> manifest) throws java.io.IOException
Will advance to next token and read the JSON into specified type- Type Parameters:
T- type- Parameters:
manifest- type to read into- Returns:
- new instance from input JSON
- Throws:
java.io.IOException- unable to process JSON
-
next
@Nullable public final <T> T next(JsonReader.ReadObject<T> reader) throws java.io.IOException
Will advance to next token and read the JSON into specified type- Type Parameters:
T- type- Parameters:
reader- reader to use- Returns:
- new instance from input JSON
- Throws:
java.io.IOException- unable to process JSON
-
next
@Nullable public final <T> T next(java.lang.Class<T> manifest, T instance) throws java.io.IOException
Will advance to next token and bind the JSON to provided instance- Type Parameters:
T- type- Parameters:
manifest- type to read intoinstance- instance to bind- Returns:
- bound instance
- Throws:
java.io.IOException- unable to process JSON
-
next
@Nullable public final <T> T next(JsonReader.BindObject<T> binder, T instance) throws java.io.IOException
Will advance to next token and bind the JSON to provided instance- Type Parameters:
T- type- Parameters:
binder- binder to useinstance- instance to bind- Returns:
- bound instance
- Throws:
java.io.IOException- unable to process JSON
-
readCollection
@Nullable public final <T> java.util.ArrayList<T> readCollection(JsonReader.ReadObject<T> readObject) throws java.io.IOException
- Throws:
java.io.IOException
-
readSet
@Nullable public final <T> java.util.LinkedHashSet<T> readSet(JsonReader.ReadObject<T> readObject) throws java.io.IOException
- Throws:
java.io.IOException
-
readMap
@Nullable public final <K,V> java.util.LinkedHashMap<K,V> readMap(JsonReader.ReadObject<K> readKey, JsonReader.ReadObject<V> readValue) throws java.io.IOException
- Throws:
java.io.IOException
-
readArray
@Nullable public final <T> T[] readArray(JsonReader.ReadObject<T> readObject, T[] emptyArray) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeCollection
public final <T,S extends T> java.util.ArrayList<T> deserializeCollection(JsonReader.ReadObject<S> readObject) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeCollection
public final <T,S extends T> void deserializeCollection(JsonReader.ReadObject<S> readObject, java.util.Collection<T> res) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeNullableCollection
public final <T,S extends T> java.util.ArrayList<T> deserializeNullableCollection(JsonReader.ReadObject<S> readObject) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeNullableCollection
public final <T,S extends T> void deserializeNullableCollection(JsonReader.ReadObject<S> readObject, java.util.Collection<T> res) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeCollection
public final <T extends JsonObject> java.util.ArrayList<T> deserializeCollection(JsonReader.ReadJsonObject<T> readObject) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeCollection
public final <T extends JsonObject> void deserializeCollection(JsonReader.ReadJsonObject<T> readObject, java.util.Collection<T> res) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeNullableCollection
public final <T extends JsonObject> java.util.ArrayList<T> deserializeNullableCollection(JsonReader.ReadJsonObject<T> readObject) throws java.io.IOException
- Throws:
java.io.IOException
-
deserializeNullableCollection
public final <T extends JsonObject> void deserializeNullableCollection(JsonReader.ReadJsonObject<T> readObject, java.util.Collection<T> res) throws java.io.IOException
- Throws:
java.io.IOException
-
iterateOver
public final <T> java.util.Iterator<T> iterateOver(JsonReader.ReadObject<T> reader)
-
iterateOver
public final <T extends JsonObject> java.util.Iterator<T> iterateOver(JsonReader.ReadJsonObject<T> reader)
-
-