| | |
| | |
| | |
| |
|
| | |
| |
|
| | package jsontext |
| |
|
| | import ( |
| | "bytes" |
| | "errors" |
| | "io" |
| |
|
| | "encoding/json/internal/jsonflags" |
| | "encoding/json/internal/jsonopts" |
| | "encoding/json/internal/jsonwire" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type Decoder struct { |
| | s decoderState |
| | } |
| |
|
| | |
| | |
| | type decoderState struct { |
| | state |
| | decodeBuffer |
| | jsonopts.Struct |
| |
|
| | StringCache *[256]string |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | type decodeBuffer struct { |
| | peekPos int |
| | peekErr error |
| |
|
| | buf []byte |
| | prevStart int |
| | prevEnd int |
| |
|
| | |
| | |
| | baseOffset int64 |
| |
|
| | rd io.Reader |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func NewDecoder(r io.Reader, opts ...Options) *Decoder { |
| | d := new(Decoder) |
| | d.Reset(r, opts...) |
| | return d |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func (d *Decoder) Reset(r io.Reader, opts ...Options) { |
| | switch { |
| | case d == nil: |
| | panic("jsontext: invalid nil Decoder") |
| | case r == nil: |
| | panic("jsontext: invalid nil io.Reader") |
| | case d.s.Flags.Get(jsonflags.WithinArshalCall): |
| | panic("jsontext: cannot reset Decoder passed to json.UnmarshalerFrom") |
| | } |
| | |
| | b := d.s.buf[:0] |
| | if _, ok := d.s.rd.(*bytes.Buffer); ok { |
| | b = nil |
| | } |
| | d.s.reset(b, r, opts...) |
| | } |
| |
|
| | func (d *decoderState) reset(b []byte, r io.Reader, opts ...Options) { |
| | d.state.reset() |
| | d.decodeBuffer = decodeBuffer{buf: b, rd: r} |
| | opts2 := jsonopts.Struct{} |
| | opts2.Join(opts...) |
| | d.Struct = opts2 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | func (d *Decoder) Options() Options { |
| | return &d.s.Struct |
| | } |
| |
|
| | var errBufferWriteAfterNext = errors.New("invalid bytes.Buffer.Write call after calling bytes.Buffer.Next") |
| |
|
| | |
| | |
| | func (d *decoderState) fetch() error { |
| | if d.rd == nil { |
| | return io.ErrUnexpectedEOF |
| | } |
| |
|
| | |
| | d.Names.copyQuotedBuffer(d.buf) |
| |
|
| | |
| | if bb, ok := d.rd.(*bytes.Buffer); ok { |
| | switch { |
| | case bb.Len() == 0: |
| | return io.ErrUnexpectedEOF |
| | case len(d.buf) == 0: |
| | d.buf = bb.Next(bb.Len()) |
| | return nil |
| | default: |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | return &ioError{action: "read", err: errBufferWriteAfterNext} |
| | } |
| | } |
| |
|
| | |
| | if cap(d.buf) == 0 { |
| | d.buf = make([]byte, 0, 64) |
| | } |
| |
|
| | |
| | const maxBufferSize = 4 << 10 |
| | const growthSizeFactor = 2 |
| | const growthRateFactor = 2 |
| | |
| | grow := cap(d.buf) <= maxBufferSize/growthSizeFactor |
| | |
| | |
| | grow = grow && int64(cap(d.buf)) < d.previousOffsetEnd()/growthRateFactor |
| | |
| | |
| | |
| | |
| | grow = grow || (d.prevStart == 0 && len(d.buf) >= 3*cap(d.buf)/4) |
| |
|
| | if grow { |
| | |
| | |
| | buf := make([]byte, 0, cap(d.buf)*growthSizeFactor) |
| | d.buf = append(buf, d.buf[d.prevStart:]...) |
| | } else { |
| | |
| | n := copy(d.buf[:cap(d.buf)], d.buf[d.prevStart:]) |
| | d.buf = d.buf[:n] |
| | } |
| | d.baseOffset += int64(d.prevStart) |
| | d.prevEnd -= d.prevStart |
| | d.prevStart = 0 |
| |
|
| | |
| | for { |
| | n, err := d.rd.Read(d.buf[len(d.buf):cap(d.buf)]) |
| | switch { |
| | case n > 0: |
| | d.buf = d.buf[:len(d.buf)+n] |
| | return nil |
| | case err == io.EOF: |
| | return io.ErrUnexpectedEOF |
| | case err != nil: |
| | return &ioError{action: "read", err: err} |
| | default: |
| | continue |
| | } |
| | } |
| | } |
| |
|
| | const invalidateBufferByte = '#' |
| |
|
| | |
| | |
| | |
| | |
| | func (d *decodeBuffer) invalidatePreviousRead() { |
| | |
| | |
| | isBytesBuffer := func(r io.Reader) bool { |
| | _, ok := r.(*bytes.Buffer) |
| | return ok |
| | } |
| | if d.rd != nil && !isBytesBuffer(d.rd) && d.prevStart < d.prevEnd && uint(d.prevStart) < uint(len(d.buf)) { |
| | d.buf[d.prevStart] = invalidateBufferByte |
| | d.prevStart = d.prevEnd |
| | } |
| | } |
| |
|
| | |
| | func (d *decodeBuffer) needMore(pos int) bool { |
| | |
| | return pos == len(d.buf) |
| | } |
| |
|
| | func (d *decodeBuffer) offsetAt(pos int) int64 { return d.baseOffset + int64(pos) } |
| | func (d *decodeBuffer) previousOffsetStart() int64 { return d.baseOffset + int64(d.prevStart) } |
| | func (d *decodeBuffer) previousOffsetEnd() int64 { return d.baseOffset + int64(d.prevEnd) } |
| | func (d *decodeBuffer) previousBuffer() []byte { return d.buf[d.prevStart:d.prevEnd] } |
| | func (d *decodeBuffer) unreadBuffer() []byte { return d.buf[d.prevEnd:len(d.buf)] } |
| |
|
| | |
| | |
| | |
| | |
| | func (d *decodeBuffer) PreviousTokenOrValue() []byte { |
| | b := d.previousBuffer() |
| | |
| | if d.peekPos > 0 || len(b) > 0 && b[0] == invalidateBufferByte { |
| | return nil |
| | } |
| | |
| | |
| | if len(b) == 0 { |
| | b = d.buf[:d.prevEnd] |
| | for _, tok := range []string{"null", "false", "true", "{", "}", "[", "]"} { |
| | if len(b) >= len(tok) && string(b[len(b)-len(tok):]) == tok { |
| | return b[len(b)-len(tok):] |
| | } |
| | } |
| | } |
| | return b |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func (d *Decoder) PeekKind() Kind { |
| | return d.s.PeekKind() |
| | } |
| | func (d *decoderState) PeekKind() Kind { |
| | |
| | if d.peekPos > 0 { |
| | return Kind(d.buf[d.peekPos]).normalize() |
| | } |
| |
|
| | var err error |
| | d.invalidatePreviousRead() |
| | pos := d.prevEnd |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 { |
| | err = io.EOF |
| | } |
| | d.peekPos, d.peekErr = -1, wrapSyntacticError(d, err, pos, 0) |
| | return invalidKind |
| | } |
| | } |
| |
|
| | |
| | var delim byte |
| | if c := d.buf[pos]; c == ':' || c == ',' { |
| | delim = c |
| | pos += 1 |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | err = wrapSyntacticError(d, err, pos, 0) |
| | d.peekPos, d.peekErr = -1, d.checkDelimBeforeIOError(delim, err) |
| | return invalidKind |
| | } |
| | } |
| | } |
| | next := Kind(d.buf[pos]).normalize() |
| | if d.Tokens.needDelim(next) != delim { |
| | d.peekPos, d.peekErr = -1, d.checkDelim(delim, next) |
| | return invalidKind |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | d.peekPos, d.peekErr = pos, nil |
| | return next |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) checkDelimBeforeIOError(delim byte, err error) error { |
| | |
| | |
| | |
| | |
| | |
| | const next = Kind('"') |
| | if d.Tokens.needDelim(next) != delim { |
| | err = d.checkDelim(delim, next) |
| | } |
| | return err |
| | } |
| |
|
| | |
| | |
| | |
| | func (d *decoderState) CountNextDelimWhitespace() int { |
| | d.PeekKind() |
| | return len(d.unreadBuffer()) - len(bytes.TrimLeft(d.unreadBuffer(), ",: \n\r\t")) |
| | } |
| |
|
| | |
| | func (d *decoderState) checkDelim(delim byte, next Kind) error { |
| | where := "at start of value" |
| | switch d.Tokens.needDelim(next) { |
| | case delim: |
| | return nil |
| | case ':': |
| | where = "after object name (expecting ':')" |
| | case ',': |
| | if d.Tokens.Last.isObject() { |
| | where = "after object value (expecting ',' or '}')" |
| | } else { |
| | where = "after array element (expecting ',' or ']')" |
| | } |
| | } |
| | pos := d.prevEnd |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | err := jsonwire.NewInvalidCharacterError(d.buf[pos:], where) |
| | return wrapSyntacticError(d, err, pos, 0) |
| | } |
| |
|
| | |
| | |
| | func (d *Decoder) SkipValue() error { |
| | return d.s.SkipValue() |
| | } |
| | func (d *decoderState) SkipValue() error { |
| | switch d.PeekKind() { |
| | case '{', '[': |
| | |
| | |
| | depth := d.Tokens.Depth() |
| | for { |
| | if _, err := d.ReadToken(); err != nil { |
| | return err |
| | } |
| | if depth >= d.Tokens.Depth() { |
| | return nil |
| | } |
| | } |
| | default: |
| | |
| | |
| | var flags jsonwire.ValueFlags |
| | if _, err := d.ReadValue(&flags); err != nil { |
| | return err |
| | } |
| | return nil |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) SkipValueRemainder() error { |
| | if d.Tokens.Depth()-1 > 0 && d.Tokens.Last.Length() == 0 { |
| | for n := d.Tokens.Depth(); d.Tokens.Depth() >= n; { |
| | if _, err := d.ReadToken(); err != nil { |
| | return err |
| | } |
| | } |
| | } |
| | return nil |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) SkipUntil(depth int, length int64) error { |
| | for d.Tokens.Depth() > depth || (d.Tokens.Depth() == depth && d.Tokens.Last.Length() < length) { |
| | if _, err := d.ReadToken(); err != nil { |
| | return err |
| | } |
| | } |
| | return nil |
| | } |
| |
|
| | |
| | |
| | |
| | func (d *Decoder) ReadToken() (Token, error) { |
| | return d.s.ReadToken() |
| | } |
| | func (d *decoderState) ReadToken() (Token, error) { |
| | |
| | var err error |
| | var next Kind |
| | pos := d.peekPos |
| | if pos != 0 { |
| | |
| | if d.peekErr != nil { |
| | err := d.peekErr |
| | d.peekPos, d.peekErr = 0, nil |
| | return Token{}, err |
| | } |
| | next = Kind(d.buf[pos]).normalize() |
| | d.peekPos = 0 |
| | } else { |
| | d.invalidatePreviousRead() |
| | pos = d.prevEnd |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 { |
| | err = io.EOF |
| | } |
| | return Token{}, wrapSyntacticError(d, err, pos, 0) |
| | } |
| | } |
| |
|
| | |
| | var delim byte |
| | if c := d.buf[pos]; c == ':' || c == ',' { |
| | delim = c |
| | pos += 1 |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | err = wrapSyntacticError(d, err, pos, 0) |
| | return Token{}, d.checkDelimBeforeIOError(delim, err) |
| | } |
| | } |
| | } |
| | next = Kind(d.buf[pos]).normalize() |
| | if d.Tokens.needDelim(next) != delim { |
| | return Token{}, d.checkDelim(delim, next) |
| | } |
| | } |
| |
|
| | |
| | var n int |
| | switch next { |
| | case 'n': |
| | if jsonwire.ConsumeNull(d.buf[pos:]) == 0 { |
| | pos, err = d.consumeLiteral(pos, "null") |
| | if err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | } else { |
| | pos += len("null") |
| | } |
| | if err = d.Tokens.appendLiteral(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos-len("null"), +1) |
| | } |
| | d.prevStart, d.prevEnd = pos, pos |
| | return Null, nil |
| |
|
| | case 'f': |
| | if jsonwire.ConsumeFalse(d.buf[pos:]) == 0 { |
| | pos, err = d.consumeLiteral(pos, "false") |
| | if err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | } else { |
| | pos += len("false") |
| | } |
| | if err = d.Tokens.appendLiteral(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos-len("false"), +1) |
| | } |
| | d.prevStart, d.prevEnd = pos, pos |
| | return False, nil |
| |
|
| | case 't': |
| | if jsonwire.ConsumeTrue(d.buf[pos:]) == 0 { |
| | pos, err = d.consumeLiteral(pos, "true") |
| | if err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | } else { |
| | pos += len("true") |
| | } |
| | if err = d.Tokens.appendLiteral(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos-len("true"), +1) |
| | } |
| | d.prevStart, d.prevEnd = pos, pos |
| | return True, nil |
| |
|
| | case '"': |
| | var flags jsonwire.ValueFlags |
| | if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 { |
| | oldAbsPos := d.baseOffset + int64(pos) |
| | pos, err = d.consumeString(&flags, pos) |
| | newAbsPos := d.baseOffset + int64(pos) |
| | n = int(newAbsPos - oldAbsPos) |
| | if err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | } else { |
| | pos += n |
| | } |
| | if d.Tokens.Last.NeedObjectName() { |
| | if !d.Flags.Get(jsonflags.AllowDuplicateNames) { |
| | if !d.Tokens.Last.isValidNamespace() { |
| | return Token{}, wrapSyntacticError(d, errInvalidNamespace, pos-n, +1) |
| | } |
| | if d.Tokens.Last.isActiveNamespace() && !d.Namespaces.Last().insertQuoted(d.buf[pos-n:pos], flags.IsVerbatim()) { |
| | err = wrapWithObjectName(ErrDuplicateName, d.buf[pos-n:pos]) |
| | return Token{}, wrapSyntacticError(d, err, pos-n, +1) |
| | } |
| | } |
| | d.Names.ReplaceLastQuotedOffset(pos - n) |
| | } |
| | if err = d.Tokens.appendString(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos-n, +1) |
| | } |
| | d.prevStart, d.prevEnd = pos-n, pos |
| | return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil |
| |
|
| | case '0': |
| | |
| | |
| | if n = jsonwire.ConsumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { |
| | oldAbsPos := d.baseOffset + int64(pos) |
| | pos, err = d.consumeNumber(pos) |
| | newAbsPos := d.baseOffset + int64(pos) |
| | n = int(newAbsPos - oldAbsPos) |
| | if err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | } else { |
| | pos += n |
| | } |
| | if err = d.Tokens.appendNumber(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos-n, +1) |
| | } |
| | d.prevStart, d.prevEnd = pos-n, pos |
| | return Token{raw: &d.decodeBuffer, num: uint64(d.previousOffsetStart())}, nil |
| |
|
| | case '{': |
| | if err = d.Tokens.pushObject(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | d.Names.push() |
| | if !d.Flags.Get(jsonflags.AllowDuplicateNames) { |
| | d.Namespaces.push() |
| | } |
| | pos += 1 |
| | d.prevStart, d.prevEnd = pos, pos |
| | return BeginObject, nil |
| |
|
| | case '}': |
| | if err = d.Tokens.popObject(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | d.Names.pop() |
| | if !d.Flags.Get(jsonflags.AllowDuplicateNames) { |
| | d.Namespaces.pop() |
| | } |
| | pos += 1 |
| | d.prevStart, d.prevEnd = pos, pos |
| | return EndObject, nil |
| |
|
| | case '[': |
| | if err = d.Tokens.pushArray(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | pos += 1 |
| | d.prevStart, d.prevEnd = pos, pos |
| | return BeginArray, nil |
| |
|
| | case ']': |
| | if err = d.Tokens.popArray(); err != nil { |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | pos += 1 |
| | d.prevStart, d.prevEnd = pos, pos |
| | return EndArray, nil |
| |
|
| | default: |
| | err = jsonwire.NewInvalidCharacterError(d.buf[pos:], "at start of value") |
| | return Token{}, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | func (d *Decoder) ReadValue() (Value, error) { |
| | var flags jsonwire.ValueFlags |
| | return d.s.ReadValue(&flags) |
| | } |
| | func (d *decoderState) ReadValue(flags *jsonwire.ValueFlags) (Value, error) { |
| | |
| | var err error |
| | var next Kind |
| | pos := d.peekPos |
| | if pos != 0 { |
| | |
| | if d.peekErr != nil { |
| | err := d.peekErr |
| | d.peekPos, d.peekErr = 0, nil |
| | return nil, err |
| | } |
| | next = Kind(d.buf[pos]).normalize() |
| | d.peekPos = 0 |
| | } else { |
| | d.invalidatePreviousRead() |
| | pos = d.prevEnd |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | if err == io.ErrUnexpectedEOF && d.Tokens.Depth() == 1 { |
| | err = io.EOF |
| | } |
| | return nil, wrapSyntacticError(d, err, pos, 0) |
| | } |
| | } |
| |
|
| | |
| | var delim byte |
| | if c := d.buf[pos]; c == ':' || c == ',' { |
| | delim = c |
| | pos += 1 |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | err = wrapSyntacticError(d, err, pos, 0) |
| | return nil, d.checkDelimBeforeIOError(delim, err) |
| | } |
| | } |
| | } |
| | next = Kind(d.buf[pos]).normalize() |
| | if d.Tokens.needDelim(next) != delim { |
| | return nil, d.checkDelim(delim, next) |
| | } |
| | } |
| |
|
| | |
| | oldAbsPos := d.baseOffset + int64(pos) |
| | pos, err = d.consumeValue(flags, pos, d.Tokens.Depth()) |
| | newAbsPos := d.baseOffset + int64(pos) |
| | n := int(newAbsPos - oldAbsPos) |
| | if err != nil { |
| | return nil, wrapSyntacticError(d, err, pos, +1) |
| | } |
| | switch next { |
| | case 'n', 't', 'f': |
| | err = d.Tokens.appendLiteral() |
| | case '"': |
| | if d.Tokens.Last.NeedObjectName() { |
| | if !d.Flags.Get(jsonflags.AllowDuplicateNames) { |
| | if !d.Tokens.Last.isValidNamespace() { |
| | err = errInvalidNamespace |
| | break |
| | } |
| | if d.Tokens.Last.isActiveNamespace() && !d.Namespaces.Last().insertQuoted(d.buf[pos-n:pos], flags.IsVerbatim()) { |
| | err = wrapWithObjectName(ErrDuplicateName, d.buf[pos-n:pos]) |
| | break |
| | } |
| | } |
| | d.Names.ReplaceLastQuotedOffset(pos - n) |
| | } |
| | err = d.Tokens.appendString() |
| | case '0': |
| | err = d.Tokens.appendNumber() |
| | case '{': |
| | if err = d.Tokens.pushObject(); err != nil { |
| | break |
| | } |
| | if err = d.Tokens.popObject(); err != nil { |
| | panic("BUG: popObject should never fail immediately after pushObject: " + err.Error()) |
| | } |
| | case '[': |
| | if err = d.Tokens.pushArray(); err != nil { |
| | break |
| | } |
| | if err = d.Tokens.popArray(); err != nil { |
| | panic("BUG: popArray should never fail immediately after pushArray: " + err.Error()) |
| | } |
| | } |
| | if err != nil { |
| | return nil, wrapSyntacticError(d, err, pos-n, +1) |
| | } |
| | d.prevEnd = pos |
| | d.prevStart = pos - n |
| | return d.buf[pos-n : pos : pos], nil |
| | } |
| |
|
| | |
| | |
| | |
| | func (d *decoderState) CheckNextValue(last bool) error { |
| | d.PeekKind() |
| | pos, err := d.peekPos, d.peekErr |
| | d.peekPos, d.peekErr = 0, nil |
| | if err != nil { |
| | return err |
| | } |
| |
|
| | var flags jsonwire.ValueFlags |
| | if pos, err := d.consumeValue(&flags, pos, d.Tokens.Depth()); err != nil { |
| | return wrapSyntacticError(d, err, pos, +1) |
| | } else if last { |
| | return d.checkEOF(pos) |
| | } |
| | return nil |
| | } |
| |
|
| | |
| | func (d *decoderState) AtEOF() bool { |
| | _, err := d.consumeWhitespace(d.prevEnd) |
| | return err == io.ErrUnexpectedEOF |
| | } |
| |
|
| | |
| | func (d *decoderState) CheckEOF() error { |
| | return d.checkEOF(d.prevEnd) |
| | } |
| | func (d *decoderState) checkEOF(pos int) error { |
| | switch pos, err := d.consumeWhitespace(pos); err { |
| | case nil: |
| | err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after top-level value") |
| | return wrapSyntacticError(d, err, pos, 0) |
| | case io.ErrUnexpectedEOF: |
| | return nil |
| | default: |
| | return err |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | func (d *decoderState) consumeWhitespace(pos int) (newPos int, err error) { |
| | for { |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | absPos := d.baseOffset + int64(pos) |
| | err = d.fetch() |
| | pos = int(absPos - d.baseOffset) |
| | if err != nil { |
| | return pos, err |
| | } |
| | continue |
| | } |
| | return pos, nil |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) consumeValue(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) { |
| | for { |
| | var n int |
| | var err error |
| | switch next := Kind(d.buf[pos]).normalize(); next { |
| | case 'n': |
| | if n = jsonwire.ConsumeNull(d.buf[pos:]); n == 0 { |
| | n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "null") |
| | } |
| | case 'f': |
| | if n = jsonwire.ConsumeFalse(d.buf[pos:]); n == 0 { |
| | n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "false") |
| | } |
| | case 't': |
| | if n = jsonwire.ConsumeTrue(d.buf[pos:]); n == 0 { |
| | n, err = jsonwire.ConsumeLiteral(d.buf[pos:], "true") |
| | } |
| | case '"': |
| | if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 { |
| | return d.consumeString(flags, pos) |
| | } |
| | case '0': |
| | |
| | |
| | if n = jsonwire.ConsumeSimpleNumber(d.buf[pos:]); n == 0 || d.needMore(pos+n) { |
| | return d.consumeNumber(pos) |
| | } |
| | case '{': |
| | return d.consumeObject(flags, pos, depth) |
| | case '[': |
| | return d.consumeArray(flags, pos, depth) |
| | default: |
| | if (d.Tokens.Last.isObject() && next == ']') || (d.Tokens.Last.isArray() && next == '}') { |
| | return pos, errMismatchDelim |
| | } |
| | return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "at start of value") |
| | } |
| | if err == io.ErrUnexpectedEOF { |
| | absPos := d.baseOffset + int64(pos) |
| | err = d.fetch() |
| | pos = int(absPos - d.baseOffset) |
| | if err != nil { |
| | return pos + n, err |
| | } |
| | continue |
| | } |
| | return pos + n, err |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) consumeLiteral(pos int, lit string) (newPos int, err error) { |
| | for { |
| | n, err := jsonwire.ConsumeLiteral(d.buf[pos:], lit) |
| | if err == io.ErrUnexpectedEOF { |
| | absPos := d.baseOffset + int64(pos) |
| | err = d.fetch() |
| | pos = int(absPos - d.baseOffset) |
| | if err != nil { |
| | return pos + n, err |
| | } |
| | continue |
| | } |
| | return pos + n, err |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) consumeString(flags *jsonwire.ValueFlags, pos int) (newPos int, err error) { |
| | var n int |
| | for { |
| | n, err = jsonwire.ConsumeStringResumable(flags, d.buf[pos:], n, !d.Flags.Get(jsonflags.AllowInvalidUTF8)) |
| | if err == io.ErrUnexpectedEOF { |
| | absPos := d.baseOffset + int64(pos) |
| | err = d.fetch() |
| | pos = int(absPos - d.baseOffset) |
| | if err != nil { |
| | return pos + n, err |
| | } |
| | continue |
| | } |
| | return pos + n, err |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) consumeNumber(pos int) (newPos int, err error) { |
| | var n int |
| | var state jsonwire.ConsumeNumberState |
| | for { |
| | n, state, err = jsonwire.ConsumeNumberResumable(d.buf[pos:], n, state) |
| | |
| | |
| | if err == io.ErrUnexpectedEOF || d.needMore(pos+n) { |
| | mayTerminate := err == nil |
| | absPos := d.baseOffset + int64(pos) |
| | err = d.fetch() |
| | pos = int(absPos - d.baseOffset) |
| | if err != nil { |
| | if mayTerminate && err == io.ErrUnexpectedEOF { |
| | return pos + n, nil |
| | } |
| | return pos, err |
| | } |
| | continue |
| | } |
| | return pos + n, err |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) consumeObject(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) { |
| | var n int |
| | var names *objectNamespace |
| | if !d.Flags.Get(jsonflags.AllowDuplicateNames) { |
| | d.Namespaces.push() |
| | defer d.Namespaces.pop() |
| | names = d.Namespaces.Last() |
| | } |
| |
|
| | |
| | if uint(pos) >= uint(len(d.buf)) || d.buf[pos] != '{' { |
| | panic("BUG: consumeObject must be called with a buffer that starts with '{'") |
| | } else if depth == maxNestingDepth+1 { |
| | return pos, errMaxDepth |
| | } |
| | pos++ |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, err |
| | } |
| | } |
| | if d.buf[pos] == '}' { |
| | pos++ |
| | return pos, nil |
| | } |
| |
|
| | depth++ |
| | for { |
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, err |
| | } |
| | } |
| | var flags2 jsonwire.ValueFlags |
| | if n = jsonwire.ConsumeSimpleString(d.buf[pos:]); n == 0 { |
| | oldAbsPos := d.baseOffset + int64(pos) |
| | pos, err = d.consumeString(&flags2, pos) |
| | newAbsPos := d.baseOffset + int64(pos) |
| | n = int(newAbsPos - oldAbsPos) |
| | flags.Join(flags2) |
| | if err != nil { |
| | return pos, err |
| | } |
| | } else { |
| | pos += n |
| | } |
| | quotedName := d.buf[pos-n : pos] |
| | if !d.Flags.Get(jsonflags.AllowDuplicateNames) && !names.insertQuoted(quotedName, flags2.IsVerbatim()) { |
| | return pos - n, wrapWithObjectName(ErrDuplicateName, quotedName) |
| | } |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, wrapWithObjectName(err, quotedName) |
| | } |
| | } |
| | if d.buf[pos] != ':' { |
| | err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after object name (expecting ':')") |
| | return pos, wrapWithObjectName(err, quotedName) |
| | } |
| | pos++ |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, wrapWithObjectName(err, quotedName) |
| | } |
| | } |
| | pos, err = d.consumeValue(flags, pos, depth) |
| | if err != nil { |
| | return pos, wrapWithObjectName(err, quotedName) |
| | } |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, err |
| | } |
| | } |
| | switch d.buf[pos] { |
| | case ',': |
| | pos++ |
| | continue |
| | case '}': |
| | pos++ |
| | return pos, nil |
| | default: |
| | return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "after object value (expecting ',' or '}')") |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | func (d *decoderState) consumeArray(flags *jsonwire.ValueFlags, pos, depth int) (newPos int, err error) { |
| | |
| | if uint(pos) >= uint(len(d.buf)) || d.buf[pos] != '[' { |
| | panic("BUG: consumeArray must be called with a buffer that starts with '['") |
| | } else if depth == maxNestingDepth+1 { |
| | return pos, errMaxDepth |
| | } |
| | pos++ |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, err |
| | } |
| | } |
| | if d.buf[pos] == ']' { |
| | pos++ |
| | return pos, nil |
| | } |
| |
|
| | var idx int64 |
| | depth++ |
| | for { |
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, err |
| | } |
| | } |
| | pos, err = d.consumeValue(flags, pos, depth) |
| | if err != nil { |
| | return pos, wrapWithArrayIndex(err, idx) |
| | } |
| |
|
| | |
| | pos += jsonwire.ConsumeWhitespace(d.buf[pos:]) |
| | if d.needMore(pos) { |
| | if pos, err = d.consumeWhitespace(pos); err != nil { |
| | return pos, err |
| | } |
| | } |
| | switch d.buf[pos] { |
| | case ',': |
| | pos++ |
| | idx++ |
| | continue |
| | case ']': |
| | pos++ |
| | return pos, nil |
| | default: |
| | return pos, jsonwire.NewInvalidCharacterError(d.buf[pos:], "after array element (expecting ',' or ']')") |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func (d *Decoder) InputOffset() int64 { |
| | return d.s.previousOffsetEnd() |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func (d *Decoder) UnreadBuffer() []byte { |
| | return d.s.unreadBuffer() |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func (d *Decoder) StackDepth() int { |
| | |
| | return d.s.Tokens.Depth() - 1 |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | func (d *Decoder) StackIndex(i int) (Kind, int64) { |
| | |
| | switch s := d.s.Tokens.index(i); { |
| | case i > 0 && s.isObject(): |
| | return '{', s.Length() |
| | case i > 0 && s.isArray(): |
| | return '[', s.Length() |
| | default: |
| | return 0, s.Length() |
| | } |
| | } |
| |
|
| | |
| | func (d *Decoder) StackPointer() Pointer { |
| | return Pointer(d.s.AppendStackPointer(nil, -1)) |
| | } |
| |
|
| | func (d *decoderState) AppendStackPointer(b []byte, where int) []byte { |
| | d.Names.copyQuotedBuffer(d.buf) |
| | return d.state.appendStackPointer(b, where) |
| | } |
| |
|