JsonOptions class

A JsonOptions object holds the options of one call to the package: the syntax that Json.Parse accepts, the layout that Json.Serialize writes, the limits on input, and how a schema is checked. It is passed as the last argument of the functions that take options, and Nothing there means the defaults of Rfc.

An options object is created from a preset. The predeclared object JsonOptions, written without a variable, is a factory: its four properties Rfc, Jsonc, Minified and Pretty each return a new object with every property set, and Clone copies one.

Dim o As JsonOptions = JsonOptions.Minified
o.SortsKeys = True
Debug.Print Json.Serialize(Json.Map("b", 1, "a", 2), o)   ' {"a":2,"b":1}
Debug.Print o.Indent                                      ' -1
Debug.Print JsonOptions.Rfc.Indent                        ' 4

A property of an options object checks nothing when it is set. The value is used by the call that receives the object, and a call does not change the object.

Important

Assigning a property on the predeclared object itself raises run-time error 5, Invalid procedure call or argument, with the source JsonOptions and the message JsonOptions (default instance) is a factory. Use Rfc, Jsonc, Minified, or Pretty. Create an options object first and assign the properties of that.

On Error Resume Next
JsonOptions.Indent = 2
Debug.Print Err.Number         ' 5
Debug.Print Err.Source         ' JsonOptions
Debug.Print Err.Description    ' JsonOptions (default instance) is a factory. Use Rfc, Jsonc, Minified, or Pretty.

Reading a property of the predeclared object does not raise an error. It returns the empty value of the type, 0, False or an empty string, and not the default of the property.

Debug.Print JsonOptions.Indent & "|" & JsonOptions.MaxDepth & "|" & JsonOptions.EscapesSolidus & "|" & JsonOptions.Newline & "|" & JsonOptions.Syntax & "|" & JsonOptions.MaxBytes
' Output:
' 0|0|False||0|0

Note

The class declares a Private constructor and the attribute [COMCreatable(False)], so that only its presets create options objects. In BETA 1005 twinBASIC does not enforce a Private constructor, and a project that references the package can still create an object with New. Every property of such an object has the empty value of its type: Indent 0, an empty Newline, Syntax jsRfc8259, and a limit of 0, which means no limit. The text it writes has no line breaks and no indentation, but still a space after each colon. The presets are the way to get the defaults.

Dim jo As JsonOptions = New JsonOptions
Debug.Print Json.Serialize(Json.Map("a", 1, "b", Json.Arr(1, 2)), jo)    ' {"a": 1,"b": [1,2]}
jo.Indent = 2
jo.Newline = vbLf
Debug.Print Replace(Json.Serialize(Json.Map("a", 1), jo), vbLf, "|")     ' {|  "a": 1|}

Where each property is used

Properties Used by
Syntax, DuplicateKeys, MaxDepth, MaxStringLength, MaxArrayItems, MaxObjectMembers The parse functions: Parse, ParseFile, ParseLines, ParseLinesFile and the Try versions. For the lines functions, each line is a document.
Encoding, MaxBytes The parse functions for bytes and files. MaxBytes also limits a String passed to Parse, counted in UTF-8 bytes, but not the text of ParseLines.
Indent, Newline, SortsKeys, EscapesSolidus, EnsuresAscii The serialize functions: Serialize, SerializeToUtf8, WriteFile, SerializeLines, WriteLinesFile, and Dump of JsonObject and JsonArray. SerializeLines ignores Indent.
MaxDepth Also Serialize and the functions that call it, and the evaluation of a schema.
IncludesBom SerializeToUtf8, WriteFile and WriteLinesFile.
IsFormatAssertion Json.Validate and JsonSchema.Validate.

The options do not reach JSONPath. A path expression nests at most 1000 levels whatever MaxDepth is.

Presets

Rfc

Returns a new options object with the defaults of RFC 8259.

Syntax: options = JsonOptions.Rfc

The object is independent of every other one, so it can be changed. These are its values:

Property Value
Indent 4
Newline vbLf
Syntax jsRfc8259
Encoding jekAuto
IncludesBom False
DuplicateKeys jdkError
SortsKeys, EscapesSolidus, EnsuresAscii, IsFormatAssertion False
MaxDepth 1000
MaxBytes 16777216 (16 MiB)
MaxStringLength 1048576 (1 MiB)
MaxArrayItems 1000000
MaxObjectMembers 1000000
Dim o As JsonOptions = JsonOptions.Rfc
Debug.Print o.Indent & " " & o.MaxDepth & " " & o.MaxBytes     ' 4 1000 16777216
Debug.Print o Is JsonOptions.Rfc                               ' False

Jsonc

Returns a new options object that accepts JSONC.

Syntax: options = JsonOptions.Jsonc

The same as Rfc, with Syntax set to jsJsonc.

Minified

Returns a new options object for compact output.

Syntax: options = JsonOptions.Minified

The same as Rfc, with Indent set to -1.

Pretty

Returns a new options object for pretty-printed output.

Syntax: options = JsonOptions.Pretty

The same as Rfc, which indents by 4 spaces.

Clone

Returns a copy of an options object.

Syntax: options**.Clone** ( ) As JsonOptions

The copy has the same values and is independent: a change to it does not change the original.

Dim a As JsonOptions = JsonOptions.Rfc
a.Indent = 2
Dim b As JsonOptions = a.Clone()
b.Indent = 8
Debug.Print a.Indent                                      ' 2
Debug.Print b.Indent                                      ' 8
Debug.Print JsonOptions.Rfc.Indent                        ' 4

Format properties

EnsuresAscii

Whether non-ASCII characters are written as escapes. A Boolean, False by default.

Syntax: options**.EnsuresAscii** [ = flag ]

When True, Serialize writes each UTF-16 code unit above U+007F as \uxxxx with lowercase hexadecimal digits, so a character outside the Basic Multilingual Plane becomes two escapes, a surrogate pair. The result contains only ASCII characters.

Dim o As JsonOptions = JsonOptions.Minified
o.EnsuresAscii = True
o.EscapesSolidus = True
Debug.Print Json.Serialize(ChrW$(233) & "a/b", o)         ' "\u00e9a\/b"

EscapesSolidus

Whether the solidus is written as an escape. A Boolean, False by default.

Syntax: options**.EscapesSolidus** [ = flag ]

When True, Serialize writes / as \/. Both spellings are valid JSON for the same character.

Indent

The indentation of pretty-printed output. A Long, 4 by default.

Syntax: options**.Indent** [ = spaces ]

A value of 0 or more starts every member and element on a new line, indented by that many spaces for each level of nesting, and writes a space after each colon. A value of 0 has line breaks and no indentation. A value below 0, and -1 in Minified, writes the text without white space.

Dim o As JsonOptions = JsonOptions.Pretty
o.Indent = 2
o.SortsKeys = True
Dim line As Variant
For Each line In Split(Json.Serialize(Json.Map("b", 1, "a", Json.Arr(True)), o), vbLf)
    Debug.Print line
Next
' Output:
' {
'   "a": [
'     true
'   ],
'   "b": 1
' }

Newline

The text that ends a line of pretty-printed output. A String, vbLf by default.

Syntax: options**.Newline** [ = text ]

Any string can be used, such as vbCrLf. It is not used when Indent is below 0.

SortsKeys

Whether the keys of an object are written in sorted order. A Boolean, False by default.

Syntax: options**.SortsKeys** [ = flag ]

When True, Serialize writes the members of every object in the order of their keys, compared by UTF-16 code unit. The objects themselves keep their order.

Parse properties

DuplicateKeys

What a repeated key in an object means. An eJsonDuplicateKeys member, jdkError by default.

Syntax: options**.DuplicateKeys** [ = policy ]

With jdkError, a repeated key is the error DuplicateKey. With jdkLastWins, the last value is kept, in the position of the first member with that key.

Dim text As String = "{""a"":1,""b"":2,""a"":3}"
Debug.Print IsEmpty(Json.Parse(text))                     ' True
Debug.Print JsonError.Code                                ' DuplicateKey

Dim o As JsonOptions = JsonOptions.Rfc
o.DuplicateKeys = jdkLastWins
Debug.Print Json.Serialize(Json.Parse(text, o), JsonOptions.Minified)   ' {"a":3,"b":2}

The members of the three enumerations are written without a qualifier, as jdkLastWins is above; so are their names as types. The qualified form JsonOptions.eJsonSyntax.jsJsonc does not compile (TB5027, Unrecognized member).

Dim s As eJsonSyntax = jsJsonc
Dim t As eJsonType = jtArray
Dim e As eJsonEncodingKind = jekUtf16Be
Debug.Print s & " " & t & " " & e                         ' 1 5 3
Dim o As JsonOptions = JsonOptions.Rfc
o.Syntax = JsonOptions.eJsonSyntax.jsJsonc

Encoding

The encoding of bytes and files that are parsed. An eJsonEncodingKind member, jekAuto by default.

Syntax: options**.Encoding** [ = kind ]

With jekAuto, a byte order mark selects UTF-8, UTF-16 little endian or UTF-16 big endian, and the encoding is UTF-8 without one. With another member, the bytes are decoded in that encoding, and a byte order mark of the same encoding at the start is skipped. The property does not affect a String, and it is not used when text is written, which is always UTF-8.

Syntax

The JSON dialect that is accepted. An eJsonSyntax member, jsRfc8259 by default.

Syntax: options**.Syntax** [ = dialect ]

jsRfc8259 accepts only the JSON of RFC 8259. jsJsonc also accepts comments, from // to the end of the line and between /* and */, wherever white space is allowed, and one comma after the last member of an object or the last element of an array. A comment that is not closed is the error InvalidComment. Parsing never keeps a comment.

Dim text As String = "{""a"": 1, // first" & vbLf & """b"": [1, 2,], /* last */ }"
Debug.Print IsEmpty(Json.Parse(text))                     ' True
Debug.Print JsonError.Code                                ' InvalidSyntax

Dim v As Variant = Json.Parse(text, JsonOptions.Jsonc)
Debug.Print Json.Serialize(v, JsonOptions.Minified)       ' {"a":1,"b":[1,2]}

Output properties

IncludesBom

Whether UTF-8 output starts with a byte order mark. A Boolean, False by default.

Syntax: options**.IncludesBom** [ = flag ]

When True, SerializeToUtf8, WriteFile and WriteLinesFile put the bytes EF BB BF first. Serialize writes a string and is not affected.

Limits

A limit of 0 means that there is no limit, and so does a value below 0. A limit that is exceeded is the error LimitExceeded, except MaxDepth, which is DepthLimitExceeded.

MaxArrayItems

The largest number of elements in an array that is parsed. A Long, 1000000 by default.

Syntax: options**.MaxArrayItems** [ = n ]

MaxBytes

The largest size of the input that is parsed. A Long, 16777216 (16 MiB) by default.

Syntax: options**.MaxBytes** [ = n ]

For a byte array it is the number of bytes. For a file it is the size of the file. For a String passed to Parse it is the number of bytes of its UTF-8 encoding. ParseLines does not check it for its text.

MaxDepth

The deepest level of nesting. A Long, 1000 by default.

Syntax: options**.MaxDepth** [ = n ]

The root value is at depth 0. A value inside a container is one level deeper than the container. A value deeper than MaxDepth is the error DepthLimitExceeded, for a scalar as for a container. The limit applies to parsing, to serializing, and to the evaluation of a schema, where each nested subschema and each $ref that is followed counts as a level.

Dim o As JsonOptions = JsonOptions.Rfc
o.MaxDepth = 2
Debug.Print IsEmpty(Json.Parse("[[1]]", o))               ' False
Debug.Print IsEmpty(Json.Parse("[[[1]]]", o))             ' True
Debug.Print JsonError.Code                                ' DepthLimitExceeded

MaxObjectMembers

The largest number of members in an object that is parsed. A Long, 1000000 by default.

Syntax: options**.MaxObjectMembers** [ = n ]

MaxStringLength

The longest string that is parsed, in UTF-16 code units. A Long, 1048576 (1 MiB) by default.

Syntax: options**.MaxStringLength** [ = n ]

The limit applies to the keys of objects as to the other strings. It is not applied when a value is written.

Schema properties

IsFormatAssertion

Whether the format keyword of a schema is checked. A Boolean, False by default.

Syntax: options**.IsFormatAssertion** [ = flag ]

By default format only annotates, as the schema specification asks: no value is rejected for its format. When True, a string that does not have the format named in the schema is a validation error. JsonSchema lists the formats that are checked.

Enumerations

eJsonDuplicateKeys

What a repeated key in an object means. DuplicateKeys takes one of these members.

Member Value Meaning
jdkError 0 A repeated key is the error DuplicateKey.
jdkLastWins 1 The last value is kept.

eJsonEncodingKind

The encoding of bytes that are parsed. Encoding takes one of these members.

Member Value Meaning
jekAuto 0 A byte order mark selects the encoding; otherwise UTF-8.
jekUtf8 1 UTF-8.
jekUtf16Le 2 UTF-16, little endian.
jekUtf16Be 3 UTF-16, big endian.

eJsonSyntax

The JSON dialect that is parsed. Syntax takes one of these members.

Member Value Meaning
jsRfc8259 0 JSON as RFC 8259 defines it.
jsJsonc 1 JSON with comments and a trailing comma.

See Also