123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- // Copyright 2010 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package json
- import (
- "bytes"
- "errors"
- "io"
- )
- // A Decoder reads and decodes JSON objects from an input stream.
- type Decoder struct {
- r io.Reader
- buf []byte
- d decodeState
- scanp int // start of unread data in buf
- scan scanner
- err error
- tokenState int
- tokenStack []int
- }
- // NewDecoder returns a new decoder that reads from r.
- //
- // The decoder introduces its own buffering and may
- // read data from r beyond the JSON values requested.
- func NewDecoder(r io.Reader) *Decoder {
- return &Decoder{r: r}
- }
- // UseNumber causes the Decoder to unmarshal a number into an interface{} as a
- // Number instead of as a float64.
- func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
- // Decode reads the next JSON-encoded value from its
- // input and stores it in the value pointed to by v.
- //
- // See the documentation for Unmarshal for details about
- // the conversion of JSON into a Go value.
- func (dec *Decoder) Decode(v interface{}) error {
- if dec.err != nil {
- return dec.err
- }
- if err := dec.tokenPrepareForDecode(); err != nil {
- return err
- }
- if !dec.tokenValueAllowed() {
- return &SyntaxError{msg: "not at beginning of value"}
- }
- // Read whole value into buffer.
- n, err := dec.readValue()
- if err != nil {
- return err
- }
- dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
- dec.scanp += n
- // Don't save err from unmarshal into dec.err:
- // the connection is still usable since we read a complete JSON
- // object from it before the error happened.
- err = dec.d.unmarshal(v)
- // fixup token streaming state
- dec.tokenValueEnd()
- return err
- }
- // Buffered returns a reader of the data remaining in the Decoder's
- // buffer. The reader is valid until the next call to Decode.
- func (dec *Decoder) Buffered() io.Reader {
- return bytes.NewReader(dec.buf[dec.scanp:])
- }
- // readValue reads a JSON value into dec.buf.
- // It returns the length of the encoding.
- func (dec *Decoder) readValue() (int, error) {
- dec.scan.reset()
- scanp := dec.scanp
- var err error
- Input:
- for {
- // Look in the buffer for a new value.
- for i, c := range dec.buf[scanp:] {
- dec.scan.bytes++
- v := dec.scan.step(&dec.scan, c)
- if v == scanEnd {
- scanp += i
- break Input
- }
- // scanEnd is delayed one byte.
- // We might block trying to get that byte from src,
- // so instead invent a space byte.
- if (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {
- scanp += i + 1
- break Input
- }
- if v == scanError {
- dec.err = dec.scan.err
- return 0, dec.scan.err
- }
- }
- scanp = len(dec.buf)
- // Did the last read have an error?
- // Delayed until now to allow buffer scan.
- if err != nil {
- if err == io.EOF {
- if dec.scan.step(&dec.scan, ' ') == scanEnd {
- break Input
- }
- if nonSpace(dec.buf) {
- err = io.ErrUnexpectedEOF
- }
- }
- dec.err = err
- return 0, err
- }
- n := scanp - dec.scanp
- err = dec.refill()
- scanp = dec.scanp + n
- }
- return scanp - dec.scanp, nil
- }
- func (dec *Decoder) refill() error {
- // Make room to read more into the buffer.
- // First slide down data already consumed.
- if dec.scanp > 0 {
- n := copy(dec.buf, dec.buf[dec.scanp:])
- dec.buf = dec.buf[:n]
- dec.scanp = 0
- }
- // Grow buffer if not large enough.
- const minRead = 512
- if cap(dec.buf)-len(dec.buf) < minRead {
- newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
- copy(newBuf, dec.buf)
- dec.buf = newBuf
- }
- // Read. Delay error for next iteration (after scan).
- n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
- dec.buf = dec.buf[0 : len(dec.buf)+n]
- return err
- }
- func nonSpace(b []byte) bool {
- for _, c := range b {
- if !isSpace(c) {
- return true
- }
- }
- return false
- }
- // An Encoder writes JSON objects to an output stream.
- type Encoder struct {
- w io.Writer
- err error
- }
- // NewEncoder returns a new encoder that writes to w.
- func NewEncoder(w io.Writer) *Encoder {
- return &Encoder{w: w}
- }
- // Encode writes the JSON encoding of v to the stream,
- // followed by a newline character.
- //
- // See the documentation for Marshal for details about the
- // conversion of Go values to JSON.
- func (enc *Encoder) Encode(v interface{}) error {
- if enc.err != nil {
- return enc.err
- }
- e := newEncodeState()
- err := e.marshal(v)
- if err != nil {
- return err
- }
- // Terminate each value with a newline.
- // This makes the output look a little nicer
- // when debugging, and some kind of space
- // is required if the encoded value was a number,
- // so that the reader knows there aren't more
- // digits coming.
- e.WriteByte('\n')
- if _, err = enc.w.Write(e.Bytes()); err != nil {
- enc.err = err
- }
- encodeStatePool.Put(e)
- return err
- }
- // RawMessage is a raw encoded JSON object.
- // It implements Marshaler and Unmarshaler and can
- // be used to delay JSON decoding or precompute a JSON encoding.
- type RawMessage []byte
- // MarshalJSON returns *m as the JSON encoding of m.
- func (m *RawMessage) MarshalJSON() ([]byte, error) {
- return *m, nil
- }
- // UnmarshalJSON sets *m to a copy of data.
- func (m *RawMessage) UnmarshalJSON(data []byte) error {
- if m == nil {
- return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
- }
- *m = append((*m)[0:0], data...)
- return nil
- }
- var _ Marshaler = (*RawMessage)(nil)
- var _ Unmarshaler = (*RawMessage)(nil)
- // A Token holds a value of one of these types:
- //
- // Delim, for the four JSON delimiters [ ] { }
- // bool, for JSON booleans
- // float64, for JSON numbers
- // Number, for JSON numbers
- // string, for JSON string literals
- // nil, for JSON null
- //
- type Token interface{}
- const (
- tokenTopValue = iota
- tokenArrayStart
- tokenArrayValue
- tokenArrayComma
- tokenObjectStart
- tokenObjectKey
- tokenObjectColon
- tokenObjectValue
- tokenObjectComma
- )
- // advance tokenstate from a separator state to a value state
- func (dec *Decoder) tokenPrepareForDecode() error {
- // Note: Not calling peek before switch, to avoid
- // putting peek into the standard Decode path.
- // peek is only called when using the Token API.
- switch dec.tokenState {
- case tokenArrayComma:
- c, err := dec.peek()
- if err != nil {
- return err
- }
- if c != ',' {
- return &SyntaxError{"expected comma after array element", 0}
- }
- dec.scanp++
- dec.tokenState = tokenArrayValue
- case tokenObjectColon:
- c, err := dec.peek()
- if err != nil {
- return err
- }
- if c != ':' {
- return &SyntaxError{"expected colon after object key", 0}
- }
- dec.scanp++
- dec.tokenState = tokenObjectValue
- }
- return nil
- }
- func (dec *Decoder) tokenValueAllowed() bool {
- switch dec.tokenState {
- case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
- return true
- }
- return false
- }
- func (dec *Decoder) tokenValueEnd() {
- switch dec.tokenState {
- case tokenArrayStart, tokenArrayValue:
- dec.tokenState = tokenArrayComma
- case tokenObjectValue:
- dec.tokenState = tokenObjectComma
- }
- }
- // A Delim is a JSON array or object delimiter, one of [ ] { or }.
- type Delim rune
- func (d Delim) String() string {
- return string(d)
- }
- // Token returns the next JSON token in the input stream.
- // At the end of the input stream, Token returns nil, io.EOF.
- //
- // Token guarantees that the delimiters [ ] { } it returns are
- // properly nested and matched: if Token encounters an unexpected
- // delimiter in the input, it will return an error.
- //
- // The input stream consists of basic JSON values—bool, string,
- // number, and null—along with delimiters [ ] { } of type Delim
- // to mark the start and end of arrays and objects.
- // Commas and colons are elided.
- func (dec *Decoder) Token() (Token, error) {
- for {
- c, err := dec.peek()
- if err != nil {
- return nil, err
- }
- switch c {
- case '[':
- if !dec.tokenValueAllowed() {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenStack = append(dec.tokenStack, dec.tokenState)
- dec.tokenState = tokenArrayStart
- return Delim('['), nil
- case ']':
- if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
- dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
- dec.tokenValueEnd()
- return Delim(']'), nil
- case '{':
- if !dec.tokenValueAllowed() {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenStack = append(dec.tokenStack, dec.tokenState)
- dec.tokenState = tokenObjectStart
- return Delim('{'), nil
- case '}':
- if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
- dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
- dec.tokenValueEnd()
- return Delim('}'), nil
- case ':':
- if dec.tokenState != tokenObjectColon {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenState = tokenObjectValue
- continue
- case ',':
- if dec.tokenState == tokenArrayComma {
- dec.scanp++
- dec.tokenState = tokenArrayValue
- continue
- }
- if dec.tokenState == tokenObjectComma {
- dec.scanp++
- dec.tokenState = tokenObjectKey
- continue
- }
- return dec.tokenError(c)
- case '"':
- if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
- var x string
- old := dec.tokenState
- dec.tokenState = tokenTopValue
- err := dec.Decode(&x)
- dec.tokenState = old
- if err != nil {
- clearOffset(err)
- return nil, err
- }
- dec.tokenState = tokenObjectColon
- return x, nil
- }
- fallthrough
- default:
- if !dec.tokenValueAllowed() {
- return dec.tokenError(c)
- }
- var x interface{}
- if err := dec.Decode(&x); err != nil {
- clearOffset(err)
- return nil, err
- }
- return x, nil
- }
- }
- }
- func clearOffset(err error) {
- if s, ok := err.(*SyntaxError); ok {
- s.Offset = 0
- }
- }
- func (dec *Decoder) tokenError(c byte) (Token, error) {
- var context string
- switch dec.tokenState {
- case tokenTopValue:
- context = " looking for beginning of value"
- case tokenArrayStart, tokenArrayValue, tokenObjectValue:
- context = " looking for beginning of value"
- case tokenArrayComma:
- context = " after array element"
- case tokenObjectKey:
- context = " looking for beginning of object key string"
- case tokenObjectColon:
- context = " after object key"
- case tokenObjectComma:
- context = " after object key:value pair"
- }
- return nil, &SyntaxError{"invalid character " + quoteChar(c) + " " + context, 0}
- }
- // More reports whether there is another element in the
- // current array or object being parsed.
- func (dec *Decoder) More() bool {
- c, err := dec.peek()
- return err == nil && c != ']' && c != '}'
- }
- func (dec *Decoder) peek() (byte, error) {
- var err error
- for {
- for i := dec.scanp; i < len(dec.buf); i++ {
- c := dec.buf[i]
- if isSpace(c) {
- continue
- }
- dec.scanp = i
- return c, nil
- }
- // buffer has been scanned, now report any error
- if err != nil {
- return 0, err
- }
- err = dec.refill()
- }
- }
- /*
- TODO
- // EncodeToken writes the given JSON token to the stream.
- // It returns an error if the delimiters [ ] { } are not properly used.
- //
- // EncodeToken does not call Flush, because usually it is part of
- // a larger operation such as Encode, and those will call Flush when finished.
- // Callers that create an Encoder and then invoke EncodeToken directly,
- // without using Encode, need to call Flush when finished to ensure that
- // the JSON is written to the underlying writer.
- func (e *Encoder) EncodeToken(t Token) error {
- ...
- }
- */
|