// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Generic JSON representation.
+// Generic representation of JSON objects.
package json
"vector";
)
+// Integers identifying the data type in the Json interface.
const (
StringKind = iota;
NumberKind;
NullKind;
)
+// The Json interface is implemented by all JSON objects.
type Json interface {
- Kind() int;
- String() string;
- Number() float64;
- Bool() bool;
- Get(s string) Json;
- Elem(i int) Json;
- Len() int;
+ Kind() int; // StringKind, NumberKind, etc.
+ String() string; // a string form (any kind)
+ Number() float64; // numeric form (NumberKind)
+ Bool() bool; // boolean (BoolKind)
+ Get(s string) Json; // field lookup (MapKind)
+ Elem(i int) Json; // element lookup (ArrayKind)
+ Len() int; // length (ArrayKind)
}
+// JsonToString returns the textual JSON syntax representation
+// for the JSON object j.
+//
+// JsonToString differs from j.String() in the handling
+// of string objects. If j represents the string abc,
+// j.String() == `abc`, but JsonToString(j) == `"abc"`.
func JsonToString(j Json) string {
if j == nil {
return "null"
}
type _Null struct { }
+
+// Null is the JSON object representing the null data object.
var Null Json = &_Null{}
+
func (*_Null) Kind() int { return NullKind }
func (*_Null) String() string { return "null" }
func (*_Null) Number() float64 { return 0 }
return s;
}
+// Walk evaluates path relative to the JSON object j.
+// Path is taken as a sequence of slash-separated field names
+// or numbers that can be used to index into JSON map and
+// array objects.
+//
+// For example, if j is the JSON object for
+// {"abc": [true, false]}, then Walk(j, "abc/1") returns the
+// JSON object for true.
func Walk(j Json, path string) Json {
for len(path) > 0 {
var elem string;
return j
}
+// Equal returns whether a and b are indistinguishable JSON objects.
func Equal(a, b Json) bool {
switch {
case a == nil && b == nil:
}
-// Parse builder for Json objects.
+// Parse builder for JSON objects.
type _JsonBuilder struct {
// either writing to *ptr
return bb
}
+// StringToJson parses the string s as a JSON-syntax string
+// and returns the generic JSON object representation.
+// On success, StringToJson returns with ok set to true and errtok empty.
+// If StringToJson encounters a syntax error, it returns with
+// ok set to false and errtok set to a fragment of the offending syntax.
func StringToJson(s string) (json Json, ok bool, errtok string) {
var errindx int;
var j Json;
}
return j, true, ""
}
+
+// BUG(rsc): StringToJson should return an *os.Error instead of a bool.
// JSON (JavaScript Object Notation) parser.
// See http://www.json.org/
+// The json package implements a simple parser and
+// representation for JSON (JavaScript Object Notation),
+// as defined at http://www.json.org/.
package json
import (
return v, true;
}
+// Unquote unquotes the JSON-quoted string s,
+// returning a raw string t. If s is not a valid
+// JSON-quoted string, Unquote returns with ok set to false.
func Unquote(s string) (t string, ok bool) {
if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
return
return string(b[0:w]), true
}
+// Quote quotes the raw string s using JSON syntax,
+// so that Unquote(Quote(s)) = s, true.
func Quote(s string) string {
chr := make([]byte, utf8.UTFMax);
chr0 := chr[0:1];
type _Value interface {}
+// BUG(rsc): The json Builder interface needs to be
+// reconciled with the xml Builder interface.
+
+// A Builder is an interface implemented by clients and passed
+// to the JSON parser. It gives clients full control over the
+// eventual representation returned by the parser.
type Builder interface {
// Set value
Int64(i int64);
return ok;
}
-func Parse(s string, build Builder) (ok bool, errindx int, errtok string) {
+// Parse parses the JSON syntax string s and makes calls to
+// the builder to construct a parsed representation.
+// On success, it returns with ok set to true.
+// On error, it returns with ok set to false, errindx set
+// to the byte index in s where a syntax error occurred,
+// and errtok set to the offending token.
+func Parse(s string, builder Builder) (ok bool, errindx int, errtok string) {
lex := new(_Lexer);
lex.s = s;
lex.Next();
- if parse(lex, build) {
+ if parse(lex, builder) {
if lex.kind == 0 { // EOF
return true, 0, ""
}
return nobuilder
}
+// Unmarshal parses the JSON syntax string s and fills in
+// an arbitrary struct or array pointed at by val.
+// It uses the reflection library to assign to fields
+// and arrays embedded in val. Well-formed data that does not fit
+// into the struct is discarded.
+//
+// For example, given the following definitions:
+//
+// type Email struct {
+// where string;
+// addr string;
+// }
+//
+// type Result struct {
+// name string;
+// phone string;
+// emails []Email
+// }
+//
+// var r = Result{ "name", "phone", nil }
+//
+// unmarshalling the JSON syntax string
+//
+// {
+// "email": [
+// {
+// "where": "home",
+// "addr": "gre@example.com"
+// },
+// {
+// "where": "work",
+// "addr": "gre@work.com"
+// }
+// ],
+// "name": "Grace R. Emlin",
+// "address": "123 Main Street"
+// }
+//
+// via Unmarshal(s, &r) is equivalent to assigning
+//
+// r = Result{
+// "Grace R. Emlin", // name
+// "phone", // no phone given
+// []Email{
+// Email{ "home", "gre@example.com" },
+// Email{ "work", "gre@work.com" }
+// }
+// }
+//
+// Note that the field r.phone has not been modified and
+// that the JSON field "address" was discarded.
+//
+// On success, Unmarshal returns with ok set to true.
+// On a syntax error, it returns with ok set to false and errtok
+// set to the offending token.
func Unmarshal(s string, val interface{}) (ok bool, errtok string) {
var errindx int;
var val1 interface{};