summaryrefslogtreecommitdiff
path: root/src/pkg/json
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/json')
-rw-r--r--src/pkg/json/Makefile15
-rw-r--r--src/pkg/json/decode.go917
-rw-r--r--src/pkg/json/decode_test.go541
-rw-r--r--src/pkg/json/encode.go369
-rw-r--r--src/pkg/json/indent.go116
-rw-r--r--src/pkg/json/scanner.go624
-rw-r--r--src/pkg/json/scanner_test.go278
-rw-r--r--src/pkg/json/stream.go185
-rw-r--r--src/pkg/json/stream_test.go122
9 files changed, 0 insertions, 3167 deletions
diff --git a/src/pkg/json/Makefile b/src/pkg/json/Makefile
deleted file mode 100644
index 4e5a8a139..000000000
--- a/src/pkg/json/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2009 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.
-
-include ../../Make.inc
-
-TARG=json
-GOFILES=\
- decode.go\
- encode.go\
- indent.go\
- scanner.go\
- stream.go\
-
-include ../../Make.pkg
diff --git a/src/pkg/json/decode.go b/src/pkg/json/decode.go
deleted file mode 100644
index 35a06b0f9..000000000
--- a/src/pkg/json/decode.go
+++ /dev/null
@@ -1,917 +0,0 @@
-// 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.
-
-// Represents JSON data structure using native Go types: booleans, floats,
-// strings, arrays, and maps.
-
-package json
-
-import (
- "container/vector"
- "encoding/base64"
- "os"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "unicode"
- "utf16"
- "utf8"
-)
-
-// Unmarshal parses the JSON-encoded data and stores the result
-// in the value pointed to by v.
-//
-// Unmarshal traverses the value v recursively.
-// If an encountered value implements the Unmarshaler interface,
-// Unmarshal calls its UnmarshalJSON method with a well-formed
-// JSON encoding.
-//
-// Otherwise, Unmarshal uses the inverse of the encodings that
-// Marshal uses, allocating maps, slices, and pointers as necessary,
-// with the following additional rules:
-//
-// To unmarshal a JSON value into a nil interface value, the
-// type stored in the interface value is one of:
-//
-// bool, for JSON booleans
-// float64, for JSON numbers
-// string, for JSON strings
-// []interface{}, for JSON arrays
-// map[string]interface{}, for JSON objects
-// nil for JSON null
-//
-// If a JSON value is not appropriate for a given target type,
-// or if a JSON number overflows the target type, Unmarshal
-// skips that field and completes the unmarshalling as best it can.
-// If no more serious errors are encountered, Unmarshal returns
-// an UnmarshalTypeError describing the earliest such error.
-//
-func Unmarshal(data []byte, v interface{}) os.Error {
- d := new(decodeState).init(data)
-
- // Quick check for well-formedness.
- // Avoids filling out half a data structure
- // before discovering a JSON syntax error.
- err := checkValid(data, &d.scan)
- if err != nil {
- return err
- }
-
- return d.unmarshal(v)
-}
-
-// Unmarshaler is the interface implemented by objects
-// that can unmarshal a JSON description of themselves.
-// The input can be assumed to be a valid JSON object
-// encoding. UnmarshalJSON must copy the JSON data
-// if it wishes to retain the data after returning.
-type Unmarshaler interface {
- UnmarshalJSON([]byte) os.Error
-}
-
-
-// An UnmarshalTypeError describes a JSON value that was
-// not appropriate for a value of a specific Go type.
-type UnmarshalTypeError struct {
- Value string // description of JSON value - "bool", "array", "number -5"
- Type reflect.Type // type of Go value it could not be assigned to
-}
-
-func (e *UnmarshalTypeError) String() string {
- return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
-}
-
-// An UnmarshalFieldError describes a JSON object key that
-// led to an unexported (and therefore unwritable) struct field.
-type UnmarshalFieldError struct {
- Key string
- Type reflect.Type
- Field reflect.StructField
-}
-
-func (e *UnmarshalFieldError) String() string {
- return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
-}
-
-// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
-// (The argument to Unmarshal must be a non-nil pointer.)
-type InvalidUnmarshalError struct {
- Type reflect.Type
-}
-
-func (e *InvalidUnmarshalError) String() string {
- if e.Type == nil {
- return "json: Unmarshal(nil)"
- }
-
- if e.Type.Kind() != reflect.Ptr {
- return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
- }
- return "json: Unmarshal(nil " + e.Type.String() + ")"
-}
-
-func (d *decodeState) unmarshal(v interface{}) (err os.Error) {
- defer func() {
- if r := recover(); r != nil {
- if _, ok := r.(runtime.Error); ok {
- panic(r)
- }
- err = r.(os.Error)
- }
- }()
-
- rv := reflect.ValueOf(v)
- pv := rv
- if pv.Kind() != reflect.Ptr || pv.IsNil() {
- return &InvalidUnmarshalError{reflect.TypeOf(v)}
- }
-
- d.scan.reset()
- // We decode rv not pv.Elem because the Unmarshaler interface
- // test must be applied at the top level of the value.
- d.value(rv)
- return d.savedError
-}
-
-// decodeState represents the state while decoding a JSON value.
-type decodeState struct {
- data []byte
- off int // read offset in data
- scan scanner
- nextscan scanner // for calls to nextValue
- savedError os.Error
-}
-
-// errPhase is used for errors that should not happen unless
-// there is a bug in the JSON decoder or something is editing
-// the data slice while the decoder executes.
-var errPhase = os.NewError("JSON decoder out of sync - data changing underfoot?")
-
-func (d *decodeState) init(data []byte) *decodeState {
- d.data = data
- d.off = 0
- d.savedError = nil
- return d
-}
-
-// error aborts the decoding by panicking with err.
-func (d *decodeState) error(err os.Error) {
- panic(err)
-}
-
-// saveError saves the first err it is called with,
-// for reporting at the end of the unmarshal.
-func (d *decodeState) saveError(err os.Error) {
- if d.savedError == nil {
- d.savedError = err
- }
-}
-
-// next cuts off and returns the next full JSON value in d.data[d.off:].
-// The next value is known to be an object or array, not a literal.
-func (d *decodeState) next() []byte {
- c := d.data[d.off]
- item, rest, err := nextValue(d.data[d.off:], &d.nextscan)
- if err != nil {
- d.error(err)
- }
- d.off = len(d.data) - len(rest)
-
- // Our scanner has seen the opening brace/bracket
- // and thinks we're still in the middle of the object.
- // invent a closing brace/bracket to get it out.
- if c == '{' {
- d.scan.step(&d.scan, '}')
- } else {
- d.scan.step(&d.scan, ']')
- }
-
- return item
-}
-
-// scanWhile processes bytes in d.data[d.off:] until it
-// receives a scan code not equal to op.
-// It updates d.off and returns the new scan code.
-func (d *decodeState) scanWhile(op int) int {
- var newOp int
- for {
- if d.off >= len(d.data) {
- newOp = d.scan.eof()
- d.off = len(d.data) + 1 // mark processed EOF with len+1
- } else {
- c := int(d.data[d.off])
- d.off++
- newOp = d.scan.step(&d.scan, c)
- }
- if newOp != op {
- break
- }
- }
- return newOp
-}
-
-// value decodes a JSON value from d.data[d.off:] into the value.
-// it updates d.off to point past the decoded value.
-func (d *decodeState) value(v reflect.Value) {
- if !v.IsValid() {
- _, rest, err := nextValue(d.data[d.off:], &d.nextscan)
- if err != nil {
- d.error(err)
- }
- d.off = len(d.data) - len(rest)
-
- // d.scan thinks we're still at the beginning of the item.
- // Feed in an empty string - the shortest, simplest value -
- // so that it knows we got to the end of the value.
- if d.scan.step == stateRedo {
- panic("redo")
- }
- d.scan.step(&d.scan, '"')
- d.scan.step(&d.scan, '"')
- return
- }
-
- switch op := d.scanWhile(scanSkipSpace); op {
- default:
- d.error(errPhase)
-
- case scanBeginArray:
- d.array(v)
-
- case scanBeginObject:
- d.object(v)
-
- case scanBeginLiteral:
- d.literal(v)
- }
-}
-
-// indirect walks down v allocating pointers as needed,
-// until it gets to a non-pointer.
-// if it encounters an Unmarshaler, indirect stops and returns that.
-// if wantptr is true, indirect stops at the last pointer.
-func (d *decodeState) indirect(v reflect.Value, wantptr bool) (Unmarshaler, reflect.Value) {
- for {
- var isUnmarshaler bool
- if v.Type().NumMethod() > 0 {
- // Remember that this is an unmarshaler,
- // but wait to return it until after allocating
- // the pointer (if necessary).
- _, isUnmarshaler = v.Interface().(Unmarshaler)
- }
-
- if iv := v; iv.Kind() == reflect.Interface && !iv.IsNil() {
- v = iv.Elem()
- continue
- }
-
- pv := v
- if pv.Kind() != reflect.Ptr {
- break
- }
-
- if pv.Elem().Kind() != reflect.Ptr && wantptr && pv.CanSet() && !isUnmarshaler {
- return nil, pv
- }
- if pv.IsNil() {
- pv.Set(reflect.New(pv.Type().Elem()))
- }
- if isUnmarshaler {
- // Using v.Interface().(Unmarshaler)
- // here means that we have to use a pointer
- // as the struct field. We cannot use a value inside
- // a pointer to a struct, because in that case
- // v.Interface() is the value (x.f) not the pointer (&x.f).
- // This is an unfortunate consequence of reflect.
- // An alternative would be to look up the
- // UnmarshalJSON method and return a FuncValue.
- return v.Interface().(Unmarshaler), reflect.Value{}
- }
- v = pv.Elem()
- }
- return nil, v
-}
-
-// array consumes an array from d.data[d.off-1:], decoding into the value v.
-// the first byte of the array ('[') has been read already.
-func (d *decodeState) array(v reflect.Value) {
- // Check for unmarshaler.
- unmarshaler, pv := d.indirect(v, false)
- if unmarshaler != nil {
- d.off--
- err := unmarshaler.UnmarshalJSON(d.next())
- if err != nil {
- d.error(err)
- }
- return
- }
- v = pv
-
- // Decoding into nil interface? Switch to non-reflect code.
- iv := v
- ok := iv.Kind() == reflect.Interface
- if ok {
- iv.Set(reflect.ValueOf(d.arrayInterface()))
- return
- }
-
- // Check type of target.
- av := v
- if av.Kind() != reflect.Array && av.Kind() != reflect.Slice {
- d.saveError(&UnmarshalTypeError{"array", v.Type()})
- d.off--
- d.next()
- return
- }
-
- sv := v
-
- i := 0
- for {
- // Look ahead for ] - can only happen on first iteration.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
-
- // Back up so d.value can have the byte we just read.
- d.off--
- d.scan.undo(op)
-
- // Get element of array, growing if necessary.
- if i >= av.Cap() && sv.IsValid() {
- newcap := sv.Cap() + sv.Cap()/2
- if newcap < 4 {
- newcap = 4
- }
- newv := reflect.MakeSlice(sv.Type(), sv.Len(), newcap)
- reflect.Copy(newv, sv)
- sv.Set(newv)
- }
- if i >= av.Len() && sv.IsValid() {
- // Must be slice; gave up on array during i >= av.Cap().
- sv.SetLen(i + 1)
- }
-
- // Decode into element.
- if i < av.Len() {
- d.value(av.Index(i))
- } else {
- // Ran out of fixed array: skip.
- d.value(reflect.Value{})
- }
- i++
-
- // Next token must be , or ].
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
- if op != scanArrayValue {
- d.error(errPhase)
- }
- }
- if i < av.Len() {
- if !sv.IsValid() {
- // Array. Zero the rest.
- z := reflect.Zero(av.Type().Elem())
- for ; i < av.Len(); i++ {
- av.Index(i).Set(z)
- }
- } else {
- sv.SetLen(i)
- }
- }
-}
-
-// matchName returns true if key should be written to a field named name.
-func matchName(key, name string) bool {
- return strings.ToLower(key) == strings.ToLower(name)
-}
-
-// object consumes an object from d.data[d.off-1:], decoding into the value v.
-// the first byte of the object ('{') has been read already.
-func (d *decodeState) object(v reflect.Value) {
- // Check for unmarshaler.
- unmarshaler, pv := d.indirect(v, false)
- if unmarshaler != nil {
- d.off--
- err := unmarshaler.UnmarshalJSON(d.next())
- if err != nil {
- d.error(err)
- }
- return
- }
- v = pv
-
- // Decoding into nil interface? Switch to non-reflect code.
- iv := v
- if iv.Kind() == reflect.Interface {
- iv.Set(reflect.ValueOf(d.objectInterface()))
- return
- }
-
- // Check type of target: struct or map[string]T
- var (
- mv reflect.Value
- sv reflect.Value
- )
- switch v.Kind() {
- case reflect.Map:
- // map must have string type
- t := v.Type()
- if t.Key() != reflect.TypeOf("") {
- d.saveError(&UnmarshalTypeError{"object", v.Type()})
- break
- }
- mv = v
- if mv.IsNil() {
- mv.Set(reflect.MakeMap(t))
- }
- case reflect.Struct:
- sv = v
- default:
- d.saveError(&UnmarshalTypeError{"object", v.Type()})
- }
-
- if !mv.IsValid() && !sv.IsValid() {
- d.off--
- d.next() // skip over { } in input
- return
- }
-
- var mapElem reflect.Value
-
- for {
- // Read opening " of string key or closing }.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- // closing } - can only happen on first iteration.
- break
- }
- if op != scanBeginLiteral {
- d.error(errPhase)
- }
-
- // Read string key.
- start := d.off - 1
- op = d.scanWhile(scanContinue)
- item := d.data[start : d.off-1]
- key, ok := unquote(item)
- if !ok {
- d.error(errPhase)
- }
-
- // Figure out field corresponding to key.
- var subv reflect.Value
- if mv.IsValid() {
- elemType := mv.Type().Elem()
- if !mapElem.IsValid() {
- mapElem = reflect.New(elemType).Elem()
- } else {
- mapElem.Set(reflect.Zero(elemType))
- }
- subv = mapElem
- } else {
- var f reflect.StructField
- var ok bool
- st := sv.Type()
- // First try for field with that tag.
- if isValidTag(key) {
- for i := 0; i < sv.NumField(); i++ {
- f = st.Field(i)
- if f.Tag.Get("json") == key {
- ok = true
- break
- }
- }
- }
- if !ok {
- // Second, exact match.
- f, ok = st.FieldByName(key)
- }
- if !ok {
- // Third, case-insensitive match.
- f, ok = st.FieldByNameFunc(func(s string) bool { return matchName(key, s) })
- }
-
- // Extract value; name must be exported.
- if ok {
- if f.PkgPath != "" {
- d.saveError(&UnmarshalFieldError{key, st, f})
- } else {
- subv = sv.FieldByIndex(f.Index)
- }
- }
- }
-
- // Read : before value.
- if op == scanSkipSpace {
- op = d.scanWhile(scanSkipSpace)
- }
- if op != scanObjectKey {
- d.error(errPhase)
- }
-
- // Read value.
- d.value(subv)
-
- // Write value back to map;
- // if using struct, subv points into struct already.
- if mv.IsValid() {
- mv.SetMapIndex(reflect.ValueOf(key), subv)
- }
-
- // Next token must be , or }.
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- break
- }
- if op != scanObjectValue {
- d.error(errPhase)
- }
- }
-}
-
-// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
-// The first byte of the literal has been read already
-// (that's how the caller knows it's a literal).
-func (d *decodeState) literal(v reflect.Value) {
- // All bytes inside literal return scanContinue op code.
- start := d.off - 1
- op := d.scanWhile(scanContinue)
-
- // Scan read one byte too far; back up.
- d.off--
- d.scan.undo(op)
- item := d.data[start:d.off]
-
- // Check for unmarshaler.
- wantptr := item[0] == 'n' // null
- unmarshaler, pv := d.indirect(v, wantptr)
- if unmarshaler != nil {
- err := unmarshaler.UnmarshalJSON(item)
- if err != nil {
- d.error(err)
- }
- return
- }
- v = pv
-
- switch c := item[0]; c {
- case 'n': // null
- switch v.Kind() {
- default:
- d.saveError(&UnmarshalTypeError{"null", v.Type()})
- case reflect.Interface, reflect.Ptr, reflect.Map:
- v.Set(reflect.Zero(v.Type()))
- }
-
- case 't', 'f': // true, false
- value := c == 't'
- switch v.Kind() {
- default:
- d.saveError(&UnmarshalTypeError{"bool", v.Type()})
- case reflect.Bool:
- v.SetBool(value)
- case reflect.Interface:
- v.Set(reflect.ValueOf(value))
- }
-
- case '"': // string
- s, ok := unquoteBytes(item)
- if !ok {
- d.error(errPhase)
- }
- switch v.Kind() {
- default:
- d.saveError(&UnmarshalTypeError{"string", v.Type()})
- case reflect.Slice:
- if v.Type() != byteSliceType {
- d.saveError(&UnmarshalTypeError{"string", v.Type()})
- break
- }
- b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
- n, err := base64.StdEncoding.Decode(b, s)
- if err != nil {
- d.saveError(err)
- break
- }
- v.Set(reflect.ValueOf(b[0:n]))
- case reflect.String:
- v.SetString(string(s))
- case reflect.Interface:
- v.Set(reflect.ValueOf(string(s)))
- }
-
- default: // number
- if c != '-' && (c < '0' || c > '9') {
- d.error(errPhase)
- }
- s := string(item)
- switch v.Kind() {
- default:
- d.error(&UnmarshalTypeError{"number", v.Type()})
- case reflect.Interface:
- n, err := strconv.Atof64(s)
- if err != nil {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
- break
- }
- v.Set(reflect.ValueOf(n))
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- n, err := strconv.Atoi64(s)
- if err != nil || v.OverflowInt(n) {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
- break
- }
- v.SetInt(n)
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- n, err := strconv.Atoui64(s)
- if err != nil || v.OverflowUint(n) {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
- break
- }
- v.SetUint(n)
-
- case reflect.Float32, reflect.Float64:
- n, err := strconv.AtofN(s, v.Type().Bits())
- if err != nil || v.OverflowFloat(n) {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
- break
- }
- v.SetFloat(n)
- }
- }
-}
-
-// The xxxInterface routines build up a value to be stored
-// in an empty interface. They are not strictly necessary,
-// but they avoid the weight of reflection in this common case.
-
-// valueInterface is like value but returns interface{}
-func (d *decodeState) valueInterface() interface{} {
- switch d.scanWhile(scanSkipSpace) {
- default:
- d.error(errPhase)
- case scanBeginArray:
- return d.arrayInterface()
- case scanBeginObject:
- return d.objectInterface()
- case scanBeginLiteral:
- return d.literalInterface()
- }
- panic("unreachable")
-}
-
-// arrayInterface is like array but returns []interface{}.
-func (d *decodeState) arrayInterface() []interface{} {
- var v vector.Vector
- for {
- // Look ahead for ] - can only happen on first iteration.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
-
- // Back up so d.value can have the byte we just read.
- d.off--
- d.scan.undo(op)
-
- v.Push(d.valueInterface())
-
- // Next token must be , or ].
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
- if op != scanArrayValue {
- d.error(errPhase)
- }
- }
- return v
-}
-
-// objectInterface is like object but returns map[string]interface{}.
-func (d *decodeState) objectInterface() map[string]interface{} {
- m := make(map[string]interface{})
- for {
- // Read opening " of string key or closing }.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- // closing } - can only happen on first iteration.
- break
- }
- if op != scanBeginLiteral {
- d.error(errPhase)
- }
-
- // Read string key.
- start := d.off - 1
- op = d.scanWhile(scanContinue)
- item := d.data[start : d.off-1]
- key, ok := unquote(item)
- if !ok {
- d.error(errPhase)
- }
-
- // Read : before value.
- if op == scanSkipSpace {
- op = d.scanWhile(scanSkipSpace)
- }
- if op != scanObjectKey {
- d.error(errPhase)
- }
-
- // Read value.
- m[key] = d.valueInterface()
-
- // Next token must be , or }.
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- break
- }
- if op != scanObjectValue {
- d.error(errPhase)
- }
- }
- return m
-}
-
-
-// literalInterface is like literal but returns an interface value.
-func (d *decodeState) literalInterface() interface{} {
- // All bytes inside literal return scanContinue op code.
- start := d.off - 1
- op := d.scanWhile(scanContinue)
-
- // Scan read one byte too far; back up.
- d.off--
- d.scan.undo(op)
- item := d.data[start:d.off]
-
- switch c := item[0]; c {
- case 'n': // null
- return nil
-
- case 't', 'f': // true, false
- return c == 't'
-
- case '"': // string
- s, ok := unquote(item)
- if !ok {
- d.error(errPhase)
- }
- return s
-
- default: // number
- if c != '-' && (c < '0' || c > '9') {
- d.error(errPhase)
- }
- n, err := strconv.Atof64(string(item))
- if err != nil {
- d.saveError(&UnmarshalTypeError{"number " + string(item), reflect.TypeOf(0.0)})
- }
- return n
- }
- panic("unreachable")
-}
-
-// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
-// or it returns -1.
-func getu4(s []byte) int {
- if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
- return -1
- }
- rune, err := strconv.Btoui64(string(s[2:6]), 16)
- if err != nil {
- return -1
- }
- return int(rune)
-}
-
-// unquote converts a quoted JSON string literal s into an actual string t.
-// The rules are different than for Go, so cannot use strconv.Unquote.
-func unquote(s []byte) (t string, ok bool) {
- s, ok = unquoteBytes(s)
- t = string(s)
- return
-}
-
-func unquoteBytes(s []byte) (t []byte, ok bool) {
- if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
- return
- }
- s = s[1 : len(s)-1]
-
- // Check for unusual characters. If there are none,
- // then no unquoting is needed, so return a slice of the
- // original bytes.
- r := 0
- for r < len(s) {
- c := s[r]
- if c == '\\' || c == '"' || c < ' ' {
- break
- }
- if c < utf8.RuneSelf {
- r++
- continue
- }
- rune, size := utf8.DecodeRune(s[r:])
- if rune == utf8.RuneError && size == 1 {
- break
- }
- r += size
- }
- if r == len(s) {
- return s, true
- }
-
- b := make([]byte, len(s)+2*utf8.UTFMax)
- w := copy(b, s[0:r])
- for r < len(s) {
- // Out of room? Can only happen if s is full of
- // malformed UTF-8 and we're replacing each
- // byte with RuneError.
- if w >= len(b)-2*utf8.UTFMax {
- nb := make([]byte, (len(b)+utf8.UTFMax)*2)
- copy(nb, b[0:w])
- b = nb
- }
- switch c := s[r]; {
- case c == '\\':
- r++
- if r >= len(s) {
- return
- }
- switch s[r] {
- default:
- return
- case '"', '\\', '/', '\'':
- b[w] = s[r]
- r++
- w++
- case 'b':
- b[w] = '\b'
- r++
- w++
- case 'f':
- b[w] = '\f'
- r++
- w++
- case 'n':
- b[w] = '\n'
- r++
- w++
- case 'r':
- b[w] = '\r'
- r++
- w++
- case 't':
- b[w] = '\t'
- r++
- w++
- case 'u':
- r--
- rune := getu4(s[r:])
- if rune < 0 {
- return
- }
- r += 6
- if utf16.IsSurrogate(rune) {
- rune1 := getu4(s[r:])
- if dec := utf16.DecodeRune(rune, rune1); dec != unicode.ReplacementChar {
- // A valid pair; consume.
- r += 6
- w += utf8.EncodeRune(b[w:], dec)
- break
- }
- // Invalid surrogate; fall back to replacement rune.
- rune = unicode.ReplacementChar
- }
- w += utf8.EncodeRune(b[w:], rune)
- }
-
- // Quote, control characters are invalid.
- case c == '"', c < ' ':
- return
-
- // ASCII
- case c < utf8.RuneSelf:
- b[w] = c
- r++
- w++
-
- // Coerce to well-formed UTF-8.
- default:
- rune, size := utf8.DecodeRune(s[r:])
- r += size
- w += utf8.EncodeRune(b[w:], rune)
- }
- }
- return b[0:w], true
-}
diff --git a/src/pkg/json/decode_test.go b/src/pkg/json/decode_test.go
deleted file mode 100644
index 9b84bc76c..000000000
--- a/src/pkg/json/decode_test.go
+++ /dev/null
@@ -1,541 +0,0 @@
-// 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"
- "os"
- "reflect"
- "strings"
- "testing"
-)
-
-type T struct {
- X string
- Y int
-}
-
-type tx struct {
- x int
-}
-
-var txType = reflect.TypeOf((*tx)(nil)).Elem()
-
-// A type that can unmarshal itself.
-
-type unmarshaler struct {
- T bool
-}
-
-func (u *unmarshaler) UnmarshalJSON(b []byte) os.Error {
- *u = unmarshaler{true} // All we need to see that UnmarshalJson is called.
- return nil
-}
-
-var (
- um0, um1 unmarshaler // target2 of unmarshaling
- ump = &um1
- umtrue = unmarshaler{true}
-)
-
-type badTag struct {
- X string
- Y string `json:"y"`
- Z string `x:"@#*%(#@"`
- W string `json:"@#$@#$"`
-}
-
-type unmarshalTest struct {
- in string
- ptr interface{}
- out interface{}
- err os.Error
-}
-
-var unmarshalTests = []unmarshalTest{
- // basic types
- {`true`, new(bool), true, nil},
- {`1`, new(int), 1, nil},
- {`1.2`, new(float64), 1.2, nil},
- {`-5`, new(int16), int16(-5), nil},
- {`"a\u1234"`, new(string), "a\u1234", nil},
- {`"http:\/\/"`, new(string), "http://", nil},
- {`"g-clef: \uD834\uDD1E"`, new(string), "g-clef: \U0001D11E", nil},
- {`"invalid: \uD834x\uDD1E"`, new(string), "invalid: \uFFFDx\uFFFD", nil},
- {"null", new(interface{}), nil, nil},
- {`{"X": [1,2,3], "Y": 4}`, new(T), T{Y: 4}, &UnmarshalTypeError{"array", reflect.TypeOf("")}},
- {`{"x": 1}`, new(tx), tx{}, &UnmarshalFieldError{"x", txType, txType.Field(0)}},
-
- // skip invalid tags
- {`{"X":"a", "y":"b", "Z":"c", "W":"d"}`, new(badTag), badTag{"a", "b", "c", "d"}, nil},
-
- // syntax errors
- {`{"X": "foo", "Y"}`, nil, nil, &SyntaxError{"invalid character '}' after object key", 17}},
-
- // composite tests
- {allValueIndent, new(All), allValue, nil},
- {allValueCompact, new(All), allValue, nil},
- {allValueIndent, new(*All), &allValue, nil},
- {allValueCompact, new(*All), &allValue, nil},
- {pallValueIndent, new(All), pallValue, nil},
- {pallValueCompact, new(All), pallValue, nil},
- {pallValueIndent, new(*All), &pallValue, nil},
- {pallValueCompact, new(*All), &pallValue, nil},
-
- // unmarshal interface test
- {`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
- {`{"T":false}`, &ump, &umtrue, nil},
-}
-
-func TestMarshal(t *testing.T) {
- b, err := Marshal(allValue)
- if err != nil {
- t.Fatalf("Marshal allValue: %v", err)
- }
- if string(b) != allValueCompact {
- t.Errorf("Marshal allValueCompact")
- diff(t, b, []byte(allValueCompact))
- return
- }
-
- b, err = Marshal(pallValue)
- if err != nil {
- t.Fatalf("Marshal pallValue: %v", err)
- }
- if string(b) != pallValueCompact {
- t.Errorf("Marshal pallValueCompact")
- diff(t, b, []byte(pallValueCompact))
- return
- }
-}
-
-func TestMarshalBadUTF8(t *testing.T) {
- s := "hello\xffworld"
- b, err := Marshal(s)
- if err == nil {
- t.Fatal("Marshal bad UTF8: no error")
- }
- if len(b) != 0 {
- t.Fatal("Marshal returned data")
- }
- if _, ok := err.(*InvalidUTF8Error); !ok {
- t.Fatalf("Marshal did not return InvalidUTF8Error: %T %v", err, err)
- }
-}
-
-func TestUnmarshal(t *testing.T) {
- for i, tt := range unmarshalTests {
- var scan scanner
- in := []byte(tt.in)
- if err := checkValid(in, &scan); err != nil {
- if !reflect.DeepEqual(err, tt.err) {
- t.Errorf("#%d: checkValid: %#v", i, err)
- continue
- }
- }
- if tt.ptr == nil {
- continue
- }
- // v = new(right-type)
- v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
- if err := Unmarshal([]byte(in), v.Interface()); !reflect.DeepEqual(err, tt.err) {
- t.Errorf("#%d: %v want %v", i, err, tt.err)
- continue
- }
- if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
- t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out)
- data, _ := Marshal(v.Elem().Interface())
- println(string(data))
- data, _ = Marshal(tt.out)
- println(string(data))
- return
- continue
- }
- }
-}
-
-func TestUnmarshalMarshal(t *testing.T) {
- initBig()
- var v interface{}
- if err := Unmarshal(jsonBig, &v); err != nil {
- t.Fatalf("Unmarshal: %v", err)
- }
- b, err := Marshal(v)
- if err != nil {
- t.Fatalf("Marshal: %v", err)
- }
- if bytes.Compare(jsonBig, b) != 0 {
- t.Errorf("Marshal jsonBig")
- diff(t, b, jsonBig)
- return
- }
-}
-
-func TestLargeByteSlice(t *testing.T) {
- s0 := make([]byte, 2000)
- for i := range s0 {
- s0[i] = byte(i)
- }
- b, err := Marshal(s0)
- if err != nil {
- t.Fatalf("Marshal: %v", err)
- }
- var s1 []byte
- if err := Unmarshal(b, &s1); err != nil {
- t.Fatalf("Unmarshal: %v", err)
- }
- if bytes.Compare(s0, s1) != 0 {
- t.Errorf("Marshal large byte slice")
- diff(t, s0, s1)
- }
-}
-
-type Xint struct {
- X int
-}
-
-func TestUnmarshalInterface(t *testing.T) {
- var xint Xint
- var i interface{} = &xint
- if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil {
- t.Fatalf("Unmarshal: %v", err)
- }
- if xint.X != 1 {
- t.Fatalf("Did not write to xint")
- }
-}
-
-func TestUnmarshalPtrPtr(t *testing.T) {
- var xint Xint
- pxint := &xint
- if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil {
- t.Fatalf("Unmarshal: %v", err)
- }
- if xint.X != 1 {
- t.Fatalf("Did not write to xint")
- }
-}
-
-func TestHTMLEscape(t *testing.T) {
- b, err := MarshalForHTML("foobarbaz<>&quux")
- if err != nil {
- t.Fatalf("MarshalForHTML error: %v", err)
- }
- if !bytes.Equal(b, []byte(`"foobarbaz\u003c\u003e\u0026quux"`)) {
- t.Fatalf("Unexpected encoding of \"<>&\": %s", b)
- }
-}
-
-func noSpace(c int) int {
- if isSpace(c) {
- return -1
- }
- return c
-}
-
-type All struct {
- Bool bool
- Int int
- Int8 int8
- Int16 int16
- Int32 int32
- Int64 int64
- Uint uint
- Uint8 uint8
- Uint16 uint16
- Uint32 uint32
- Uint64 uint64
- Uintptr uintptr
- Float32 float32
- Float64 float64
-
- Foo string `json:"bar"`
-
- PBool *bool
- PInt *int
- PInt8 *int8
- PInt16 *int16
- PInt32 *int32
- PInt64 *int64
- PUint *uint
- PUint8 *uint8
- PUint16 *uint16
- PUint32 *uint32
- PUint64 *uint64
- PUintptr *uintptr
- PFloat32 *float32
- PFloat64 *float64
-
- String string
- PString *string
-
- Map map[string]Small
- MapP map[string]*Small
- PMap *map[string]Small
- PMapP *map[string]*Small
-
- EmptyMap map[string]Small
- NilMap map[string]Small
-
- Slice []Small
- SliceP []*Small
- PSlice *[]Small
- PSliceP *[]*Small
-
- EmptySlice []Small
- NilSlice []Small
-
- StringSlice []string
- ByteSlice []byte
-
- Small Small
- PSmall *Small
- PPSmall **Small
-
- Interface interface{}
- PInterface *interface{}
-
- unexported int
-}
-
-type Small struct {
- Tag string
-}
-
-var allValue = All{
- Bool: true,
- Int: 2,
- Int8: 3,
- Int16: 4,
- Int32: 5,
- Int64: 6,
- Uint: 7,
- Uint8: 8,
- Uint16: 9,
- Uint32: 10,
- Uint64: 11,
- Uintptr: 12,
- Float32: 14.1,
- Float64: 15.1,
- Foo: "foo",
- String: "16",
- Map: map[string]Small{
- "17": {Tag: "tag17"},
- "18": {Tag: "tag18"},
- },
- MapP: map[string]*Small{
- "19": &Small{Tag: "tag19"},
- "20": nil,
- },
- EmptyMap: map[string]Small{},
- Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}},
- SliceP: []*Small{&Small{Tag: "tag22"}, nil, &Small{Tag: "tag23"}},
- EmptySlice: []Small{},
- StringSlice: []string{"str24", "str25", "str26"},
- ByteSlice: []byte{27, 28, 29},
- Small: Small{Tag: "tag30"},
- PSmall: &Small{Tag: "tag31"},
- Interface: 5.2,
-}
-
-var pallValue = All{
- PBool: &allValue.Bool,
- PInt: &allValue.Int,
- PInt8: &allValue.Int8,
- PInt16: &allValue.Int16,
- PInt32: &allValue.Int32,
- PInt64: &allValue.Int64,
- PUint: &allValue.Uint,
- PUint8: &allValue.Uint8,
- PUint16: &allValue.Uint16,
- PUint32: &allValue.Uint32,
- PUint64: &allValue.Uint64,
- PUintptr: &allValue.Uintptr,
- PFloat32: &allValue.Float32,
- PFloat64: &allValue.Float64,
- PString: &allValue.String,
- PMap: &allValue.Map,
- PMapP: &allValue.MapP,
- PSlice: &allValue.Slice,
- PSliceP: &allValue.SliceP,
- PPSmall: &allValue.PSmall,
- PInterface: &allValue.Interface,
-}
-
-var allValueIndent = `{
- "Bool": true,
- "Int": 2,
- "Int8": 3,
- "Int16": 4,
- "Int32": 5,
- "Int64": 6,
- "Uint": 7,
- "Uint8": 8,
- "Uint16": 9,
- "Uint32": 10,
- "Uint64": 11,
- "Uintptr": 12,
- "Float32": 14.1,
- "Float64": 15.1,
- "bar": "foo",
- "PBool": null,
- "PInt": null,
- "PInt8": null,
- "PInt16": null,
- "PInt32": null,
- "PInt64": null,
- "PUint": null,
- "PUint8": null,
- "PUint16": null,
- "PUint32": null,
- "PUint64": null,
- "PUintptr": null,
- "PFloat32": null,
- "PFloat64": null,
- "String": "16",
- "PString": null,
- "Map": {
- "17": {
- "Tag": "tag17"
- },
- "18": {
- "Tag": "tag18"
- }
- },
- "MapP": {
- "19": {
- "Tag": "tag19"
- },
- "20": null
- },
- "PMap": null,
- "PMapP": null,
- "EmptyMap": {},
- "NilMap": null,
- "Slice": [
- {
- "Tag": "tag20"
- },
- {
- "Tag": "tag21"
- }
- ],
- "SliceP": [
- {
- "Tag": "tag22"
- },
- null,
- {
- "Tag": "tag23"
- }
- ],
- "PSlice": null,
- "PSliceP": null,
- "EmptySlice": [],
- "NilSlice": [],
- "StringSlice": [
- "str24",
- "str25",
- "str26"
- ],
- "ByteSlice": "Gxwd",
- "Small": {
- "Tag": "tag30"
- },
- "PSmall": {
- "Tag": "tag31"
- },
- "PPSmall": null,
- "Interface": 5.2,
- "PInterface": null
-}`
-
-var allValueCompact = strings.Map(noSpace, allValueIndent)
-
-var pallValueIndent = `{
- "Bool": false,
- "Int": 0,
- "Int8": 0,
- "Int16": 0,
- "Int32": 0,
- "Int64": 0,
- "Uint": 0,
- "Uint8": 0,
- "Uint16": 0,
- "Uint32": 0,
- "Uint64": 0,
- "Uintptr": 0,
- "Float32": 0,
- "Float64": 0,
- "bar": "",
- "PBool": true,
- "PInt": 2,
- "PInt8": 3,
- "PInt16": 4,
- "PInt32": 5,
- "PInt64": 6,
- "PUint": 7,
- "PUint8": 8,
- "PUint16": 9,
- "PUint32": 10,
- "PUint64": 11,
- "PUintptr": 12,
- "PFloat32": 14.1,
- "PFloat64": 15.1,
- "String": "",
- "PString": "16",
- "Map": null,
- "MapP": null,
- "PMap": {
- "17": {
- "Tag": "tag17"
- },
- "18": {
- "Tag": "tag18"
- }
- },
- "PMapP": {
- "19": {
- "Tag": "tag19"
- },
- "20": null
- },
- "EmptyMap": null,
- "NilMap": null,
- "Slice": [],
- "SliceP": [],
- "PSlice": [
- {
- "Tag": "tag20"
- },
- {
- "Tag": "tag21"
- }
- ],
- "PSliceP": [
- {
- "Tag": "tag22"
- },
- null,
- {
- "Tag": "tag23"
- }
- ],
- "EmptySlice": [],
- "NilSlice": [],
- "StringSlice": [],
- "ByteSlice": "",
- "Small": {
- "Tag": ""
- },
- "PSmall": null,
- "PPSmall": {
- "Tag": "tag31"
- },
- "Interface": null,
- "PInterface": 5.2
-}`
-
-var pallValueCompact = strings.Map(noSpace, pallValueIndent)
diff --git a/src/pkg/json/encode.go b/src/pkg/json/encode.go
deleted file mode 100644
index adc0f0f37..000000000
--- a/src/pkg/json/encode.go
+++ /dev/null
@@ -1,369 +0,0 @@
-// 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 implements encoding and decoding of JSON objects as defined in
-// RFC 4627.
-package json
-
-import (
- "bytes"
- "encoding/base64"
- "os"
- "reflect"
- "runtime"
- "sort"
- "strconv"
- "unicode"
- "utf8"
-)
-
-// Marshal returns the JSON encoding of v.
-//
-// Marshal traverses the value v recursively.
-// If an encountered value implements the Marshaler interface,
-// Marshal calls its MarshalJSON method to produce JSON.
-//
-// Otherwise, Marshal uses the following type-dependent default encodings:
-//
-// Boolean values encode as JSON booleans.
-//
-// Floating point and integer values encode as JSON numbers.
-//
-// String values encode as JSON strings, with each invalid UTF-8 sequence
-// replaced by the encoding of the Unicode replacement character U+FFFD.
-//
-// Array and slice values encode as JSON arrays, except that
-// []byte encodes as a base64-encoded string.
-//
-// Struct values encode as JSON objects. Each exported struct field
-// becomes a member of the object. By default the object's key string
-// is the struct field name. If the struct field's tag has a "json" key with a
-// value that is a non-empty string consisting of only Unicode letters,
-// digits, and underscores, that value will be used as the object key.
-// For example, the field tag `json:"myName"` says to use "myName"
-// as the object key.
-//
-// Map values encode as JSON objects.
-// The map's key type must be string; the object keys are used directly
-// as map keys.
-//
-// Pointer values encode as the value pointed to.
-// A nil pointer encodes as the null JSON object.
-//
-// Interface values encode as the value contained in the interface.
-// A nil interface value encodes as the null JSON object.
-//
-// Channel, complex, and function values cannot be encoded in JSON.
-// Attempting to encode such a value causes Marshal to return
-// an InvalidTypeError.
-//
-// JSON cannot represent cyclic data structures and Marshal does not
-// handle them. Passing cyclic structures to Marshal will result in
-// an infinite recursion.
-//
-func Marshal(v interface{}) ([]byte, os.Error) {
- e := &encodeState{}
- err := e.marshal(v)
- if err != nil {
- return nil, err
- }
- return e.Bytes(), nil
-}
-
-// MarshalIndent is like Marshal but applies Indent to format the output.
-func MarshalIndent(v interface{}, prefix, indent string) ([]byte, os.Error) {
- b, err := Marshal(v)
- if err != nil {
- return nil, err
- }
- var buf bytes.Buffer
- err = Indent(&buf, b, prefix, indent)
- if err != nil {
- return nil, err
- }
- return buf.Bytes(), nil
-}
-
-// MarshalForHTML is like Marshal but applies HTMLEscape to the output.
-func MarshalForHTML(v interface{}) ([]byte, os.Error) {
- b, err := Marshal(v)
- if err != nil {
- return nil, err
- }
- var buf bytes.Buffer
- HTMLEscape(&buf, b)
- return buf.Bytes(), nil
-}
-
-// HTMLEscape appends to dst the JSON-encoded src with <, >, and &
-// characters inside string literals changed to \u003c, \u003e, \u0026
-// so that the JSON will be safe to embed inside HTML <script> tags.
-// For historical reasons, web browsers don't honor standard HTML
-// escaping within <script> tags, so an alternative JSON encoding must
-// be used.
-func HTMLEscape(dst *bytes.Buffer, src []byte) {
- // < > & can only appear in string literals,
- // so just scan the string one byte at a time.
- start := 0
- for i, c := range src {
- if c == '<' || c == '>' || c == '&' {
- if start < i {
- dst.Write(src[start:i])
- }
- dst.WriteString(`\u00`)
- dst.WriteByte(hex[c>>4])
- dst.WriteByte(hex[c&0xF])
- start = i + 1
- }
- }
- if start < len(src) {
- dst.Write(src[start:])
- }
-}
-
-// Marshaler is the interface implemented by objects that
-// can marshal themselves into valid JSON.
-type Marshaler interface {
- MarshalJSON() ([]byte, os.Error)
-}
-
-type UnsupportedTypeError struct {
- Type reflect.Type
-}
-
-func (e *UnsupportedTypeError) String() string {
- return "json: unsupported type: " + e.Type.String()
-}
-
-type InvalidUTF8Error struct {
- S string
-}
-
-func (e *InvalidUTF8Error) String() string {
- return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
-}
-
-type MarshalerError struct {
- Type reflect.Type
- Error os.Error
-}
-
-func (e *MarshalerError) String() string {
- return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Error.String()
-}
-
-type interfaceOrPtrValue interface {
- IsNil() bool
- Elem() reflect.Value
-}
-
-var hex = "0123456789abcdef"
-
-// An encodeState encodes JSON into a bytes.Buffer.
-type encodeState struct {
- bytes.Buffer // accumulated output
-}
-
-func (e *encodeState) marshal(v interface{}) (err os.Error) {
- defer func() {
- if r := recover(); r != nil {
- if _, ok := r.(runtime.Error); ok {
- panic(r)
- }
- err = r.(os.Error)
- }
- }()
- e.reflectValue(reflect.ValueOf(v))
- return nil
-}
-
-func (e *encodeState) error(err os.Error) {
- panic(err)
-}
-
-var byteSliceType = reflect.TypeOf([]byte(nil))
-
-func (e *encodeState) reflectValue(v reflect.Value) {
- if !v.IsValid() {
- e.WriteString("null")
- return
- }
-
- if j, ok := v.Interface().(Marshaler); ok {
- b, err := j.MarshalJSON()
- if err == nil {
- // copy JSON into buffer, checking validity.
- err = Compact(&e.Buffer, b)
- }
- if err != nil {
- e.error(&MarshalerError{v.Type(), err})
- }
- return
- }
-
- switch v.Kind() {
- case reflect.Bool:
- x := v.Bool()
- if x {
- e.WriteString("true")
- } else {
- e.WriteString("false")
- }
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- e.WriteString(strconv.Itoa64(v.Int()))
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- e.WriteString(strconv.Uitoa64(v.Uint()))
-
- case reflect.Float32, reflect.Float64:
- e.WriteString(strconv.FtoaN(v.Float(), 'g', -1, v.Type().Bits()))
-
- case reflect.String:
- e.string(v.String())
-
- case reflect.Struct:
- e.WriteByte('{')
- t := v.Type()
- n := v.NumField()
- first := true
- for i := 0; i < n; i++ {
- f := t.Field(i)
- if f.PkgPath != "" {
- continue
- }
- if first {
- first = false
- } else {
- e.WriteByte(',')
- }
- if tag := f.Tag.Get("json"); tag != "" && isValidTag(tag) {
- e.string(tag)
- } else {
- e.string(f.Name)
- }
- e.WriteByte(':')
- e.reflectValue(v.Field(i))
- }
- e.WriteByte('}')
-
- case reflect.Map:
- if v.Type().Key().Kind() != reflect.String {
- e.error(&UnsupportedTypeError{v.Type()})
- }
- if v.IsNil() {
- e.WriteString("null")
- break
- }
- e.WriteByte('{')
- var sv stringValues = v.MapKeys()
- sort.Sort(sv)
- for i, k := range sv {
- if i > 0 {
- e.WriteByte(',')
- }
- e.string(k.String())
- e.WriteByte(':')
- e.reflectValue(v.MapIndex(k))
- }
- e.WriteByte('}')
-
- case reflect.Array, reflect.Slice:
- if v.Type() == byteSliceType {
- e.WriteByte('"')
- s := v.Interface().([]byte)
- if len(s) < 1024 {
- // for small buffers, using Encode directly is much faster.
- dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
- base64.StdEncoding.Encode(dst, s)
- e.Write(dst)
- } else {
- // for large buffers, avoid unnecessary extra temporary
- // buffer space.
- enc := base64.NewEncoder(base64.StdEncoding, e)
- enc.Write(s)
- enc.Close()
- }
- e.WriteByte('"')
- break
- }
- e.WriteByte('[')
- n := v.Len()
- for i := 0; i < n; i++ {
- if i > 0 {
- e.WriteByte(',')
- }
- e.reflectValue(v.Index(i))
- }
- e.WriteByte(']')
-
- case reflect.Interface, reflect.Ptr:
- if v.IsNil() {
- e.WriteString("null")
- return
- }
- e.reflectValue(v.Elem())
-
- default:
- e.error(&UnsupportedTypeError{v.Type()})
- }
- return
-}
-
-func isValidTag(s string) bool {
- if s == "" {
- return false
- }
- for _, c := range s {
- if c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) {
- return false
- }
- }
- return true
-}
-
-// stringValues is a slice of reflect.Value holding *reflect.StringValue.
-// It implements the methods to sort by string.
-type stringValues []reflect.Value
-
-func (sv stringValues) Len() int { return len(sv) }
-func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
-func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
-func (sv stringValues) get(i int) string { return sv[i].String() }
-
-func (e *encodeState) string(s string) {
- e.WriteByte('"')
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- if 0x20 <= b && b != '\\' && b != '"' {
- i++
- continue
- }
- if start < i {
- e.WriteString(s[start:i])
- }
- if b == '\\' || b == '"' {
- e.WriteByte('\\')
- e.WriteByte(b)
- } else {
- e.WriteString(`\u00`)
- e.WriteByte(hex[b>>4])
- e.WriteByte(hex[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRuneInString(s[i:])
- if c == utf8.RuneError && size == 1 {
- e.error(&InvalidUTF8Error{s})
- }
- i += size
- }
- if start < len(s) {
- e.WriteString(s[start:])
- }
- e.WriteByte('"')
-}
diff --git a/src/pkg/json/indent.go b/src/pkg/json/indent.go
deleted file mode 100644
index 000da42f6..000000000
--- a/src/pkg/json/indent.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// 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"
- "os"
-)
-
-// Compact appends to dst the JSON-encoded src with
-// insignificant space characters elided.
-func Compact(dst *bytes.Buffer, src []byte) os.Error {
- origLen := dst.Len()
- var scan scanner
- scan.reset()
- start := 0
- for i, c := range src {
- v := scan.step(&scan, int(c))
- if v >= scanSkipSpace {
- if v == scanError {
- break
- }
- if start < i {
- dst.Write(src[start:i])
- }
- start = i + 1
- }
- }
- if scan.eof() == scanError {
- dst.Truncate(origLen)
- return scan.err
- }
- if start < len(src) {
- dst.Write(src[start:])
- }
- return nil
-}
-
-func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
- dst.WriteByte('\n')
- dst.WriteString(prefix)
- for i := 0; i < depth; i++ {
- dst.WriteString(indent)
- }
-}
-
-// Indent appends to dst an indented form of the JSON-encoded src.
-// Each element in a JSON object or array begins on a new,
-// indented line beginning with prefix followed by one or more
-// copies of indent according to the indentation nesting.
-// The data appended to dst has no trailing newline, to make it easier
-// to embed inside other formatted JSON data.
-func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) os.Error {
- origLen := dst.Len()
- var scan scanner
- scan.reset()
- needIndent := false
- depth := 0
- for _, c := range src {
- v := scan.step(&scan, int(c))
- if v == scanSkipSpace {
- continue
- }
- if v == scanError {
- break
- }
- if needIndent && v != scanEndObject && v != scanEndArray {
- needIndent = false
- depth++
- newline(dst, prefix, indent, depth)
- }
-
- // Emit semantically uninteresting bytes
- // (in particular, punctuation in strings) unmodified.
- if v == scanContinue {
- dst.WriteByte(c)
- continue
- }
-
- // Add spacing around real punctuation.
- switch c {
- case '{', '[':
- // delay indent so that empty object and array are formatted as {} and [].
- needIndent = true
- dst.WriteByte(c)
-
- case ',':
- dst.WriteByte(c)
- newline(dst, prefix, indent, depth)
-
- case ':':
- dst.WriteByte(c)
- dst.WriteByte(' ')
-
- case '}', ']':
- if needIndent {
- // suppress indent in empty object/array
- needIndent = false
- } else {
- depth--
- newline(dst, prefix, indent, depth)
- }
- dst.WriteByte(c)
-
- default:
- dst.WriteByte(c)
- }
- }
- if scan.eof() == scanError {
- dst.Truncate(origLen)
- return scan.err
- }
- return nil
-}
diff --git a/src/pkg/json/scanner.go b/src/pkg/json/scanner.go
deleted file mode 100644
index 49c2edd54..000000000
--- a/src/pkg/json/scanner.go
+++ /dev/null
@@ -1,624 +0,0 @@
-// 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
-
-// JSON value parser state machine.
-// Just about at the limit of what is reasonable to write by hand.
-// Some parts are a bit tedious, but overall it nicely factors out the
-// otherwise common code from the multiple scanning functions
-// in this package (Compact, Indent, checkValid, nextValue, etc).
-//
-// This file starts with two simple examples using the scanner
-// before diving into the scanner itself.
-
-import (
- "os"
- "strconv"
-)
-
-// checkValid verifies that data is valid JSON-encoded data.
-// scan is passed in for use by checkValid to avoid an allocation.
-func checkValid(data []byte, scan *scanner) os.Error {
- scan.reset()
- for _, c := range data {
- scan.bytes++
- if scan.step(scan, int(c)) == scanError {
- return scan.err
- }
- }
- if scan.eof() == scanError {
- return scan.err
- }
- return nil
-}
-
-// nextValue splits data after the next whole JSON value,
-// returning that value and the bytes that follow it as separate slices.
-// scan is passed in for use by nextValue to avoid an allocation.
-func nextValue(data []byte, scan *scanner) (value, rest []byte, err os.Error) {
- scan.reset()
- for i, c := range data {
- v := scan.step(scan, int(c))
- if v >= scanEnd {
- switch v {
- case scanError:
- return nil, nil, scan.err
- case scanEnd:
- return data[0:i], data[i:], nil
- }
- }
- }
- if scan.eof() == scanError {
- return nil, nil, scan.err
- }
- return data, nil, nil
-}
-
-// A SyntaxError is a description of a JSON syntax error.
-type SyntaxError struct {
- msg string // description of error
- Offset int64 // error occurred after reading Offset bytes
-}
-
-func (e *SyntaxError) String() string { return e.msg }
-
-// A scanner is a JSON scanning state machine.
-// Callers call scan.reset() and then pass bytes in one at a time
-// by calling scan.step(&scan, c) for each byte.
-// The return value, referred to as an opcode, tells the
-// caller about significant parsing events like beginning
-// and ending literals, objects, and arrays, so that the
-// caller can follow along if it wishes.
-// The return value scanEnd indicates that a single top-level
-// JSON value has been completed, *before* the byte that
-// just got passed in. (The indication must be delayed in order
-// to recognize the end of numbers: is 123 a whole value or
-// the beginning of 12345e+6?).
-type scanner struct {
- // The step is a func to be called to execute the next transition.
- // Also tried using an integer constant and a single func
- // with a switch, but using the func directly was 10% faster
- // on a 64-bit Mac Mini, and it's nicer to read.
- step func(*scanner, int) int
-
- // Stack of what we're in the middle of - array values, object keys, object values.
- parseState []int
-
- // Error that happened, if any.
- err os.Error
-
- // 1-byte redo (see undo method)
- redoCode int
- redoState func(*scanner, int) int
-
- // total bytes consumed, updated by decoder.Decode
- bytes int64
-}
-
-// These values are returned by the state transition functions
-// assigned to scanner.state and the method scanner.eof.
-// They give details about the current state of the scan that
-// callers might be interested to know about.
-// It is okay to ignore the return value of any particular
-// call to scanner.state: if one call returns scanError,
-// every subsequent call will return scanError too.
-const (
- // Continue.
- scanContinue = iota // uninteresting byte
- scanBeginLiteral // end implied by next result != scanContinue
- scanBeginObject // begin object
- scanObjectKey // just finished object key (string)
- scanObjectValue // just finished non-last object value
- scanEndObject // end object (implies scanObjectValue if possible)
- scanBeginArray // begin array
- scanArrayValue // just finished array value
- scanEndArray // end array (implies scanArrayValue if possible)
- scanSkipSpace // space byte; can skip; known to be last "continue" result
-
- // Stop.
- scanEnd // top-level value ended *before* this byte; known to be first "stop" result
- scanError // hit an error, scanner.err.
-)
-
-// These values are stored in the parseState stack.
-// They give the current state of a composite value
-// being scanned. If the parser is inside a nested value
-// the parseState describes the nested state, outermost at entry 0.
-const (
- parseObjectKey = iota // parsing object key (before colon)
- parseObjectValue // parsing object value (after colon)
- parseArrayValue // parsing array value
-)
-
-// reset prepares the scanner for use.
-// It must be called before calling s.step.
-func (s *scanner) reset() {
- s.step = stateBeginValue
- s.parseState = s.parseState[0:0]
- s.err = nil
-}
-
-// eof tells the scanner that the end of input has been reached.
-// It returns a scan status just as s.step does.
-func (s *scanner) eof() int {
- if s.err != nil {
- return scanError
- }
- if s.step == stateEndTop {
- return scanEnd
- }
- s.step(s, ' ')
- if s.step == stateEndTop {
- return scanEnd
- }
- if s.err == nil {
- s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
- }
- return scanError
-}
-
-// pushParseState pushes a new parse state p onto the parse stack.
-func (s *scanner) pushParseState(p int) {
- s.parseState = append(s.parseState, p)
-}
-
-// popParseState pops a parse state (already obtained) off the stack
-// and updates s.step accordingly.
-func (s *scanner) popParseState() {
- n := len(s.parseState) - 1
- s.parseState = s.parseState[0:n]
- if n == 0 {
- s.step = stateEndTop
- } else {
- s.step = stateEndValue
- }
-}
-
-func isSpace(c int) bool {
- return c == ' ' || c == '\t' || c == '\r' || c == '\n'
-}
-
-// NOTE(rsc): The various instances of
-//
-// if c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n')
-//
-// below should all be if c <= ' ' && isSpace(c), but inlining
-// the checks makes a significant difference (>10%) in tight loops
-// such as nextValue. These should be rewritten with the clearer
-// function call once 6g knows to inline the call.
-
-// stateBeginValueOrEmpty is the state after reading `[`.
-func stateBeginValueOrEmpty(s *scanner, c int) int {
- if c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- return scanSkipSpace
- }
- if c == ']' {
- return stateEndValue(s, c)
- }
- return stateBeginValue(s, c)
-}
-
-// stateBeginValue is the state at the beginning of the input.
-func stateBeginValue(s *scanner, c int) int {
- if c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- return scanSkipSpace
- }
- switch c {
- case '{':
- s.step = stateBeginStringOrEmpty
- s.pushParseState(parseObjectKey)
- return scanBeginObject
- case '[':
- s.step = stateBeginValueOrEmpty
- s.pushParseState(parseArrayValue)
- return scanBeginArray
- case '"':
- s.step = stateInString
- return scanBeginLiteral
- case '-':
- s.step = stateNeg
- return scanBeginLiteral
- case '0': // beginning of 0.123
- s.step = state0
- return scanBeginLiteral
- case 't': // beginning of true
- s.step = stateT
- return scanBeginLiteral
- case 'f': // beginning of false
- s.step = stateF
- return scanBeginLiteral
- case 'n': // beginning of null
- s.step = stateN
- return scanBeginLiteral
- }
- if '1' <= c && c <= '9' { // beginning of 1234.5
- s.step = state1
- return scanBeginLiteral
- }
- return s.error(c, "looking for beginning of value")
-}
-
-// stateBeginStringOrEmpty is the state after reading `{`.
-func stateBeginStringOrEmpty(s *scanner, c int) int {
- if c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- return scanSkipSpace
- }
- if c == '}' {
- n := len(s.parseState)
- s.parseState[n-1] = parseObjectValue
- return stateEndValue(s, c)
- }
- return stateBeginString(s, c)
-}
-
-// stateBeginString is the state after reading `{"key": value,`.
-func stateBeginString(s *scanner, c int) int {
- if c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- return scanSkipSpace
- }
- if c == '"' {
- s.step = stateInString
- return scanBeginLiteral
- }
- return s.error(c, "looking for beginning of object key string")
-}
-
-// stateEndValue is the state after completing a value,
-// such as after reading `{}` or `true` or `["x"`.
-func stateEndValue(s *scanner, c int) int {
- n := len(s.parseState)
- if n == 0 {
- // Completed top-level before the current byte.
- s.step = stateEndTop
- return stateEndTop(s, c)
- }
- if c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- s.step = stateEndValue
- return scanSkipSpace
- }
- ps := s.parseState[n-1]
- switch ps {
- case parseObjectKey:
- if c == ':' {
- s.parseState[n-1] = parseObjectValue
- s.step = stateBeginValue
- return scanObjectKey
- }
- return s.error(c, "after object key")
- case parseObjectValue:
- if c == ',' {
- s.parseState[n-1] = parseObjectKey
- s.step = stateBeginString
- return scanObjectValue
- }
- if c == '}' {
- s.popParseState()
- return scanEndObject
- }
- return s.error(c, "after object key:value pair")
- case parseArrayValue:
- if c == ',' {
- s.step = stateBeginValue
- return scanArrayValue
- }
- if c == ']' {
- s.popParseState()
- return scanEndArray
- }
- return s.error(c, "after array element")
- }
- return s.error(c, "")
-}
-
-// stateEndTop is the state after finishing the top-level value,
-// such as after reading `{}` or `[1,2,3]`.
-// Only space characters should be seen now.
-func stateEndTop(s *scanner, c int) int {
- if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
- // Complain about non-space byte on next call.
- s.error(c, "after top-level value")
- }
- return scanEnd
-}
-
-// stateInString is the state after reading `"`.
-func stateInString(s *scanner, c int) int {
- if c == '"' {
- s.step = stateEndValue
- return scanContinue
- }
- if c == '\\' {
- s.step = stateInStringEsc
- return scanContinue
- }
- if c < 0x20 {
- return s.error(c, "in string literal")
- }
- return scanContinue
-}
-
-// stateInStringEsc is the state after reading `"\` during a quoted string.
-func stateInStringEsc(s *scanner, c int) int {
- switch c {
- case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
- s.step = stateInString
- return scanContinue
- }
- if c == 'u' {
- s.step = stateInStringEscU
- return scanContinue
- }
- return s.error(c, "in string escape code")
-}
-
-// stateInStringEscU is the state after reading `"\u` during a quoted string.
-func stateInStringEscU(s *scanner, c int) int {
- if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
- s.step = stateInStringEscU1
- return scanContinue
- }
- // numbers
- return s.error(c, "in \\u hexadecimal character escape")
-}
-
-// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
-func stateInStringEscU1(s *scanner, c int) int {
- if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
- s.step = stateInStringEscU12
- return scanContinue
- }
- // numbers
- return s.error(c, "in \\u hexadecimal character escape")
-}
-
-// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
-func stateInStringEscU12(s *scanner, c int) int {
- if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
- s.step = stateInStringEscU123
- return scanContinue
- }
- // numbers
- return s.error(c, "in \\u hexadecimal character escape")
-}
-
-// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
-func stateInStringEscU123(s *scanner, c int) int {
- if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
- s.step = stateInString
- return scanContinue
- }
- // numbers
- return s.error(c, "in \\u hexadecimal character escape")
-}
-
-// stateInStringEscU123 is the state after reading `-` during a number.
-func stateNeg(s *scanner, c int) int {
- if c == '0' {
- s.step = state0
- return scanContinue
- }
- if '1' <= c && c <= '9' {
- s.step = state1
- return scanContinue
- }
- return s.error(c, "in numeric literal")
-}
-
-// state1 is the state after reading a non-zero integer during a number,
-// such as after reading `1` or `100` but not `0`.
-func state1(s *scanner, c int) int {
- if '0' <= c && c <= '9' {
- s.step = state1
- return scanContinue
- }
- return state0(s, c)
-}
-
-// state0 is the state after reading `0` during a number.
-func state0(s *scanner, c int) int {
- if c == '.' {
- s.step = stateDot
- return scanContinue
- }
- if c == 'e' || c == 'E' {
- s.step = stateE
- return scanContinue
- }
- return stateEndValue(s, c)
-}
-
-// stateDot is the state after reading the integer and decimal point in a number,
-// such as after reading `1.`.
-func stateDot(s *scanner, c int) int {
- if '0' <= c && c <= '9' {
- s.step = stateDot0
- return scanContinue
- }
- return s.error(c, "after decimal point in numeric literal")
-}
-
-// stateDot0 is the state after reading the integer, decimal point, and subsequent
-// digits of a number, such as after reading `3.14`.
-func stateDot0(s *scanner, c int) int {
- if '0' <= c && c <= '9' {
- s.step = stateDot0
- return scanContinue
- }
- if c == 'e' || c == 'E' {
- s.step = stateE
- return scanContinue
- }
- return stateEndValue(s, c)
-}
-
-// stateE is the state after reading the mantissa and e in a number,
-// such as after reading `314e` or `0.314e`.
-func stateE(s *scanner, c int) int {
- if c == '+' {
- s.step = stateESign
- return scanContinue
- }
- if c == '-' {
- s.step = stateESign
- return scanContinue
- }
- return stateESign(s, c)
-}
-
-// stateESign is the state after reading the mantissa, e, and sign in a number,
-// such as after reading `314e-` or `0.314e+`.
-func stateESign(s *scanner, c int) int {
- if '0' <= c && c <= '9' {
- s.step = stateE0
- return scanContinue
- }
- return s.error(c, "in exponent of numeric literal")
-}
-
-// stateE0 is the state after reading the mantissa, e, optional sign,
-// and at least one digit of the exponent in a number,
-// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
-func stateE0(s *scanner, c int) int {
- if '0' <= c && c <= '9' {
- s.step = stateE0
- return scanContinue
- }
- return stateEndValue(s, c)
-}
-
-// stateT is the state after reading `t`.
-func stateT(s *scanner, c int) int {
- if c == 'r' {
- s.step = stateTr
- return scanContinue
- }
- return s.error(c, "in literal true (expecting 'r')")
-}
-
-// stateTr is the state after reading `tr`.
-func stateTr(s *scanner, c int) int {
- if c == 'u' {
- s.step = stateTru
- return scanContinue
- }
- return s.error(c, "in literal true (expecting 'u')")
-}
-
-// stateTru is the state after reading `tru`.
-func stateTru(s *scanner, c int) int {
- if c == 'e' {
- s.step = stateEndValue
- return scanContinue
- }
- return s.error(c, "in literal true (expecting 'e')")
-}
-
-// stateF is the state after reading `f`.
-func stateF(s *scanner, c int) int {
- if c == 'a' {
- s.step = stateFa
- return scanContinue
- }
- return s.error(c, "in literal false (expecting 'a')")
-}
-
-// stateFa is the state after reading `fa`.
-func stateFa(s *scanner, c int) int {
- if c == 'l' {
- s.step = stateFal
- return scanContinue
- }
- return s.error(c, "in literal false (expecting 'l')")
-}
-
-// stateFal is the state after reading `fal`.
-func stateFal(s *scanner, c int) int {
- if c == 's' {
- s.step = stateFals
- return scanContinue
- }
- return s.error(c, "in literal false (expecting 's')")
-}
-
-// stateFals is the state after reading `fals`.
-func stateFals(s *scanner, c int) int {
- if c == 'e' {
- s.step = stateEndValue
- return scanContinue
- }
- return s.error(c, "in literal false (expecting 'e')")
-}
-
-// stateN is the state after reading `n`.
-func stateN(s *scanner, c int) int {
- if c == 'u' {
- s.step = stateNu
- return scanContinue
- }
- return s.error(c, "in literal null (expecting 'u')")
-}
-
-// stateNu is the state after reading `nu`.
-func stateNu(s *scanner, c int) int {
- if c == 'l' {
- s.step = stateNul
- return scanContinue
- }
- return s.error(c, "in literal null (expecting 'l')")
-}
-
-// stateNul is the state after reading `nul`.
-func stateNul(s *scanner, c int) int {
- if c == 'l' {
- s.step = stateEndValue
- return scanContinue
- }
- return s.error(c, "in literal null (expecting 'l')")
-}
-
-// stateError is the state after reaching a syntax error,
-// such as after reading `[1}` or `5.1.2`.
-func stateError(s *scanner, c int) int {
- return scanError
-}
-
-// error records an error and switches to the error state.
-func (s *scanner) error(c int, context string) int {
- s.step = stateError
- s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
- return scanError
-}
-
-// quoteChar formats c as a quoted character literal
-func quoteChar(c int) string {
- // special cases - different from quoted strings
- if c == '\'' {
- return `'\''`
- }
- if c == '"' {
- return `'"'`
- }
-
- // use quoted string with different quotation marks
- s := strconv.Quote(string(c))
- return "'" + s[1:len(s)-1] + "'"
-}
-
-// undo causes the scanner to return scanCode from the next state transition.
-// This gives callers a simple 1-byte undo mechanism.
-func (s *scanner) undo(scanCode int) {
- if s.step == stateRedo {
- panic("invalid use of scanner")
- }
- s.redoCode = scanCode
- s.redoState = s.step
- s.step = stateRedo
-}
-
-// stateRedo helps implement the scanner's 1-byte undo.
-func stateRedo(s *scanner, c int) int {
- s.step = s.redoState
- return s.redoCode
-}
diff --git a/src/pkg/json/scanner_test.go b/src/pkg/json/scanner_test.go
deleted file mode 100644
index 023e7c81e..000000000
--- a/src/pkg/json/scanner_test.go
+++ /dev/null
@@ -1,278 +0,0 @@
-// 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"
- "math"
- "rand"
- "testing"
-)
-
-// Tests of simple examples.
-
-type example struct {
- compact string
- indent string
-}
-
-var examples = []example{
- {`1`, `1`},
- {`{}`, `{}`},
- {`[]`, `[]`},
- {`{"":2}`, "{\n\t\"\": 2\n}"},
- {`[3]`, "[\n\t3\n]"},
- {`[1,2,3]`, "[\n\t1,\n\t2,\n\t3\n]"},
- {`{"x":1}`, "{\n\t\"x\": 1\n}"},
- {ex1, ex1i},
-}
-
-var ex1 = `[true,false,null,"x",1,1.5,0,-5e+2]`
-
-var ex1i = `[
- true,
- false,
- null,
- "x",
- 1,
- 1.5,
- 0,
- -5e+2
-]`
-
-func TestCompact(t *testing.T) {
- var buf bytes.Buffer
- for _, tt := range examples {
- buf.Reset()
- if err := Compact(&buf, []byte(tt.compact)); err != nil {
- t.Errorf("Compact(%#q): %v", tt.compact, err)
- } else if s := buf.String(); s != tt.compact {
- t.Errorf("Compact(%#q) = %#q, want original", tt.compact, s)
- }
-
- buf.Reset()
- if err := Compact(&buf, []byte(tt.indent)); err != nil {
- t.Errorf("Compact(%#q): %v", tt.indent, err)
- continue
- } else if s := buf.String(); s != tt.compact {
- t.Errorf("Compact(%#q) = %#q, want %#q", tt.indent, s, tt.compact)
- }
- }
-}
-
-func TestIndent(t *testing.T) {
- var buf bytes.Buffer
- for _, tt := range examples {
- buf.Reset()
- if err := Indent(&buf, []byte(tt.indent), "", "\t"); err != nil {
- t.Errorf("Indent(%#q): %v", tt.indent, err)
- } else if s := buf.String(); s != tt.indent {
- t.Errorf("Indent(%#q) = %#q, want original", tt.indent, s)
- }
-
- buf.Reset()
- if err := Indent(&buf, []byte(tt.compact), "", "\t"); err != nil {
- t.Errorf("Indent(%#q): %v", tt.compact, err)
- continue
- } else if s := buf.String(); s != tt.indent {
- t.Errorf("Indent(%#q) = %#q, want %#q", tt.compact, s, tt.indent)
- }
- }
-}
-
-// Tests of a large random structure.
-
-func TestCompactBig(t *testing.T) {
- initBig()
- var buf bytes.Buffer
- if err := Compact(&buf, jsonBig); err != nil {
- t.Fatalf("Compact: %v", err)
- }
- b := buf.Bytes()
- if bytes.Compare(b, jsonBig) != 0 {
- t.Error("Compact(jsonBig) != jsonBig")
- diff(t, b, jsonBig)
- return
- }
-}
-
-func TestIndentBig(t *testing.T) {
- initBig()
- var buf bytes.Buffer
- if err := Indent(&buf, jsonBig, "", "\t"); err != nil {
- t.Fatalf("Indent1: %v", err)
- }
- b := buf.Bytes()
- if len(b) == len(jsonBig) {
- // jsonBig is compact (no unnecessary spaces);
- // indenting should make it bigger
- t.Fatalf("Indent(jsonBig) did not get bigger")
- }
-
- // should be idempotent
- var buf1 bytes.Buffer
- if err := Indent(&buf1, b, "", "\t"); err != nil {
- t.Fatalf("Indent2: %v", err)
- }
- b1 := buf1.Bytes()
- if bytes.Compare(b1, b) != 0 {
- t.Error("Indent(Indent(jsonBig)) != Indent(jsonBig)")
- diff(t, b1, b)
- return
- }
-
- // should get back to original
- buf1.Reset()
- if err := Compact(&buf1, b); err != nil {
- t.Fatalf("Compact: %v", err)
- }
- b1 = buf1.Bytes()
- if bytes.Compare(b1, jsonBig) != 0 {
- t.Error("Compact(Indent(jsonBig)) != jsonBig")
- diff(t, b1, jsonBig)
- return
- }
-}
-
-func TestNextValueBig(t *testing.T) {
- initBig()
- var scan scanner
- item, rest, err := nextValue(jsonBig, &scan)
- if err != nil {
- t.Fatalf("nextValue: %s", err)
- }
- if len(item) != len(jsonBig) || &item[0] != &jsonBig[0] {
- t.Errorf("invalid item: %d %d", len(item), len(jsonBig))
- }
- if len(rest) != 0 {
- t.Errorf("invalid rest: %d", len(rest))
- }
-
- item, rest, err = nextValue(append(jsonBig, []byte("HELLO WORLD")...), &scan)
- if err != nil {
- t.Fatalf("nextValue extra: %s", err)
- }
- if len(item) != len(jsonBig) {
- t.Errorf("invalid item: %d %d", len(item), len(jsonBig))
- }
- if string(rest) != "HELLO WORLD" {
- t.Errorf("invalid rest: %d", len(rest))
- }
-}
-
-func BenchmarkSkipValue(b *testing.B) {
- initBig()
- var scan scanner
- for i := 0; i < b.N; i++ {
- nextValue(jsonBig, &scan)
- }
- b.SetBytes(int64(len(jsonBig)))
-}
-
-func diff(t *testing.T, a, b []byte) {
- for i := 0; ; i++ {
- if i >= len(a) || i >= len(b) || a[i] != b[i] {
- j := i - 10
- if j < 0 {
- j = 0
- }
- t.Errorf("diverge at %d: «%s» vs «%s»", i, trim(a[j:]), trim(b[j:]))
- return
- }
- }
-}
-
-func trim(b []byte) []byte {
- if len(b) > 20 {
- return b[0:20]
- }
- return b
-}
-
-// Generate a random JSON object.
-
-var jsonBig []byte
-
-const (
- big = 10000
- small = 100
-)
-
-func initBig() {
- n := big
- if testing.Short() {
- n = small
- }
- if len(jsonBig) != n {
- b, err := Marshal(genValue(n))
- if err != nil {
- panic(err)
- }
- jsonBig = b
- }
-}
-
-func genValue(n int) interface{} {
- if n > 1 {
- switch rand.Intn(2) {
- case 0:
- return genArray(n)
- case 1:
- return genMap(n)
- }
- }
- switch rand.Intn(3) {
- case 0:
- return rand.Intn(2) == 0
- case 1:
- return rand.NormFloat64()
- case 2:
- return genString(30)
- }
- panic("unreachable")
-}
-
-func genString(stddev float64) string {
- n := int(math.Fabs(rand.NormFloat64()*stddev + stddev/2))
- c := make([]int, n)
- for i := range c {
- f := math.Fabs(rand.NormFloat64()*64 + 32)
- if f > 0x10ffff {
- f = 0x10ffff
- }
- c[i] = int(f)
- }
- return string(c)
-}
-
-func genArray(n int) []interface{} {
- f := int(math.Fabs(rand.NormFloat64()) * math.Fmin(10, float64(n/2)))
- if f > n {
- f = n
- }
- if n > 0 && f == 0 {
- f = 1
- }
- x := make([]interface{}, f)
- for i := range x {
- x[i] = genValue(((i+1)*n)/f - (i*n)/f)
- }
- return x
-}
-
-func genMap(n int) map[string]interface{} {
- f := int(math.Fabs(rand.NormFloat64()) * math.Fmin(10, float64(n/2)))
- if f > n {
- f = n
- }
- if n > 0 && f == 0 {
- f = 1
- }
- x := make(map[string]interface{})
- for i := 0; i < f; i++ {
- x[genString(10)] = genValue(((i+1)*n)/f - (i*n)/f)
- }
- return x
-}
diff --git a/src/pkg/json/stream.go b/src/pkg/json/stream.go
deleted file mode 100644
index f143b3f0a..000000000
--- a/src/pkg/json/stream.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// 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 (
- "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 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{}) 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:] {
- dec.scan.bytes++
- 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 = append((*m)[0:0], data...)
- return nil
-}
-
-var _ Marshaler = (*RawMessage)(nil)
-var _ Unmarshaler = (*RawMessage)(nil)
diff --git a/src/pkg/json/stream_test.go b/src/pkg/json/stream_test.go
deleted file mode 100644
index 6ddaed9fe..000000000
--- a/src/pkg/json/stream_test.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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"
- "reflect"
- "testing"
-)
-
-// Test values for the stream test.
-// One of each JSON kind.
-var streamTest = []interface{}{
- 0.1,
- "hello",
- nil,
- true,
- false,
- []interface{}{"a", "b", "c"},
- map[string]interface{}{"K": "Kelvin", "ß": "long s"},
- 3.14, // another value to make sure something can follow map
-}
-
-var streamEncoded = `0.1
-"hello"
-null
-true
-false
-["a","b","c"]
-{"ß":"long s","K":"Kelvin"}
-3.14
-`
-
-func TestEncoder(t *testing.T) {
- for i := 0; i <= len(streamTest); i++ {
- var buf bytes.Buffer
- enc := NewEncoder(&buf)
- for j, v := range streamTest[0:i] {
- if err := enc.Encode(v); err != nil {
- t.Fatalf("encode #%d: %v", j, err)
- }
- }
- if have, want := buf.String(), nlines(streamEncoded, i); have != want {
- t.Errorf("encoding %d items: mismatch", i)
- diff(t, []byte(have), []byte(want))
- break
- }
- }
-}
-
-func TestDecoder(t *testing.T) {
- for i := 0; i <= len(streamTest); i++ {
- // Use stream without newlines as input,
- // just to stress the decoder even more.
- // Our test input does not include back-to-back numbers.
- // Otherwise stripping the newlines would
- // merge two adjacent JSON values.
- var buf bytes.Buffer
- for _, c := range nlines(streamEncoded, i) {
- if c != '\n' {
- buf.WriteRune(c)
- }
- }
- out := make([]interface{}, i)
- dec := NewDecoder(&buf)
- for j := range out {
- if err := dec.Decode(&out[j]); err != nil {
- t.Fatalf("decode #%d/%d: %v", j, i, err)
- }
- }
- if !reflect.DeepEqual(out, streamTest[0:i]) {
- t.Errorf("decoding %d items: mismatch", i)
- for j := range out {
- if !reflect.DeepEqual(out[j], streamTest[j]) {
- t.Errorf("#%d: have %v want %v", j, out[j], streamTest[j])
- }
- }
- break
- }
- }
-}
-
-func nlines(s string, n int) string {
- if n <= 0 {
- return ""
- }
- for i, c := range s {
- if c == '\n' {
- if n--; n == 0 {
- return s[0 : i+1]
- }
- }
- }
- return s
-}
-
-func TestRawMessage(t *testing.T) {
- // TODO(rsc): Should not need the * in *RawMessage
- var data struct {
- X float64
- Id *RawMessage
- Y float32
- }
- const raw = `["\u0056",null]`
- const msg = `{"X":0.1,"Id":["\u0056",null],"Y":0.2}`
- err := Unmarshal([]byte(msg), &data)
- if err != nil {
- t.Fatalf("Unmarshal: %v", err)
- }
- if string([]byte(*data.Id)) != raw {
- t.Fatalf("Raw mismatch: have %#q want %#q", []byte(*data.Id), raw)
- }
- b, err := Marshal(&data)
- if err != nil {
- t.Fatalf("Marshal: %v", err)
- }
- if string(b) != msg {
- t.Fatalf("Marshal: have %#q want %#q", b, msg)
- }
-}