From 24acda1afc24e668faf29340e76277edeb9db780 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sat, 11 Jul 2015 16:32:46 -0700 Subject: [PATCH] Distinguish between ReadJSON vs ReadJSONPtr. The latter expects a non-nil pointer to write into. The former creates new things intelligently --- binary/binary.go | 30 +++++++++++++++++++++++++++++- node/node.go | 2 +- rpc/server/handlers.go | 4 ++-- state/genesis.go | 2 +- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/binary/binary.go b/binary/binary.go index 962eef98c..00b251163 100644 --- a/binary/binary.go +++ b/binary/binary.go @@ -16,6 +16,10 @@ var ErrBinaryReadSizeUnderflow = errors.New("Error: binary read size underflow") func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) if rv.Kind() == reflect.Ptr { + if rv.IsNil() { + rv = reflect.New(rt.Elem()) + o = rv.Interface() + } readReflectBinary(rv, rt, Options{}, r, n, err) return o } else { @@ -51,10 +55,24 @@ func ReadJSON(o interface{}, bytes []byte, err *error) interface{} { return ReadJSONObject(o, object, err) } +func ReadJSONPtr(o interface{}, bytes []byte, err *error) interface{} { + var object interface{} + *err = json.Unmarshal(bytes, &object) + if *err != nil { + return o + } + + return ReadJSONObjectPtr(o, object, err) +} + func ReadJSONObject(o interface{}, object interface{}, err *error) interface{} { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) if rv.Kind() == reflect.Ptr { - readReflectJSON(rv.Elem(), rt.Elem(), object, err) + if rv.IsNil() { + rv = reflect.New(rt.Elem()) + o = rv.Interface() + } + readReflectJSON(rv, rt, object, err) return o } else { ptrRv := reflect.New(rt) @@ -63,6 +81,16 @@ func ReadJSONObject(o interface{}, object interface{}, err *error) interface{} { } } +func ReadJSONObjectPtr(o interface{}, object interface{}, err *error) interface{} { + rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) + if rv.Kind() == reflect.Ptr { + readReflectJSON(rv.Elem(), rt.Elem(), object, err) + return o + } else { + panic("ReadJSON(Object)Ptr expects o to be a pointer") + } +} + func WriteJSON(o interface{}, w io.Writer, n *int64, err *error) { rv := reflect.ValueOf(o) rt := reflect.TypeOf(o) diff --git a/node/node.go b/node/node.go index 1075c1d7f..aa96606c9 100644 --- a/node/node.go +++ b/node/node.go @@ -69,7 +69,7 @@ func NewNode() *Node { } else { genDocBytes := stateDB.Get(sm.GenDocKey) err := new(error) - binary.ReadJSON(&genDoc, genDocBytes, err) + binary.ReadJSONPtr(&genDoc, genDocBytes, err) if *err != nil { panic(Fmt("Unable to read gendoc from db: %v", err)) } diff --git a/rpc/server/handlers.go b/rpc/server/handlers.go index 77ecc5c92..be4733fd9 100644 --- a/rpc/server/handlers.go +++ b/rpc/server/handlers.go @@ -145,7 +145,7 @@ func jsonParamsToArgs(rpcFunc *RPCFunc, params []interface{}) ([]reflect.Value, func _jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) { var err error v := reflect.New(ty) - binary.ReadJSONObject(v.Interface(), object, &err) + binary.ReadJSONObjectPtr(v.Interface(), object, &err) if err != nil { return v, err } @@ -198,7 +198,7 @@ func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) { var err error v := reflect.New(ty) - binary.ReadJSON(v.Interface(), []byte(arg), &err) + binary.ReadJSONPtr(v.Interface(), []byte(arg), &err) if err != nil { return v, err } diff --git a/state/genesis.go b/state/genesis.go index dfd333be4..c582cf5bb 100644 --- a/state/genesis.go +++ b/state/genesis.go @@ -58,7 +58,7 @@ type GenesisDoc struct { func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { var err error - binary.ReadJSON(&genState, jsonBlob, &err) + binary.ReadJSONPtr(&genState, jsonBlob, &err) if err != nil { log.Error(Fmt("Couldn't read GenesisDoc: %v", err)) os.Exit(1)