mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-24 04:59:30 +01:00
131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
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
|
|
}
|