diff options
Diffstat (limited to 'vendor/github.com/francoispqt/gojay/decode_interface.go')
-rw-r--r-- | vendor/github.com/francoispqt/gojay/decode_interface.go | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/vendor/github.com/francoispqt/gojay/decode_interface.go b/vendor/github.com/francoispqt/gojay/decode_interface.go new file mode 100644 index 00000000..015790d8 --- /dev/null +++ b/vendor/github.com/francoispqt/gojay/decode_interface.go @@ -0,0 +1,130 @@ +package gojay + +// TODO @afiune for now we are using the standard json unmarshaling but in +// the future it would be great to implement one here inside this repo +import "encoding/json" + +// DecodeInterface reads the next JSON-encoded value from the decoder's input (io.Reader) and stores it in the value pointed to by i. +// +// i must be an interface poiter +func (dec *Decoder) DecodeInterface(i *interface{}) error { + if dec.isPooled == 1 { + panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder")) + } + err := dec.decodeInterface(i) + return err +} + +func (dec *Decoder) decodeInterface(i *interface{}) error { + start, end, err := dec.getObject() + if err != nil { + dec.cursor = start + return err + } + + // if start & end are equal the object is a null, don't unmarshal + if start == end { + return nil + } + + object := dec.data[start:end] + if err = json.Unmarshal(object, i); err != nil { + return err + } + + dec.cursor = end + return nil +} + +// @afiune Maybe return the type as well? +func (dec *Decoder) getObject() (start int, end int, err error) { + // start cursor + for ; dec.cursor < dec.length || dec.read(); dec.cursor++ { + switch dec.data[dec.cursor] { + case ' ', '\n', '\t', '\r', ',': + continue + // is null + case 'n': + dec.cursor++ + err = dec.assertNull() + if err != nil { + return + } + // Set start & end to the same cursor to indicate the object + // is a null and should not be unmarshal + start = dec.cursor + end = dec.cursor + return + case 't': + start = dec.cursor + dec.cursor++ + err = dec.assertTrue() + if err != nil { + return + } + end = dec.cursor + dec.cursor++ + return + // is false + case 'f': + start = dec.cursor + dec.cursor++ + err = dec.assertFalse() + if err != nil { + return + } + end = dec.cursor + dec.cursor++ + return + // is an object + case '{': + start = dec.cursor + dec.cursor++ + end, err = dec.skipObject() + dec.cursor = end + return + // is string + case '"': + start = dec.cursor + dec.cursor++ + start, end, err = dec.getString() + start-- + dec.cursor = end + return + // is array + case '[': + start = dec.cursor + dec.cursor++ + end, err = dec.skipArray() + dec.cursor = end + return + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': + start = dec.cursor + end, err = dec.skipNumber() + dec.cursor = end + return + default: + err = dec.raiseInvalidJSONErr(dec.cursor) + return + } + } + err = dec.raiseInvalidJSONErr(dec.cursor) + return +} + +// Add Values functions + +// AddInterface decodes the JSON value within an object or an array to a interface{}. +func (dec *Decoder) AddInterface(v *interface{}) error { + return dec.Interface(v) +} + +// Interface decodes the JSON value within an object or an array to an interface{}. +func (dec *Decoder) Interface(value *interface{}) error { + err := dec.decodeInterface(value) + if err != nil { + return err + } + dec.called |= 1 + return nil +} |