Go Home Page
The Go Programming Language

Source file src/pkg/json/stream.go

// 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"
    "io"
    "os"
)

// A Decoder reads and decodes JSON objects from an input stream.
type Decoder struct {
    r    io.Reader
    buf  []byte
    d    decodeState
    scan scanner
    err  os.Error
}

// NewDecoder returns a new decoder that reads from r.
func NewDecoder(r io.Reader) *Decoder {
    return &Decoder{r: r}
}

// Decode reads the next JSON-encoded value from the
// connection 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{}) os.Error {
    if dec.err != nil {
        return dec.err
    }

    n, err := dec.readValue()
    if err != nil {
        return err
    }

    // 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.
    dec.d.init(dec.buf[0:n])
    err = dec.d.unmarshal(v)

    // Slide rest of data down.
    rest := copy(dec.buf, dec.buf[n:])
    dec.buf = dec.buf[0:rest]

    return err
}

// readValue reads a JSON value into dec.buf.
// It returns the length of the encoding.
func (dec *Decoder) readValue() (int, os.Error) {
    dec.scan.reset()

    scanp := 0
    var err os.Error
Input:
    for {
        // Look in the buffer for a new value.
        for i, c := range dec.buf[scanp:] {
            v := dec.scan.step(&dec.scan, int(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 && 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 == os.EOF {
                if dec.scan.step(&dec.scan, ' ') == scanEnd {
                    break Input
                }
                if nonSpace(dec.buf) {
                    err = io.ErrUnexpectedEOF
                }
            }
            dec.err = err
            return 0, err
        }

        // Make room to read more into the buffer.
        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).
        var n int
        n, err = dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
        dec.buf = dec.buf[0 : len(dec.buf)+n]
    }
    return scanp, nil
}

func nonSpace(b []byte) bool {
    for _, c := range b {
        if !isSpace(int(c)) {
            return true
        }
    }
    return false
}

// An Encoder writes JSON objects to an output stream.
type Encoder struct {
    w   io.Writer
    e   encodeState
    err os.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 connection.
//
// See the documentation for Marshal for details about the
// conversion of Go values to JSON.
func (enc *Encoder) Encode(v interface{}) os.Error {
    if enc.err != nil {
        return enc.err
    }
    enc.e.Reset()
    err := enc.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.
    enc.e.WriteByte('\n')

    if _, err = enc.w.Write(enc.e.Bytes()); err != nil {
        enc.err = err
    }
    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, os.Error) {
    return *m, nil
}

// UnmarshalJSON sets *m to a copy of data.
func (m *RawMessage) UnmarshalJSON(data []byte) os.Error {
    if m == nil {
        return os.NewError("json.RawMessage: UnmarshalJSON on nil pointer")
    }
    *m = bytes.Add((*m)[0:0], data)
    return nil
}

var _ Marshaler = (*RawMessage)(nil)
var _ Unmarshaler = (*RawMessage)(nil)