mirror of
https://github.com/42wim/matterbridge.git
synced 2024-11-27 05:02:02 -08:00
401 lines
9.3 KiB
Go
401 lines
9.3 KiB
Go
|
package gojay
|
||
|
|
||
|
var objKeyStr = []byte(`":"`)
|
||
|
var objKeyObj = []byte(`":{`)
|
||
|
var objKeyArr = []byte(`":[`)
|
||
|
var objKey = []byte(`":`)
|
||
|
|
||
|
// EncodeObject encodes an object to JSON
|
||
|
func (enc *Encoder) EncodeObject(v MarshalerJSONObject) error {
|
||
|
if enc.isPooled == 1 {
|
||
|
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
|
||
|
}
|
||
|
_, err := enc.encodeObject(v)
|
||
|
if err != nil {
|
||
|
enc.err = err
|
||
|
return err
|
||
|
}
|
||
|
_, err = enc.Write()
|
||
|
if err != nil {
|
||
|
enc.err = err
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// EncodeObjectKeys encodes an object to JSON
|
||
|
func (enc *Encoder) EncodeObjectKeys(v MarshalerJSONObject, keys []string) error {
|
||
|
if enc.isPooled == 1 {
|
||
|
panic(InvalidUsagePooledEncoderError("Invalid usage of pooled encoder"))
|
||
|
}
|
||
|
enc.hasKeys = true
|
||
|
enc.keys = keys
|
||
|
_, err := enc.encodeObject(v)
|
||
|
if err != nil {
|
||
|
enc.err = err
|
||
|
return err
|
||
|
}
|
||
|
_, err = enc.Write()
|
||
|
if err != nil {
|
||
|
enc.err = err
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (enc *Encoder) encodeObject(v MarshalerJSONObject) ([]byte, error) {
|
||
|
enc.grow(512)
|
||
|
enc.writeByte('{')
|
||
|
if !v.IsNil() {
|
||
|
v.MarshalJSONObject(enc)
|
||
|
}
|
||
|
if enc.hasKeys {
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
}
|
||
|
enc.writeByte('}')
|
||
|
return enc.buf, enc.err
|
||
|
}
|
||
|
|
||
|
// AddObject adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) AddObject(v MarshalerJSONObject) {
|
||
|
enc.Object(v)
|
||
|
}
|
||
|
|
||
|
// AddObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) AddObjectOmitEmpty(v MarshalerJSONObject) {
|
||
|
enc.ObjectOmitEmpty(v)
|
||
|
}
|
||
|
|
||
|
// AddObjectNullEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) AddObjectNullEmpty(v MarshalerJSONObject) {
|
||
|
enc.ObjectNullEmpty(v)
|
||
|
}
|
||
|
|
||
|
// AddObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) AddObjectKey(key string, v MarshalerJSONObject) {
|
||
|
enc.ObjectKey(key, v)
|
||
|
}
|
||
|
|
||
|
// AddObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) AddObjectKeyOmitEmpty(key string, v MarshalerJSONObject) {
|
||
|
enc.ObjectKeyOmitEmpty(key, v)
|
||
|
}
|
||
|
|
||
|
// AddObjectKeyNullEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) AddObjectKeyNullEmpty(key string, v MarshalerJSONObject) {
|
||
|
enc.ObjectKeyNullEmpty(key, v)
|
||
|
}
|
||
|
|
||
|
// Object adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) Object(v MarshalerJSONObject) {
|
||
|
if v.IsNil() {
|
||
|
enc.grow(2)
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' && r != '[' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
enc.writeByte('}')
|
||
|
return
|
||
|
}
|
||
|
enc.grow(4)
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '[' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
var origKeys = enc.keys
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectWithKeys adds an object to be encoded, must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject. It will only encode the keys in keys.
|
||
|
func (enc *Encoder) ObjectWithKeys(v MarshalerJSONObject, keys []string) {
|
||
|
if v.IsNil() {
|
||
|
enc.grow(2)
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' && r != '[' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
enc.writeByte('}')
|
||
|
return
|
||
|
}
|
||
|
enc.grow(4)
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '[' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
|
||
|
var origKeys = enc.keys
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
enc.hasKeys = true
|
||
|
enc.keys = keys
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) ObjectOmitEmpty(v MarshalerJSONObject) {
|
||
|
if v.IsNil() {
|
||
|
return
|
||
|
}
|
||
|
enc.grow(2)
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '[' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
var origKeys = enc.keys
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectNullEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) ObjectNullEmpty(v MarshalerJSONObject) {
|
||
|
enc.grow(2)
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '[' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
if v.IsNil() {
|
||
|
enc.writeBytes(nullBytes)
|
||
|
return
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
var origKeys = enc.keys
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectKey adds a struct to be encoded, must be used inside an object as it will encode a key
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) ObjectKey(key string, v MarshalerJSONObject) {
|
||
|
if enc.hasKeys {
|
||
|
if !enc.keyExists(key) {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if v.IsNil() {
|
||
|
enc.grow(2 + len(key))
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('"')
|
||
|
enc.writeStringEscape(key)
|
||
|
enc.writeBytes(objKeyObj)
|
||
|
enc.writeByte('}')
|
||
|
return
|
||
|
}
|
||
|
enc.grow(5 + len(key))
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('"')
|
||
|
enc.writeStringEscape(key)
|
||
|
enc.writeBytes(objKeyObj)
|
||
|
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
var origKeys = enc.keys
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectKeyWithKeys adds a struct to be encoded, must be used inside an object as it will encode a key.
|
||
|
// Value must implement MarshalerJSONObject. It will only encode the keys in keys.
|
||
|
func (enc *Encoder) ObjectKeyWithKeys(key string, value MarshalerJSONObject, keys []string) {
|
||
|
if enc.hasKeys {
|
||
|
if !enc.keyExists(key) {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if value.IsNil() {
|
||
|
enc.grow(2 + len(key))
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('"')
|
||
|
enc.writeStringEscape(key)
|
||
|
enc.writeBytes(objKeyObj)
|
||
|
enc.writeByte('}')
|
||
|
return
|
||
|
}
|
||
|
enc.grow(5 + len(key))
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('"')
|
||
|
enc.writeStringEscape(key)
|
||
|
enc.writeBytes(objKeyObj)
|
||
|
var origKeys = enc.keys
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
enc.hasKeys = true
|
||
|
enc.keys = keys
|
||
|
value.MarshalJSONObject(enc)
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectKeyOmitEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) ObjectKeyOmitEmpty(key string, v MarshalerJSONObject) {
|
||
|
if enc.hasKeys {
|
||
|
if !enc.keyExists(key) {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if v.IsNil() {
|
||
|
return
|
||
|
}
|
||
|
enc.grow(5 + len(key))
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('"')
|
||
|
enc.writeStringEscape(key)
|
||
|
enc.writeBytes(objKeyObj)
|
||
|
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
var origKeys = enc.keys
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// ObjectKeyNullEmpty adds an object to be encoded or skips it if IsNil returns true.
|
||
|
// Must be used inside a slice or array encoding (does not encode a key)
|
||
|
// value must implement MarshalerJSONObject
|
||
|
func (enc *Encoder) ObjectKeyNullEmpty(key string, v MarshalerJSONObject) {
|
||
|
if enc.hasKeys {
|
||
|
if !enc.keyExists(key) {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
enc.grow(5 + len(key))
|
||
|
r := enc.getPreviousRune()
|
||
|
if r != '{' {
|
||
|
enc.writeByte(',')
|
||
|
}
|
||
|
enc.writeByte('"')
|
||
|
enc.writeStringEscape(key)
|
||
|
enc.writeBytes(objKey)
|
||
|
if v.IsNil() {
|
||
|
enc.writeBytes(nullBytes)
|
||
|
return
|
||
|
}
|
||
|
enc.writeByte('{')
|
||
|
|
||
|
var origHasKeys = enc.hasKeys
|
||
|
var origKeys = enc.keys
|
||
|
enc.hasKeys = false
|
||
|
enc.keys = nil
|
||
|
|
||
|
v.MarshalJSONObject(enc)
|
||
|
|
||
|
enc.hasKeys = origHasKeys
|
||
|
enc.keys = origKeys
|
||
|
|
||
|
enc.writeByte('}')
|
||
|
}
|
||
|
|
||
|
// EncodeObjectFunc is a custom func type implementing MarshaleObject.
|
||
|
// Use it to cast a func(*Encoder) to Marshal an object.
|
||
|
//
|
||
|
// enc := gojay.NewEncoder(io.Writer)
|
||
|
// enc.EncodeObject(gojay.EncodeObjectFunc(func(enc *gojay.Encoder) {
|
||
|
// enc.AddStringKey("hello", "world")
|
||
|
// }))
|
||
|
type EncodeObjectFunc func(*Encoder)
|
||
|
|
||
|
// MarshalJSONObject implements MarshalerJSONObject.
|
||
|
func (f EncodeObjectFunc) MarshalJSONObject(enc *Encoder) {
|
||
|
f(enc)
|
||
|
}
|
||
|
|
||
|
// IsNil implements MarshalerJSONObject.
|
||
|
func (f EncodeObjectFunc) IsNil() bool {
|
||
|
return f == nil
|
||
|
}
|
||
|
|
||
|
func (enc *Encoder) keyExists(k string) bool {
|
||
|
if enc.keys == nil {
|
||
|
return false
|
||
|
}
|
||
|
for _, key := range enc.keys {
|
||
|
if key == k {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
return false
|
||
|
}
|