URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [json/] [stream.go] - Rev 747
Compare with Previous | Blame | View Log
// 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 jsonimport ("errors""io")// A Decoder reads and decodes JSON objects from an input stream.type Decoder struct {r io.Readerbuf []byted decodeStatescan scannererr 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 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}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, error) {dec.scan.reset()scanp := 0var err errorInput: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, int(c))if v == scanEnd {scanp += ibreak 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 + 1break Input}if v == scanError {dec.err = dec.scan.errreturn 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 = errreturn 0, err}// Make room to read more into the buffer.const minRead = 512if 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 intn, 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(rune(c)) {return true}}return false}// An Encoder writes JSON objects to an output stream.type Encoder struct {w io.Writere encodeStateerr 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{}) 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, 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)
