Commit 393df079 authored by Russ Cox's avatar Russ Cox

casify json

R=r
DELTA=163  (0 added, 0 deleted, 163 changed)
OCL=22910
CL=22939
parent d2cdcfc1
......@@ -44,40 +44,40 @@ export func JsonToString(j Json) string {
return j.String()
}
type Null struct { }
export var null Json = &Null{}
func (*Null) Kind() int { return NullKind }
func (*Null) String() string { return "null" }
func (*Null) Number() float64 { return 0 }
func (*Null) Bool() bool { return false }
func (*Null) Get(s string) Json { return null }
func (*Null) Elem(int) Json { return null }
func (*Null) Len() int { return 0 }
type String struct { s string; Null }
func (j *String) Kind() int { return StringKind }
func (j *String) String() string { return j.s }
type Number struct { f float64; Null }
func (j *Number) Kind() int { return NumberKind }
func (j *Number) Number() float64 { return j.f }
func (j *Number) String() string {
type _Null struct { }
export var Null Json = &_Null{}
func (*_Null) Kind() int { return NullKind }
func (*_Null) String() string { return "null" }
func (*_Null) Number() float64 { return 0 }
func (*_Null) Bool() bool { return false }
func (*_Null) Get(s string) Json { return Null }
func (*_Null) Elem(int) Json { return Null }
func (*_Null) Len() int { return 0 }
type _String struct { s string; _Null }
func (j *_String) Kind() int { return StringKind }
func (j *_String) String() string { return j.s }
type _Number struct { f float64; _Null }
func (j *_Number) Kind() int { return NumberKind }
func (j *_Number) Number() float64 { return j.f }
func (j *_Number) String() string {
if math.Floor(j.f) == j.f {
return fmt.Sprintf("%.0f", j.f);
}
return fmt.Sprintf("%g", j.f);
}
type Array struct { a *array.Array; Null }
func (j *Array) Kind() int { return ArrayKind }
func (j *Array) Len() int { return j.a.Len() }
func (j *Array) Elem(i int) Json {
type _Array struct { a *array.Array; _Null }
func (j *_Array) Kind() int { return ArrayKind }
func (j *_Array) Len() int { return j.a.Len() }
func (j *_Array) Elem(i int) Json {
if i < 0 || i >= j.a.Len() {
return null
return Null
}
return j.a.At(i)
}
func (j *Array) String() string {
func (j *_Array) String() string {
s := "[";
for i := 0; i < j.a.Len(); i++ {
if i > 0 {
......@@ -89,29 +89,29 @@ func (j *Array) String() string {
return s;
}
type Bool struct { b bool; Null }
func (j *Bool) Kind() int { return BoolKind }
func (j *Bool) Bool() bool { return j.b }
func (j *Bool) String() string {
type _Bool struct { b bool; _Null }
func (j *_Bool) Kind() int { return BoolKind }
func (j *_Bool) Bool() bool { return j.b }
func (j *_Bool) String() string {
if j.b {
return "true"
}
return "false"
}
type Map struct { m map[string]Json; Null }
func (j *Map) Kind() int { return MapKind }
func (j *Map) Get(s string) Json {
type _Map struct { m map[string]Json; _Null }
func (j *_Map) Kind() int { return MapKind }
func (j *_Map) Get(s string) Json {
if j.m == nil {
return null
return Null
}
v, ok := j.m[s];
if !ok {
return null
return Null
}
return v;
}
func (j *Map) String() string {
func (j *_Map) String() string {
s := "{";
first := true;
for k,v := range j.m {
......@@ -142,13 +142,13 @@ export func Walk(j Json, path string) Json {
case ArrayKind:
indx, err := strconv.Atoi(elem);
if err != nil {
return null
return Null
}
j = j.Elem(indx);
case MapKind:
j = j.Get(elem);
default:
return null
return Null
}
}
return j
......@@ -184,8 +184,8 @@ export func Equal(a, b Json) bool {
}
return true;
case MapKind:
m := a.(*Map).m;
if len(m) != len(b.(*Map).m) {
m := a.(*_Map).m;
if len(m) != len(b.(*_Map).m) {
return false;
}
for k,v := range m {
......@@ -203,7 +203,7 @@ export func Equal(a, b Json) bool {
// Parse builder for Json objects.
type JsonBuilder struct {
type _JsonBuilder struct {
// either writing to *ptr
ptr *Json;
......@@ -216,7 +216,7 @@ type JsonBuilder struct {
k string;
}
func (b *JsonBuilder) Put(j Json) {
func (b *_JsonBuilder) Put(j Json) {
switch {
case b.ptr != nil:
*b.ptr = j;
......@@ -227,7 +227,7 @@ func (b *JsonBuilder) Put(j Json) {
}
}
func (b *JsonBuilder) Get() Json {
func (b *_JsonBuilder) Get() Json {
switch {
case b.ptr != nil:
return *b.ptr;
......@@ -239,61 +239,61 @@ func (b *JsonBuilder) Get() Json {
return nil
}
func (b *JsonBuilder) Float64(f float64) {
b.Put(&Number{f, Null{}})
func (b *_JsonBuilder) Float64(f float64) {
b.Put(&_Number{f, _Null{}})
}
func (b *JsonBuilder) Int64(i int64) {
func (b *_JsonBuilder) Int64(i int64) {
b.Float64(float64(i))
}
func (b *JsonBuilder) Uint64(i uint64) {
func (b *_JsonBuilder) Uint64(i uint64) {
b.Float64(float64(i))
}
func (b *JsonBuilder) Bool(tf bool) {
b.Put(&Bool{tf, Null{}})
func (b *_JsonBuilder) Bool(tf bool) {
b.Put(&_Bool{tf, _Null{}})
}
func (b *JsonBuilder) Null() {
b.Put(null)
func (b *_JsonBuilder) Null() {
b.Put(Null)
}
func (b *JsonBuilder) String(s string) {
b.Put(&String{s, Null{}})
func (b *_JsonBuilder) String(s string) {
b.Put(&_String{s, _Null{}})
}
func (b *JsonBuilder) Array() {
b.Put(&Array{array.New(0), Null{}})
func (b *_JsonBuilder) Array() {
b.Put(&_Array{array.New(0), _Null{}})
}
func (b *JsonBuilder) Map() {
b.Put(&Map{make(map[string]Json), Null{}})
func (b *_JsonBuilder) Map() {
b.Put(&_Map{make(map[string]Json), _Null{}})
}
func (b *JsonBuilder) Elem(i int) Builder {
bb := new(JsonBuilder);
bb.a = b.Get().(*Array).a;
func (b *_JsonBuilder) Elem(i int) Builder {
bb := new(_JsonBuilder);
bb.a = b.Get().(*_Array).a;
bb.i = i;
for i >= bb.a.Len() {
bb.a.Push(null)
bb.a.Push(Null)
}
return bb
}
func (b *JsonBuilder) Key(k string) Builder {
bb := new(JsonBuilder);
bb.m = b.Get().(*Map).m;
func (b *_JsonBuilder) Key(k string) Builder {
bb := new(_JsonBuilder);
bb.m = b.Get().(*_Map).m;
bb.k = k;
bb.m[k] = null;
bb.m[k] = Null;
return bb
}
export func StringToJson(s string) (json Json, ok bool, errtok string) {
var errindx int;
var j Json;
b := new(JsonBuilder);
b := new(_JsonBuilder);
b.ptr = &j;
ok, errindx, errtok = Parse(s, b);
if !ok {
......
......@@ -23,7 +23,7 @@ import (
// No literal control characters, supposedly.
// Have also seen \' and embedded newlines.
func UnHex(p string, r, l int) (v int, ok bool) {
func _UnHex(p string, r, l int) (v int, ok bool) {
v = 0;
for i := r; i < l; i++ {
if i >= len(p) {
......@@ -86,7 +86,7 @@ export func Unquote(s string) (t string, ok bool) {
w++;
case 'u':
r++;
rune, ok := UnHex(s, r, 4);
rune, ok := _UnHex(s, r, 4);
if !ok {
return
}
......@@ -166,38 +166,38 @@ export func Quote(s string) string {
}
// Lexer
// _Lexer
type Lexer struct {
type _Lexer struct {
s string;
i int;
kind int;
token string;
}
func Punct(c byte) bool {
func punct(c byte) bool {
return c=='"' || c=='[' || c==']' || c==':' || c=='{' || c=='}' || c==','
}
func White(c byte) bool {
func white(c byte) bool {
return c==' ' || c=='\t' || c=='\n' || c=='\v'
}
func SkipWhite(p string, i int) int {
for i < len(p) && White(p[i]) {
func skipwhite(p string, i int) int {
for i < len(p) && white(p[i]) {
i++
}
return i
}
func SkipToken(p string, i int) int {
for i < len(p) && !Punct(p[i]) && !White(p[i]) {
func skiptoken(p string, i int) int {
for i < len(p) && !punct(p[i]) && !white(p[i]) {
i++
}
return i
}
func SkipString(p string, i int) int {
func skipstring(p string, i int) int {
for i++; i < len(p) && p[i] != '"'; i++ {
if p[i] == '\\' {
i++
......@@ -209,9 +209,9 @@ func SkipString(p string, i int) int {
return i+1
}
func (t *Lexer) Next() {
func (t *_Lexer) Next() {
i, s := t.i, t.s;
i = SkipWhite(s, i);
i = skipwhite(s, i);
if i >= len(s) {
t.kind = 0;
t.token = "";
......@@ -222,19 +222,19 @@ func (t *Lexer) Next() {
c := s[i];
switch {
case c == '-' || '0' <= c && c <= '9':
j := SkipToken(s, i);
j := skiptoken(s, i);
t.kind = '1';
t.token = s[i:j];
i = j;
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
j := SkipToken(s, i);
j := skiptoken(s, i);
t.kind = 'a';
t.token = s[i:j];
i = j;
case c == '"':
j := SkipString(s, i);
j := skipstring(s, i);
t.kind = '"';
t.token = s[i:j];
i = j;
......@@ -270,7 +270,7 @@ func (t *Lexer) Next() {
// nested data structure, using the "map keys"
// as struct field names.
type Value interface {}
type _Value interface {}
export type Builder interface {
// Set value
......@@ -288,7 +288,7 @@ export type Builder interface {
Key(s string) Builder;
}
func ParseValue(lex *Lexer, build Builder) bool {
func parse(lex *_Lexer, build Builder) bool {
ok := false;
Switch:
switch lex.kind {
......@@ -341,7 +341,7 @@ Switch:
}
lex.Next();
}
if !ParseValue(lex, build.Elem(n)) {
if !parse(lex, build.Elem(n)) {
break Switch;
}
n++;
......@@ -372,7 +372,7 @@ Switch:
break Switch;
}
lex.Next();
if !ParseValue(lex, build.Key(key)) {
if !parse(lex, build.Key(key)) {
break Switch;
}
n++;
......@@ -387,10 +387,10 @@ Switch:
}
export func Parse(s string, build Builder) (ok bool, errindx int, errtok string) {
lex := new(Lexer);
lex := new(_Lexer);
lex.s = s;
lex.Next();
if ParseValue(lex, build) {
if parse(lex, build) {
if lex.kind == 0 { // EOF
return true, 0, ""
}
......
......@@ -12,13 +12,13 @@ import (
"reflect";
)
type StructBuilder struct {
type _StructBuilder struct {
val reflect.Value
}
var nobuilder *StructBuilder
var nobuilder *_StructBuilder
func SetFloat(v reflect.Value, f float64) {
func setfloat(v reflect.Value, f float64) {
switch v.Kind() {
case reflect.FloatKind:
v.(reflect.FloatValue).Set(float(f));
......@@ -29,7 +29,7 @@ func SetFloat(v reflect.Value, f float64) {
}
}
func SetInt(v reflect.Value, i int64) {
func setint(v reflect.Value, i int64) {
switch v.Kind() {
case reflect.IntKind:
v.(reflect.IntValue).Set(int(i));
......@@ -54,49 +54,49 @@ func SetInt(v reflect.Value, i int64) {
}
}
func (b *StructBuilder) Int64(i int64) {
func (b *_StructBuilder) Int64(i int64) {
if b == nil {
return
}
v := b.val;
switch v.Kind() {
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind:
SetFloat(v, float64(i));
setfloat(v, float64(i));
default:
SetInt(v, i);
setint(v, i);
}
}
func (b *StructBuilder) Uint64(i uint64) {
func (b *_StructBuilder) Uint64(i uint64) {
if b == nil {
return
}
v := b.val;
switch v.Kind() {
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind:
SetFloat(v, float64(i));
setfloat(v, float64(i));
default:
SetInt(v, int64(i));
setint(v, int64(i));
}
}
func (b *StructBuilder) Float64(f float64) {
func (b *_StructBuilder) Float64(f float64) {
if b == nil {
return
}
v := b.val;
switch v.Kind() {
case reflect.FloatKind, reflect.Float32Kind, reflect.Float64Kind:
SetFloat(v, f);
setfloat(v, f);
default:
SetInt(v, int64(f));
setint(v, int64(f));
}
}
func (b *StructBuilder) Null() {
func (b *_StructBuilder) Null() {
}
func (b *StructBuilder) String(s string) {
func (b *_StructBuilder) String(s string) {
if b == nil {
return
}
......@@ -105,7 +105,7 @@ func (b *StructBuilder) String(s string) {
}
}
func (b *StructBuilder) Bool(tf bool) {
func (b *_StructBuilder) Bool(tf bool) {
if b == nil {
return
}
......@@ -114,7 +114,7 @@ func (b *StructBuilder) Bool(tf bool) {
}
}
func (b *StructBuilder) Array() {
func (b *_StructBuilder) Array() {
if b == nil {
return
}
......@@ -128,7 +128,7 @@ func (b *StructBuilder) Array() {
}
}
func (b *StructBuilder) Elem(i int) Builder {
func (b *_StructBuilder) Elem(i int) Builder {
if b == nil || i < 0 {
return nobuilder
}
......@@ -163,13 +163,13 @@ func (b *StructBuilder) Elem(i int) Builder {
av.SetLen(i+1);
}
if i < av.Len() {
return &StructBuilder{ av.Elem(i) }
return &_StructBuilder{ av.Elem(i) }
}
}
return nobuilder
}
func (b *StructBuilder) Map() {
func (b *_StructBuilder) Map() {
if b == nil {
return
}
......@@ -181,7 +181,7 @@ func (b *StructBuilder) Map() {
}
}
func (b *StructBuilder) Key(k string) Builder {
func (b *_StructBuilder) Key(k string) Builder {
if b == nil {
return nobuilder
}
......@@ -195,7 +195,7 @@ func (b *StructBuilder) Key(k string) Builder {
for i := 0; i < t.Len(); i++ {
name, typ, tag, off := t.Field(i);
if k == name {
return &StructBuilder{ sv.Field(i) }
return &_StructBuilder{ sv.Field(i) }
}
}
}
......@@ -205,7 +205,7 @@ func (b *StructBuilder) Key(k string) Builder {
export func Unmarshal(s string, val interface{}) (ok bool, errtok string) {
var errindx int;
var val1 interface{};
b := &StructBuilder{ reflect.NewValue(val) };
b := &_StructBuilder{ reflect.NewValue(val) };
ok, errindx, errtok = Parse(s, b);
if !ok {
return false, errtok
......
......@@ -9,7 +9,7 @@ import (
"testing";
)
type MyStruct struct {
type _MyStruct struct {
t bool;
f bool;
s string;
......@@ -27,10 +27,10 @@ type MyStruct struct {
fl32 float32;
fl64 float64;
a *[]string; // TODO(rsc): Should be able to use []string.
my *MyStruct;
my *_MyStruct;
};
const Encoded =
const _Encoded =
`{"t":true,"f":false,"s":"abc","i8":1,"i16":2,"i32":3,"i64":4,`
` "u8":5,"u16":6,"u32":7,"u64":8,`
` "i":-9,"u":10,"bogusfield":"should be ignored",`
......@@ -38,7 +38,7 @@ const Encoded =
` "a":["x","y","z"],"my":{"s":"subguy"}}`;
func Check(t *testing.T, ok bool, name string, v interface{}) {
func _Check(t *testing.T, ok bool, name string, v interface{}) {
if !ok {
t.Errorf("%s = %v (BAD)", name, v);
} else {
......@@ -47,36 +47,36 @@ func Check(t *testing.T, ok bool, name string, v interface{}) {
}
export func TestUnmarshal(t *testing.T) {
var m MyStruct;
var m _MyStruct;
m.f = true;
ok, errtok := Unmarshal(Encoded, &m);
ok, errtok := Unmarshal(_Encoded, &m);
if !ok {
t.Fatalf("Unmarshal failed near %s", errtok);
}
Check(t, m.t==true, "t", m.t);
Check(t, m.f==false, "f", m.f);
Check(t, m.s=="abc", "s", m.s);
Check(t, m.i8==1, "i8", m.i8);
Check(t, m.i16==2, "i16", m.i16);
Check(t, m.i32==3, "i32", m.i32);
Check(t, m.i64==4, "i64", m.i64);
Check(t, m.u8==5, "u8", m.u8);
Check(t, m.u16==6, "u16", m.u16);
Check(t, m.u32==7, "u32", m.u32);
Check(t, m.u64==8, "u64", m.u64);
Check(t, m.i==-9, "i", m.i);
Check(t, m.u==10, "u", m.u);
Check(t, m.fl==11.5, "fl", m.fl);
Check(t, m.fl32==12.25, "fl32", m.fl32);
Check(t, m.fl64==13.75, "fl64", m.fl64);
Check(t, m.a!=nil, "a", m.a);
_Check(t, m.t==true, "t", m.t);
_Check(t, m.f==false, "f", m.f);
_Check(t, m.s=="abc", "s", m.s);
_Check(t, m.i8==1, "i8", m.i8);
_Check(t, m.i16==2, "i16", m.i16);
_Check(t, m.i32==3, "i32", m.i32);
_Check(t, m.i64==4, "i64", m.i64);
_Check(t, m.u8==5, "u8", m.u8);
_Check(t, m.u16==6, "u16", m.u16);
_Check(t, m.u32==7, "u32", m.u32);
_Check(t, m.u64==8, "u64", m.u64);
_Check(t, m.i==-9, "i", m.i);
_Check(t, m.u==10, "u", m.u);
_Check(t, m.fl==11.5, "fl", m.fl);
_Check(t, m.fl32==12.25, "fl32", m.fl32);
_Check(t, m.fl64==13.75, "fl64", m.fl64);
_Check(t, m.a!=nil, "a", m.a);
if m.a != nil {
Check(t, m.a[0]=="x", "a[0]", m.a[0]);
Check(t, m.a[1]=="y", "a[1]", m.a[1]);
Check(t, m.a[2]=="z", "a[2]", m.a[2]);
_Check(t, m.a[0]=="x", "a[0]", m.a[0]);
_Check(t, m.a[1]=="y", "a[1]", m.a[1]);
_Check(t, m.a[2]=="z", "a[2]", m.a[2]);
}
Check(t, m.my!=nil, "my", m.my);
_Check(t, m.my!=nil, "my", m.my);
if m.my != nil {
Check(t, m.my.s=="subguy", "my.s", m.my.s);
_Check(t, m.my.s=="subguy", "my.s", m.my.s);
}
}
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