Documentation ¶
Overview ¶
Package lowmemjson is an alternative to the standard library's encoding/json that has lower memory requirements for large data structures.
Index ¶
- Constants
- Variables
- func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) error
- func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) error) error
- func DecodeString(in io.RuneScanner, out fastio.RuneWriter) error
- type BackslashEscapeMode
- func EscapeDefault(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
- func EscapeDefaultNonHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
- func EscapeHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
- func EscapeJSSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
- func EscapePreserve(_ rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
- type BackslashEscaper
- type Decodable
- type DecodeArgumentError
- type DecodeError
- type DecodeReadError
- type DecodeSyntaxError
- type DecodeTypeError
- type Decoder
- type Encodable
- type EncodeMethodError
- type EncodeTypeError
- type EncodeValueError
- type EncodeWriteError
- type Encoder
- type InvalidUTF8Mode
- type Number
- type RawMessage
- type ReEncodeSyntaxError
- type ReEncodeWriteError
- type ReEncoder
- type ReEncoderConfig
Constants ¶
const ( InvalidUTF8Replace = jsonstring.InvalidUTF8Replace InvalidUTF8Preserve = jsonstring.InvalidUTF8Preserve InvalidUTF8Error = jsonstring.InvalidUTF8Error )
const ( BackslashEscapeNone = jsonstring.BackslashEscapeNone BackslashEscapeShort = jsonstring.BackslashEscapeShort BackslashEscapeRawByte = jsonstring.BackslashEscapeRawByte BackslashEscapeUnicodeXXXX = jsonstring.BackslashEscapeUnicodeXXXX BackslashEscapeUnicodeXXXx = jsonstring.BackslashEscapeUnicodeXXXx BackslashEscapeUnicodeXXxX = jsonstring.BackslashEscapeUnicodeXXxX BackslashEscapeUnicodeXXxx = jsonstring.BackslashEscapeUnicodeXXxx BackslashEscapeUnicodeXxXX = jsonstring.BackslashEscapeUnicodeXxXX BackslashEscapeUnicodeXxXx = jsonstring.BackslashEscapeUnicodeXxXx BackslashEscapeUnicodeXxxX = jsonstring.BackslashEscapeUnicodeXxxX BackslashEscapeUnicodeXxxx = jsonstring.BackslashEscapeUnicodeXxxx BackslashEscapeUnicodexXXX = jsonstring.BackslashEscapeUnicodexXXX BackslashEscapeUnicodexXXx = jsonstring.BackslashEscapeUnicodexXXx BackslashEscapeUnicodexXxX = jsonstring.BackslashEscapeUnicodexXxX BackslashEscapeUnicodexXxx = jsonstring.BackslashEscapeUnicodexXxx BackslashEscapeUnicodexxXX = jsonstring.BackslashEscapeUnicodexxXX BackslashEscapeUnicodexxXx = jsonstring.BackslashEscapeUnicodexxXx BackslashEscapeUnicodexxxX = jsonstring.BackslashEscapeUnicodexxxX BackslashEscapeUnicodexxxx = jsonstring.BackslashEscapeUnicodexxxx BackslashEscapeUnicodeMin = jsonstring.BackslashEscapeUnicodeMin BackslashEscapeUnicodeMax = jsonstring.BackslashEscapeUnicodeMax BackslashEscapeUnicode = jsonstring.BackslashEscapeUnicode // back-compat )
Variables ¶
ErrDecodeNonEmptyInterface is the base error that a *DecodeTypeError wraps when Decode is asked to unmarshal into an `interface` type that has one or more methods.
ErrInvalidUnreadRune is returned to Decodable.DecodeJSON(scanner) implementations from scanner.UnreadRune() if the last operation was not a successful .ReadRune() call.
var ErrParserExceededMaxDepth = jsonparse.ErrParserExceededMaxDepth
ErrParserExceededMaxDepth is the base error that a *DecodeSyntaxError wraps when the depth of the JSON document exceeds 10000.
Functions ¶
func DecodeArray ¶
func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) error
DecodeArray is a helper function to ease implementing the Decoder interface; allowing the lowmemjson package to handle decoding the array syntax, while the Decodable only needs to handle decoding members within the array.
Outside of implementing Decodable.DecodeJSON methods, callers should instead simply use NewDecoder(r).Decode(&val) rather than attempting to call DecodeArray directly.
func DecodeObject ¶
func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) error) error
DecodeObject is a helper function to ease implementing the Decodable interface; allowing the lowmemjson package to handle decoding the object syntax, while the Decodable only needs to handle decoding the keys and values within the object.
Outside of implementing Decodable.DecodeJSON methods, callers should instead simply use NewDecoder(r).Decode(&val) rather than attempting to call DecodeObject directly.
func DecodeString ¶ added in v0.3.8
func DecodeString(in io.RuneScanner, out fastio.RuneWriter) error
DecodeString is a helper function to eas implementing the Decodable interface; allowing the lowmemjson package to handle decoding character escapes and such, while the Decodable only needs to handle what to do with the decoded runes.
Outside of implementing Decodable.DecodeJSON methods, callers should instead simply use NewDecoder(r).Decode(&val) rather than attempting to call DecodeString directly.
Types ¶
type BackslashEscapeMode ¶
type BackslashEscapeMode = jsonstring.BackslashEscapeMode
BackslashEscapeMode identifies one of the four ways that a character may be represented in a JSON string:
literally (no backslash escaping)
as a short "well-known" `\X` backslash sequence (where `X` is a single-character)
as a long Unicode `\uXXXX` backslash sequence (with 16 permutations of capitalization)
as a raw byte; this allows you to emit invalid JSON; JSON must be valid UTF-8, but this allows you to emit arbitrary binary data. If the character does not satisfy `utf8.RuneSelf <= char <= 0xFF`, then the encoder will panic.
func EscapeDefault ¶
func EscapeDefault(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
EscapeDefault is a BackslashEscaper that mimics the default behavior of encoding/json.
It is like EscapeHTMLSafe, but also uses long Unicode `\uXXXX` sequences for `\b` and `\f`
A ReEncoder uses EscapeDefault if a BackslashEscaper is not specified.
func EscapeDefaultNonHTMLSafe ¶
func EscapeDefaultNonHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
EscapeDefaultNonHTMLSafe is a BackslashEscaper that mimics the default behavior of an encoding/json.Encoder that has had SetEscapeHTML(false) called on it.
It is like EscapeJSSafe, but also uses long Unicode `\uXXXX` sequences for `\b` and `\f`.
func EscapeHTMLSafe ¶
func EscapeHTMLSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
EscapeHTMLSafe is a BackslashEscaper that escapes strings such that the JSON is safe to embed in HTML; it otherwise preserves the original input escaping.
func EscapeJSSafe ¶
func EscapeJSSafe(c rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
EscapeJSSafe is a BackslashEscaper that escapes strings such that the JSON safe to embed in JS; it otherwise preserves the original input escaping.
JSON is notionally a JS subset, but that's not actually true; so more conservative backslash-escaping is necessary to safely embed it in JS. http://timelessrepo.com/json-isnt-a-javascript-subset
func EscapePreserve ¶
func EscapePreserve(_ rune, wasEscaped BackslashEscapeMode) BackslashEscapeMode
EscapePreserve is a BackslashEscaper that preserves the original input escaping.
type BackslashEscaper ¶
type BackslashEscaper = func(rune, BackslashEscapeMode) BackslashEscapeMode
A BackslashEscaper controls how a ReEncoder emits a character in a JSON string. The `rune` argument is the character being considered, and the `BackslashEscapeMode` argument is how it was originally encoded in the input.
The ReEncoder will panic if a BackslashEscaper returns an unknown BackslashEscapeMode. However, a BackslashEscaper should be permissive of BackslashEscapeModes it doesn't recognize; it is safe to just return them unmodified.
type Decodable ¶
type Decodable interface {
DecodeJSON(io.RuneScanner) error
}
Decodable is the interface implemented by types that can decode a JSON representation of themselves. Decodable is a low-memory-overhead replacement for the json.Unmarshaler interface.
On the io.RuneScanner passed to DecodeJSON:
.UnreadRune() will return ErrInvalidUnreadRune if the last operation was not a successful .ReadRune() call.
.ReadRune() will return io.EOF at the end of the JSON value; it is not possible for .ReadRune() to read past the end of the value in to another value.
.ReadRune() will never return invalid JSON; if invalid JSON is encountered, it will use a panic-based mechanism to transfer control back to the Decoder.
.ReadRune() never return an error other than io.EOF; if an I/O error is encountered, it will use a panic-based mechanism to transfer control back to the Decoder.
DecodeJSON is expected to consume the entire scanner until io.EOF or another is encountered; if it does not, then the parent Decode call will return a *DecodeTypeError.
DecodeJSON should return nil (not io.EOF) on success.
Implementor's note: "withLimitingScanner" is the thing to search for in decode.go if you want to read up on that io.RuneScanner.
type DecodeArgumentError ¶
type DecodeArgumentError = json.InvalidUnmarshalError
A DecodeArgumentError is returned from Decode if the argument is not a non-nil pointer or is not settable.
Alternatively, a *DecodeArgument error may be found inside of a *DecodeTypeError if the type being decoded into is not a type that can be decoded into (such as map with non-stringable type as keys).
type DecodeArgumentError struct { Type reflect.Type }
type DecodeError ¶
type DecodeError struct { Field string // Where in the JSON the error was, in the form "v[idx][idx][idx]". Err error // What the error was. FieldParent string // for compat; the same as encoding/json.UnmarshalTypeError.Struct FieldName string // for compat; the same as encoding/json.UnmarshalTypeError.Field }
A DecodeError is returned from Decode for all errors except for *DecodeArgumentError.
A *DecodeError wraps *DecodeSyntaxError for malformed or illegal input, *DecodeTypeError for Go type issues, or *DecodeReadError for I/O errors.
func (*DecodeError) Error ¶
func (e *DecodeError) Error() string
func (*DecodeError) Unwrap ¶
func (e *DecodeError) Unwrap() error
type DecodeReadError ¶
A DecodeReadError is returned from Decode (wrapped in a *DecodeError) if there is an I/O error reading the input.
func (*DecodeReadError) Error ¶
func (e *DecodeReadError) Error() string
func (*DecodeReadError) Unwrap ¶
func (e *DecodeReadError) Unwrap() error
type DecodeSyntaxError ¶
A DecodeSyntaxError is returned from Decode (wrapped in a *DecodeError) if there is a syntax error in the input.
func (*DecodeSyntaxError) Error ¶
func (e *DecodeSyntaxError) Error() string
func (*DecodeSyntaxError) Unwrap ¶
func (e *DecodeSyntaxError) Unwrap() error
type DecodeTypeError ¶
type DecodeTypeError struct { JSONType string // (optional) GoType reflect.Type Offset int64 Err error // (optional) }
A DecodeTypeError is returned from Decode (wrapped in a *DecodeError) if the JSON input is not appropriate for the given Go type.
If a .DecodeJSON, .UnmarshalJSON, or .UnmashaleText method returns an error, it is wrapped in a *DecodeTypeError.
func (*DecodeTypeError) Error ¶
func (e *DecodeTypeError) Error() string
func (*DecodeTypeError) Unwrap ¶
func (e *DecodeTypeError) Unwrap() error
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
A Decoder reads and decodes values from an input stream of JSON elements.
Decoder is analogous to, and has a similar API to the standard library's encoding/json.Decoder. Differences are:
lowmemjson.NewDecoder takes an io.RuneScanner, while json.NewDecoder takes an io.Reader.
lowmemjson.Decoder does not have a .Buffered() method, while json.Decoder does.
lowmemjson.Decoder does not have a .Token() method, while json.Decoder does.
If something more similar to a json.Decoder is desired, lowmemjson/compat/json.NewDecoder takes an io.Reader (and turns it into an io.RuneScanner by wrapping it in a bufio.Reader), and lowmemjson/compat/json.Decoder has a .Buffered() method; though lowmemjson/compat/json.Decoder also lacks the .Token() method.
func NewDecoder ¶
func NewDecoder(r io.RuneScanner) *Decoder
NewDecoder returns a new Decoder that reads from r.
NewDecoder is analogous to the standard library's encoding/json.NewDecoder, but takes an io.RuneScanner rather than an io.Reader.
func (*Decoder) Decode ¶
Decode reads the next JSON element from the Decoder's input stream and stores it in the value pointed to by ptr.
See the documentation for encoding/json.Unmarshal for details about the conversion of JSON into a Go value; Decode behaves identically to that, with the exception that in addition to the json.Unmarshaler interface it also checks for the Decodable interface.
func (*Decoder) DecodeThenEOF ¶
DecodeThenEOF is like Decode, but emits an error if there is extra data after the JSON. A JSON document is specified to be a single JSON element; repeated calls to Decoder.Decode will happily decode a stream of multiple JSON elements.
func (*Decoder) DisallowUnknownFields ¶
func (dec *Decoder) DisallowUnknownFields()
DisallowUnknownFields causes the Decoder to return an error when the destination is a struct and the input contains object keys which do not match any non-ignored, exported fields in the destination.
This is identical to the standard library's encoding/json.Decoder.DisallowUnknownFields.
func (*Decoder) InputOffset ¶
InputOffset returns the input stream byte offset of the current decoder position. The offset gives the location of the rune that will be returned from the next call to .ReadRune().
This is identical to the standard library's encoding/json.Decoder.InputOffset.
func (*Decoder) More ¶
More reports whether there is more to the stream of JSON elements, or if the Decoder has reached EOF or an error.
More is identical to the standard library's encoding/json.Decoder.More.
type Encodable ¶
Encodable is the interface implemented by types that can encode themselves to JSON. Encodable is a low-memory-overhead replacement for the json.Marshaler interface.
The io.Writer passed to EncodeJSON returns an error if invalid JSON is written to it.
type EncodeMethodError ¶
type EncodeMethodError struct { Type reflect.Type // The Go type that the method is on SourceFunc string // The method: "EncodeJSON", "MarshalJSON", or "MarshalText" Err error // The error that the method returned }
An EncodeMethodError either wraps an error that is returned from an object's method when encoding that object to JSON, or wraps a *ReEncodeSyntaxError for the method's output.
func (*EncodeMethodError) Error ¶
func (e *EncodeMethodError) Error() string
func (*EncodeMethodError) Unwrap ¶
func (e *EncodeMethodError) Unwrap() error
type EncodeTypeError ¶
type EncodeTypeError = json.UnsupportedTypeError
An EncodeTypeError is returned by Encode when attempting to encode an unsupported type.
type EncodeTypeError struct { Type reflect.Type }
type EncodeValueError ¶
type EncodeValueError = json.UnsupportedValueError
An EncodeValueError is returned by Encode when attempting to encode an unsupported value (such as a datastructure with a cycle, or (if InvalidUTF8=InvalidUTF8Error) a string with invalid UTF-8).
type UnsupportedValueError struct { Value reflect.Value Str string }
type EncodeWriteError ¶ added in v0.3.6
A EncodeWriteError is returned from Encode if there is an error writing to the output stream.
func (*EncodeWriteError) Error ¶ added in v0.3.6
func (e *EncodeWriteError) Error() string
func (*EncodeWriteError) Unwrap ¶ added in v0.3.6
func (e *EncodeWriteError) Unwrap() error
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
An Encoder encodes and writes values to a stream of JSON elements.
Encoder is analogous to, and has a similar API to the standar library's encoding/json.Encoder. Differences are that rather than having .SetEscapeHTML and .SetIndent methods, the io.Writer passed to it may be a *ReEncoder that has these settings (and more). If something more similar to a json.Encoder is desired, lowmemjson/compat/json.Encoder offers those .SetEscapeHTML and .SetIndent methods.
func NewEncoder ¶
NewEncoder returns a new Encoder that writes to w.
If w is an *ReEncoder, then the inner backslash-escaping of double-encoded ",string" tagged string values obeys the *ReEncoder's BackslashEscape policy.
An Encoder tends to make many small writes; if w.Write calls are syscalls, then you may want to wrap w in a bufio.Writer.
func (*Encoder) Encode ¶
Encode encodes obj to JSON and writes that JSON to the Encoder's output stream.
See the documentation for encoding/json.Marshal for details about the conversion Go values to JSON; Encode behaves identically to that, with the exception that in addition to the json.Marshaler interface it also checks for the Encodable interface.
Unlike encoding/json.Encoder.Encode, lowmemjson.Encoder.Encode does not buffer its output; if a encode-error is encountered, lowmemjson may write partial output, whereas encodin/json would not have written anything.
type InvalidUTF8Mode ¶ added in v0.3.7
type InvalidUTF8Mode = jsonstring.InvalidUTF8Mode
InvalidUTF8Mode identifies one of the 3 ways that an Encoder or ReEncoder can behave when encountering invalid UTF-8 in a string value:
Replace the byte with the Unicode replacement character U+FFFD.
Allow the byte through to the string-encoder, with an escape-mode of BackslashEscapeRawByte.
Emit a syntax error.
type Number ¶ added in v0.3.6
A Number represents a JSON number value. It is represented as a string containing the raw JSON text; it is useful for preserving number values with perfect fidelity, but isn't so useful for use as a number value in a Go program.
type RawMessage ¶ added in v0.3.6
type RawMessage = json.RawMessage
A RawMessage is a raw encoded JSON value. This saves time when encoding or decoding, but does mean that the full text must be buffered when decoding.
type ReEncodeSyntaxError ¶
A ReEncodeSyntaxError is returned from ReEncoder's methods if there is a syntax error in the input.
func (*ReEncodeSyntaxError) Error ¶
func (e *ReEncodeSyntaxError) Error() string
func (*ReEncodeSyntaxError) Unwrap ¶
func (e *ReEncodeSyntaxError) Unwrap() error
type ReEncodeWriteError ¶ added in v0.3.6
A ReEncodeWriteError is returned from ReEncoder's methods if there is an error writing to the output stream.
func (*ReEncodeWriteError) Error ¶ added in v0.3.6
func (e *ReEncodeWriteError) Error() string
func (*ReEncodeWriteError) Unwrap ¶ added in v0.3.6
func (e *ReEncodeWriteError) Unwrap() error
type ReEncoder ¶
type ReEncoder struct {
// contains filtered or unexported fields
}
A ReEncoder takes a stream of JSON elements (by way of implementing io.Writer, io.StringWriter, io.ByteWriter, and WriteRune), and re-encodes the JSON, writing it to the .Out member.
This is useful for prettifying, minifying, sanitizing, and/or validating JSON.
The memory use of a ReEncoder is O(CompactIfUnder+depth).
func NewReEncoder ¶ added in v0.3.0
func NewReEncoder(out io.Writer, cfg ReEncoderConfig) *ReEncoder
NewReEncoder returns a new ReEncoder instance.
A ReEncoder tends to make many small writes; if Out.Write calls are syscalls, then you may want to wrap Out in a bufio.Writer.
func (*ReEncoder) Close ¶
Close implements io.Closer; it does what you'd expect, mostly.
The *ReEncoder may continue to be written to with new JSON values if enc.AllowMultipleValues is set.
func (*ReEncoder) Write ¶
Write implements io.Writer; it does what you'd expect.
It is worth noting that Write returns the number of bytes consumed from p, not number of bytes written to the output stream. This distinction that most io.Writer implementations don't need to make, but *ReEncoder does because it transforms the data written to it, and the number of bytes written may be wildly different than the number of bytes handled.
func (*ReEncoder) WriteByte ¶ added in v0.3.1
WriteByte implements io.ByteWriter; it does what you'd expect.
func (*ReEncoder) WriteRune ¶
WriteRune does what you'd expect.
type ReEncoderConfig ¶ added in v0.3.0
type ReEncoderConfig struct { // A JSON document is specified to be a single JSON element; // but it is often desirable to handle streams of multiple // JSON elements. AllowMultipleValues bool // Whether to minify the JSON. // // Trims all whitespace, except that it emits a newline // between two *number* top-level values (or puts a newline // after all top-level values if ForceTrailingNewlines). // // Trims superflous 0s from numbers. Compact bool // CompactIfUnder causes the *ReEncoder to behave as if // Compact=true for individual elements if doing so would // cause that element to be under this number of bytes. // // Has no affect if Compact is true or Indent is empty. // // his has O(2^min(CompactIfUnder, depth)) time overhead, so // set with caution. CompactIfUnder int // String to use to indent; ignored if Compact is true. // // Newlines are emitted *between* top-level values; a newline is // not emitted after the *last* top-level value (unless // ForceTrailingNewlines is on). Indent string // String to put before indents. Prefix string // Whether to emit a newline after each top-level value. See // the comments on Compact and Indent for discussion of how // this is different than the usual behavior. ForceTrailingNewlines bool // CompactFloats causes the *ReEncoder to trim unnecessary '0' // digits from floating-point number values. CompactFloats bool // A JSON document is specified to be a sequence of Unicode // codepoints; InvalidUTF8 controls how the *ReEncoder behaves // when it encounters invalid UTF-8 bytes in a JSON string // (i.e. the string is not representable as a sequence of // Unicode codepoints, and thus the document is invalid JSON). InvalidUTF8 InvalidUTF8Mode // Returns whether a given character in a string should be // backslash-escaped. The bool argument is whether it was // \u-escaped in the input. This does not affect characters // that must or must-not be escaped to be valid JSON. // // If not set, then EscapeDefault is used. BackslashEscape BackslashEscaper }
A ReEncoderConfig controls how a ReEncoder should behave.