Class JsonValueReader
- Namespace
- MassiveDotNet.Serialization
- Assembly
- MassiveDotNet.dll
Reads a scalar from a Utf8JsonReader positioned on its value token, reporting a malformed value as a JsonException.
public static class JsonValueReader
- Inheritance
-
JsonValueReader
- Inherited Members
Remarks
The generated model converters are built from these. Utf8JsonReader's own accessors are the wrong shape for that job: GetInt32() throws InvalidOperationException on a token of the wrong kind and FormatException on a number outside the target's range. Neither is a JsonException, so neither is recognised as a malformed body by the transport, and both would surface from an ordinary REST call as an exception type nothing documents.
One implementation rather than the same token check emitted into every generated converter,
for the reason decision D15 keeps filter rendering in RequestUriBuilder: it is tested
once here instead of once per generated file, and it cannot drift between them.
Every method leaves the reader on the value it read, so the caller's next Read() advances to the following property name.
Exactly one failure message echoes the value that caused it: the range failure raised when a
token is a number the target type cannot hold. This paragraph used to say that no method echoes
anything, and issue #65 is what reversed it. A streaming StockAggregate.z was refused in
production and the log said only that the number did not fit -- which cannot distinguish a
non-integral value from an integral one written as 12.0 from one genuinely past the
range. Those are three different causes with three different fixes, and the value is the only
thing that tells them apart.
The echo is confined to that one helper, and the confinement IS the rule 11 argument: it is
reachable only after its caller has checked
reader.TokenType == JsonTokenType.Number, which every caller does and no other path
reaches it, so the bytes it quotes are provably a JSON number -- and an API key is not a JSON
number. The safety is structural rather than a matter of care taken at each site. The
wrong-token-type failure names a token type and has no value in hand; the decimal round-trip
failure reads a String, where that proof does not hold and the class
of value it could quote back is unbounded. Neither echoes, and neither is to be changed to
(D-W21).
Methods
ReadBoolean(ref Utf8JsonReader, string, string)
Reads a boolean.
public static bool ReadBoolean(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
- bool
The boolean.
Exceptions
- JsonException
The token is not
trueorfalse.
ReadDecimal(ref Utf8JsonReader, string, string)
Reads a decimal the wire sent as a string, refusing any value that does not round-trip.
public static decimal ReadDecimal(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
- decimal
The decimal, with the scale the wire wrote.
Remarks
The fractional-share family -- dv, dav, ds, decimal_size,
decimal_volume -- is declared type: string at all 31 of its sites, so this
reads a String. A JSON number is refused, exactly as it was when
the family bound to string.
The parse is verified by formatting the result back and comparing bytes, rather than
predicted by counting digits. decimal rounds silently and returns
true when a value's scaled integer overflows its 96-bit mantissa --
8827.8140001491929689677164477 does at 29 digits while
12345678901234567890123456789 does not -- so digit count does not predict it, and a
threshold set at 29 leaked silent roundings across a randomized corpus. Round-tripping is
exact in both directions because the value carries its own scale, which is the same property
that lets 4989.0 keep its trailing zero (D38).
The guard also enforces canonical spelling, since a leading +, a redundant zero, a
thousands separator, surrounding whitespace, or exponent notation all format back
differently. That is stricter than "never rounds" and is accepted deliberately: Massive's
wire is canonical, and a refusal is visible where a silent normalisation is not.
Exceptions
- JsonException
The token is not a string, or the string is not a decimal this type can carry exactly.
ReadDouble(ref Utf8JsonReader, string, string)
Reads a double.
public static double ReadDouble(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
- double
The double.
Exceptions
- JsonException
The token is not a number, or does not fit a double.
ReadInt32(ref Utf8JsonReader, string, string)
Reads a 32-bit integer.
public static int ReadInt32(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
- int
The integer.
Exceptions
- JsonException
The token is not a number, or does not fit an int.
ReadInt64(ref Utf8JsonReader, string, string)
Reads a 64-bit integer.
public static long ReadInt64(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
- long
The integer.
Remarks
The range check matters more here than anywhere else in this file: nanosecond timestamps are stored raw as long (decision D5), and a value one past the range silently becoming a double would hand a caller a wrong instant with nothing to notice it.
Exceptions
- JsonException
The token is not a number, or does not fit a long.
ReadNullableBoolean(ref Utf8JsonReader, string, string)
Reads a boolean, or null from a JSON null.
public static bool? ReadNullableBoolean(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
Exceptions
- JsonException
The token is neither a boolean nor null.
ReadNullableDecimal(ref Utf8JsonReader, string, string)
Reads a decimal string, or null from a JSON null.
public static decimal? ReadNullableDecimal(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
Exceptions
- JsonException
The token is neither an exact decimal string nor null.
ReadNullableDouble(ref Utf8JsonReader, string, string)
Reads a double, or null from a JSON null.
public static double? ReadNullableDouble(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
Exceptions
- JsonException
The token is neither a fitting number nor null.
ReadNullableInt32(ref Utf8JsonReader, string, string)
Reads a 32-bit integer, or null from a JSON null.
public static int? ReadNullableInt32(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
Exceptions
- JsonException
The token is neither a fitting number nor null.
ReadNullableInt64(ref Utf8JsonReader, string, string)
Reads a 64-bit integer, or null from a JSON null.
public static long? ReadNullableInt64(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
Exceptions
- JsonException
The token is neither a fitting number nor null.
ReadString(ref Utf8JsonReader, string, string)
Reads a string, or null from a JSON null.
public static string? ReadString(ref Utf8JsonReader reader, string model, string property)
Parameters
readerUtf8JsonReaderA reader positioned on the value token.
modelstringThe model being read, named in the failure message.
propertystringThe property being read, named in the failure message.
Returns
Exceptions
- JsonException
The token is neither a string nor null.