type DecodeOptions … type Decoder … type decodeBuffer … // NewDecoder constructs a new streaming decoder reading from r. // // If r is a bytes.Buffer, then the decoder parses directly from the buffer // without first copying the contents to an intermediate buffer. // Additional writes to the buffer must not occur while the decoder is in use. func NewDecoder(r io.Reader) *Decoder { … } // NewDecoder constructs a new streaming decoder reading from r // configured with the provided options. func (o DecodeOptions) NewDecoder(r io.Reader) *Decoder { … } // ResetDecoder resets a decoder such that it is reading afresh from r and // configured with the provided options. func (o DecodeOptions) ResetDecoder(d *Decoder, r io.Reader) { … } func (d *Decoder) reset(b []byte, r io.Reader, o DecodeOptions) { … } // Reset resets a decoder such that it is reading afresh from r but // keep any pre-existing decoder options. func (d *Decoder) Reset(r io.Reader) { … } var errBufferWriteAfterNext … // fetch reads at least 1 byte from the underlying io.Reader. // It returns io.ErrUnexpectedEOF if zero bytes were read and io.EOF was seen. func (d *Decoder) fetch() error { … } const invalidateBufferByte … // invalidatePreviousRead invalidates buffers returned by Peek and Read calls // so that the first byte is an invalid character. // This Hyrum-proofs the API against faulty application code that assumes // values returned by ReadValue remain valid past subsequent Read calls. func (d *decodeBuffer) invalidatePreviousRead() { … } // needMore reports whether there are no more unread bytes. func (d *decodeBuffer) needMore(pos int) bool { … } // injectSyntacticErrorWithPosition wraps a SyntacticError with the position, // otherwise it returns the error as is. // It takes a position relative to the start of the start of d.buf. func (d *decodeBuffer) injectSyntacticErrorWithPosition(err error, pos int) error { … } func (d *decodeBuffer) previousOffsetStart() int64 { … } func (d *decodeBuffer) previousOffsetEnd() int64 { … } func (d *decodeBuffer) previousBuffer() []byte { … } func (d *decodeBuffer) unreadBuffer() []byte { … } // PeekKind retrieves the next token kind, but does not advance the read offset. // It returns 0 if there are no more tokens. func (d *Decoder) PeekKind() Kind { … } // SkipValue is semantically equivalent to calling ReadValue and discarding // the result except that memory is not wasted trying to hold the entire result. func (d *Decoder) SkipValue() error { … } // ReadToken reads the next Token, advancing the read offset. // The returned token is only valid until the next Peek, Read, or Skip call. // It returns io.EOF if there are no more tokens. func (d *Decoder) ReadToken() (Token, error) { … } type valueFlags … const _ … const stringNonVerbatim … const stringNonCanonical … func (f *valueFlags) set(f2 valueFlags) { … } func (f valueFlags) isVerbatim() bool { … } func (f valueFlags) isCanonical() bool { … } // ReadValue returns the next raw JSON value, advancing the read offset. // The value is stripped of any leading or trailing whitespace. // The returned value is only valid until the next Peek, Read, or Skip call and // may not be mutated while the Decoder remains in use. // If the decoder is currently at the end token for an object or array, // then it reports a SyntacticError and the internal state remains unchanged. // It returns io.EOF if there are no more values. func (d *Decoder) ReadValue() (RawValue, error) { … } func (d *Decoder) readValue(flags *valueFlags) (RawValue, error) { … } // checkEOF verifies that the input has no more data. func (d *Decoder) checkEOF() error { … } // consumeWhitespace consumes all whitespace starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the last whitespace. // If it returns nil, there is guaranteed to at least be one unread byte. // // The following pattern is common in this implementation: // // pos += consumeWhitespace(d.buf[pos:]) // if d.needMore(pos) { // if pos, err = d.consumeWhitespace(pos); err != nil { // return ... // } // } // // It is difficult to simplify this without sacrificing performance since // consumeWhitespace must be inlined. The body of the if statement is // executed only in rare situations where we need to fetch more data. // Since fetching may return an error, we also need to check the error. func (d *Decoder) consumeWhitespace(pos int) (newPos int, err error) { … } // consumeValue consumes a single JSON value starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the value. func (d *Decoder) consumeValue(flags *valueFlags, pos int) (newPos int, err error) { … } // consumeLiteral consumes a single JSON literal starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the literal. func (d *Decoder) consumeLiteral(pos int, lit string) (newPos int, err error) { … } // consumeString consumes a single JSON string starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the string. func (d *Decoder) consumeString(flags *valueFlags, pos int) (newPos int, err error) { … } // consumeNumber consumes a single JSON number starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the number. func (d *Decoder) consumeNumber(pos int) (newPos int, err error) { … } // consumeObject consumes a single JSON object starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the object. func (d *Decoder) consumeObject(flags *valueFlags, pos int) (newPos int, err error) { … } // consumeArray consumes a single JSON array starting at d.buf[pos:]. // It returns the new position in d.buf immediately after the array. func (d *Decoder) consumeArray(flags *valueFlags, pos int) (newPos int, err error) { … } // InputOffset returns the current input byte offset. It gives the location // of the next byte immediately after the most recently returned token or value. // The number of bytes actually read from the underlying io.Reader may be more // than this offset due to internal buffering effects. func (d *Decoder) InputOffset() int64 { … } // UnreadBuffer returns the data remaining in the unread buffer, // which may contain zero or more bytes. // The returned buffer must not be mutated while Decoder continues to be used. // The buffer contents are valid until the next Peek, Read, or Skip call. func (d *Decoder) UnreadBuffer() []byte { … } // StackDepth returns the depth of the state machine for read JSON data. // Each level on the stack represents a nested JSON object or array. // It is incremented whenever an ObjectStart or ArrayStart token is encountered // and decremented whenever an ObjectEnd or ArrayEnd token is encountered. // The depth is zero-indexed, where zero represents the top-level JSON value. func (d *Decoder) StackDepth() int { … } // StackIndex returns information about the specified stack level. // It must be a number between 0 and StackDepth, inclusive. // For each level, it reports the kind: // // - 0 for a level of zero, // - '{' for a level representing a JSON object, and // - '[' for a level representing a JSON array. // // It also reports the length of that JSON object or array. // Each name and value in a JSON object is counted separately, // so the effective number of members would be half the length. // A complete JSON object must have an even length. func (d *Decoder) StackIndex(i int) (Kind, int) { … } // StackPointer returns a JSON Pointer (RFC 6901) to the most recently read value. // Object names are only present if AllowDuplicateNames is false, otherwise // object members are represented using their index within the object. func (d *Decoder) StackPointer() string { … } // consumeWhitespace consumes leading JSON whitespace per RFC 7159, section 2. func consumeWhitespace(b []byte) (n int) { … } // consumeNull consumes the next JSON null literal per RFC 7159, section 3. // It returns 0 if it is invalid, in which case consumeLiteral should be used. func consumeNull(b []byte) int { … } // consumeFalse consumes the next JSON false literal per RFC 7159, section 3. // It returns 0 if it is invalid, in which case consumeLiteral should be used. func consumeFalse(b []byte) int { … } // consumeTrue consumes the next JSON true literal per RFC 7159, section 3. // It returns 0 if it is invalid, in which case consumeLiteral should be used. func consumeTrue(b []byte) int { … } // consumeLiteral consumes the next JSON literal per RFC 7159, section 3. // If the input appears truncated, it returns io.ErrUnexpectedEOF. func consumeLiteral(b []byte, lit string) (n int, err error) { … } // consumeSimpleString consumes the next JSON string per RFC 7159, section 7 // but is limited to the grammar for an ASCII string without escape sequences. // It returns 0 if it is invalid or more complicated than a simple string, // in which case consumeString should be called. func consumeSimpleString(b []byte) (n int) { … } // consumeString consumes the next JSON string per RFC 7159, section 7. // If validateUTF8 is false, then this allows the presence of invalid UTF-8 // characters within the string itself. // It reports the number of bytes consumed and whether an error was encountered. // If the input appears truncated, it returns io.ErrUnexpectedEOF. func consumeString(flags *valueFlags, b []byte, validateUTF8 bool) (n int, err error) { … } // consumeStringResumable is identical to consumeString but supports resuming // from a previous call that returned io.ErrUnexpectedEOF. func consumeStringResumable(flags *valueFlags, b []byte, resumeOffset int, validateUTF8 bool) (n int, err error) { … } // hasEscapeSequencePrefix reports whether b is possibly // the truncated prefix of a \uFFFF escape sequence. func hasEscapeSequencePrefix(b []byte) bool { … } // unescapeString appends the unescaped form of a JSON string in src to dst. // Any invalid UTF-8 within the string will be replaced with utf8.RuneError. // The input must be an entire JSON string with no surrounding whitespace. func unescapeString(dst, src []byte) (v []byte, ok bool) { … } // unescapeStringMayCopy returns the unescaped form of b. // If there are no escaped characters, the output is simply a subslice of // the input with the surrounding quotes removed. // Otherwise, a new buffer is allocated for the output. func unescapeStringMayCopy(b []byte, isVerbatim bool) []byte { … } // consumeSimpleNumber consumes the next JSON number per RFC 7159, section 6 // but is limited to the grammar for a positive integer. // It returns 0 if it is invalid or more complicated than a simple integer, // in which case consumeNumber should be called. func consumeSimpleNumber(b []byte) (n int) { … } type consumeNumberState … const consumeNumberInit … const beforeIntegerDigits … const withinIntegerDigits … const beforeFractionalDigits … const withinFractionalDigits … const beforeExponentDigits … const withinExponentDigits … // consumeNumber consumes the next JSON number per RFC 7159, section 6. // It reports the number of bytes consumed and whether an error was encountered. // If the input appears truncated, it returns io.ErrUnexpectedEOF. // // Note that JSON numbers are not self-terminating. // If the entire input is consumed, then the caller needs to consider whether // there may be subsequent unread data that may still be part of this number. func consumeNumber(b []byte) (n int, err error) { … } // consumeNumberResumable is identical to consumeNumber but supports resuming // from a previous call that returned io.ErrUnexpectedEOF. func consumeNumberResumable(b []byte, resumeOffset int, state consumeNumberState) (n int, _ consumeNumberState, err error) { … } // parseHexUint16 is similar to strconv.ParseUint, // but operates directly on []byte and is optimized for base-16. // See https://go.dev/issue/42429. func parseHexUint16(b []byte) (v uint16, ok bool) { … } // parseDecUint is similar to strconv.ParseUint, // but operates directly on []byte and is optimized for base-10. // If the number is syntactically valid but overflows uint64, // then it returns (math.MaxUint64, false). // See https://go.dev/issue/42429. func parseDecUint(b []byte) (v uint64, ok bool) { … } // parseFloat parses a floating point number according to the Go float grammar. // Note that the JSON number grammar is a strict subset. // // If the number overflows the finite representation of a float, // then we return MaxFloat since any finite value will always be infinitely // more accurate at representing another finite value than an infinite value. func parseFloat(b []byte, bits int) (v float64, ok bool) { … }