Commit 6479d893 authored by Russ Cox's avatar Russ Cox

document json

R=r
DELTA=115  (102 added, 0 deleted, 13 changed)
OCL=25953
CL=26128
parent 68c69fac
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Generic JSON representation. // Generic representation of JSON objects.
package json package json
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"vector"; "vector";
) )
// Integers identifying the data type in the Json interface.
const ( const (
StringKind = iota; StringKind = iota;
NumberKind; NumberKind;
...@@ -24,16 +25,23 @@ const ( ...@@ -24,16 +25,23 @@ const (
NullKind; NullKind;
) )
// The Json interface is implemented by all JSON objects.
type Json interface { type Json interface {
Kind() int; Kind() int; // StringKind, NumberKind, etc.
String() string; String() string; // a string form (any kind)
Number() float64; Number() float64; // numeric form (NumberKind)
Bool() bool; Bool() bool; // boolean (BoolKind)
Get(s string) Json; Get(s string) Json; // field lookup (MapKind)
Elem(i int) Json; Elem(i int) Json; // element lookup (ArrayKind)
Len() int; 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 { func JsonToString(j Json) string {
if j == nil { if j == nil {
return "null" return "null"
...@@ -45,7 +53,10 @@ func JsonToString(j Json) string { ...@@ -45,7 +53,10 @@ func JsonToString(j Json) string {
} }
type _Null struct { } type _Null struct { }
// Null is the JSON object representing the null data object.
var Null Json = &_Null{} var Null Json = &_Null{}
func (*_Null) Kind() int { return NullKind } func (*_Null) Kind() int { return NullKind }
func (*_Null) String() string { return "null" } func (*_Null) String() string { return "null" }
func (*_Null) Number() float64 { return 0 } func (*_Null) Number() float64 { return 0 }
...@@ -128,6 +139,14 @@ func (j *_Map) String() string { ...@@ -128,6 +139,14 @@ func (j *_Map) String() string {
return s; 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 { func Walk(j Json, path string) Json {
for len(path) > 0 { for len(path) > 0 {
var elem string; var elem string;
...@@ -154,6 +173,7 @@ func Walk(j Json, path string) Json { ...@@ -154,6 +173,7 @@ func Walk(j Json, path string) Json {
return j return j
} }
// Equal returns whether a and b are indistinguishable JSON objects.
func Equal(a, b Json) bool { func Equal(a, b Json) bool {
switch { switch {
case a == nil && b == nil: case a == nil && b == nil:
...@@ -201,7 +221,7 @@ func Equal(a, b Json) bool { ...@@ -201,7 +221,7 @@ func Equal(a, b Json) bool {
} }
// Parse builder for Json objects. // Parse builder for JSON objects.
type _JsonBuilder struct { type _JsonBuilder struct {
// either writing to *ptr // either writing to *ptr
...@@ -290,6 +310,11 @@ func (b *_JsonBuilder) Key(k string) Builder { ...@@ -290,6 +310,11 @@ func (b *_JsonBuilder) Key(k string) Builder {
return bb 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) { func StringToJson(s string) (json Json, ok bool, errtok string) {
var errindx int; var errindx int;
var j Json; var j Json;
...@@ -301,3 +326,5 @@ func StringToJson(s string) (json Json, ok bool, errtok string) { ...@@ -301,3 +326,5 @@ func StringToJson(s string) (json Json, ok bool, errtok string) {
} }
return j, true, "" return j, true, ""
} }
// BUG(rsc): StringToJson should return an *os.Error instead of a bool.
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
// JSON (JavaScript Object Notation) parser. // JSON (JavaScript Object Notation) parser.
// See http://www.json.org/ // 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 package json
import ( import (
...@@ -43,6 +46,9 @@ func _UnHex(p string, r, l int) (v int, ok bool) { ...@@ -43,6 +46,9 @@ func _UnHex(p string, r, l int) (v int, ok bool) {
return v, true; 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) { func Unquote(s string) (t string, ok bool) {
if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
return return
...@@ -116,6 +122,8 @@ func Unquote(s string) (t string, ok bool) { ...@@ -116,6 +122,8 @@ func Unquote(s string) (t string, ok bool) {
return string(b[0:w]), true 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 { func Quote(s string) string {
chr := make([]byte, utf8.UTFMax); chr := make([]byte, utf8.UTFMax);
chr0 := chr[0:1]; chr0 := chr[0:1];
...@@ -271,6 +279,12 @@ func (t *_Lexer) Next() { ...@@ -271,6 +279,12 @@ func (t *_Lexer) Next() {
type _Value interface {} 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 { type Builder interface {
// Set value // Set value
Int64(i int64); Int64(i int64);
...@@ -385,11 +399,17 @@ Switch: ...@@ -385,11 +399,17 @@ Switch:
return ok; 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 := new(_Lexer);
lex.s = s; lex.s = s;
lex.Next(); lex.Next();
if parse(lex, build) { if parse(lex, builder) {
if lex.kind == 0 { // EOF if lex.kind == 0 { // EOF
return true, 0, "" return true, 0, ""
} }
......
...@@ -202,6 +202,61 @@ func (b *_StructBuilder) Key(k string) Builder { ...@@ -202,6 +202,61 @@ func (b *_StructBuilder) Key(k string) Builder {
return nobuilder 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) { func Unmarshal(s string, val interface{}) (ok bool, errtok string) {
var errindx int; var errindx int;
var val1 interface{}; var val1 interface{};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment