mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
4.7 KiB
278 lines
4.7 KiB
package jsoniter |
|
|
|
import ( |
|
"reflect" |
|
"unsafe" |
|
) |
|
|
|
type arrayLazyAny struct { |
|
baseAny |
|
cfg *frozenConfig |
|
buf []byte |
|
err error |
|
} |
|
|
|
func (any *arrayLazyAny) ValueType() ValueType { |
|
return ArrayValue |
|
} |
|
|
|
func (any *arrayLazyAny) MustBeValid() Any { |
|
return any |
|
} |
|
|
|
func (any *arrayLazyAny) LastError() error { |
|
return any.err |
|
} |
|
|
|
func (any *arrayLazyAny) ToBool() bool { |
|
iter := any.cfg.BorrowIterator(any.buf) |
|
defer any.cfg.ReturnIterator(iter) |
|
return iter.ReadArray() |
|
} |
|
|
|
func (any *arrayLazyAny) ToInt() int { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToInt32() int32 { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToInt64() int64 { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToUint() uint { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToUint32() uint32 { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToUint64() uint64 { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToFloat32() float32 { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToFloat64() float64 { |
|
if any.ToBool() { |
|
return 1 |
|
} |
|
return 0 |
|
} |
|
|
|
func (any *arrayLazyAny) ToString() string { |
|
return *(*string)(unsafe.Pointer(&any.buf)) |
|
} |
|
|
|
func (any *arrayLazyAny) ToVal(val interface{}) { |
|
iter := any.cfg.BorrowIterator(any.buf) |
|
defer any.cfg.ReturnIterator(iter) |
|
iter.ReadVal(val) |
|
} |
|
|
|
func (any *arrayLazyAny) Get(path ...interface{}) Any { |
|
if len(path) == 0 { |
|
return any |
|
} |
|
switch firstPath := path[0].(type) { |
|
case int: |
|
iter := any.cfg.BorrowIterator(any.buf) |
|
defer any.cfg.ReturnIterator(iter) |
|
valueBytes := locateArrayElement(iter, firstPath) |
|
if valueBytes == nil { |
|
return newInvalidAny(path) |
|
} |
|
iter.ResetBytes(valueBytes) |
|
return locatePath(iter, path[1:]) |
|
case int32: |
|
if '*' == firstPath { |
|
iter := any.cfg.BorrowIterator(any.buf) |
|
defer any.cfg.ReturnIterator(iter) |
|
arr := make([]Any, 0) |
|
iter.ReadArrayCB(func(iter *Iterator) bool { |
|
found := iter.readAny().Get(path[1:]...) |
|
if found.ValueType() != InvalidValue { |
|
arr = append(arr, found) |
|
} |
|
return true |
|
}) |
|
return wrapArray(arr) |
|
} |
|
return newInvalidAny(path) |
|
default: |
|
return newInvalidAny(path) |
|
} |
|
} |
|
|
|
func (any *arrayLazyAny) Size() int { |
|
size := 0 |
|
iter := any.cfg.BorrowIterator(any.buf) |
|
defer any.cfg.ReturnIterator(iter) |
|
iter.ReadArrayCB(func(iter *Iterator) bool { |
|
size++ |
|
iter.Skip() |
|
return true |
|
}) |
|
return size |
|
} |
|
|
|
func (any *arrayLazyAny) WriteTo(stream *Stream) { |
|
stream.Write(any.buf) |
|
} |
|
|
|
func (any *arrayLazyAny) GetInterface() interface{} { |
|
iter := any.cfg.BorrowIterator(any.buf) |
|
defer any.cfg.ReturnIterator(iter) |
|
return iter.Read() |
|
} |
|
|
|
type arrayAny struct { |
|
baseAny |
|
val reflect.Value |
|
} |
|
|
|
func wrapArray(val interface{}) *arrayAny { |
|
return &arrayAny{baseAny{}, reflect.ValueOf(val)} |
|
} |
|
|
|
func (any *arrayAny) ValueType() ValueType { |
|
return ArrayValue |
|
} |
|
|
|
func (any *arrayAny) MustBeValid() Any { |
|
return any |
|
} |
|
|
|
func (any *arrayAny) LastError() error { |
|
return nil |
|
} |
|
|
|
func (any *arrayAny) ToBool() bool { |
|
return any.val.Len() != 0 |
|
} |
|
|
|
func (any *arrayAny) ToInt() int { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToInt32() int32 { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToInt64() int64 { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToUint() uint { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToUint32() uint32 { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToUint64() uint64 { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToFloat32() float32 { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToFloat64() float64 { |
|
if any.val.Len() == 0 { |
|
return 0 |
|
} |
|
return 1 |
|
} |
|
|
|
func (any *arrayAny) ToString() string { |
|
str, _ := MarshalToString(any.val.Interface()) |
|
return str |
|
} |
|
|
|
func (any *arrayAny) Get(path ...interface{}) Any { |
|
if len(path) == 0 { |
|
return any |
|
} |
|
switch firstPath := path[0].(type) { |
|
case int: |
|
if firstPath < 0 || firstPath >= any.val.Len() { |
|
return newInvalidAny(path) |
|
} |
|
return Wrap(any.val.Index(firstPath).Interface()) |
|
case int32: |
|
if '*' == firstPath { |
|
mappedAll := make([]Any, 0) |
|
for i := 0; i < any.val.Len(); i++ { |
|
mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) |
|
if mapped.ValueType() != InvalidValue { |
|
mappedAll = append(mappedAll, mapped) |
|
} |
|
} |
|
return wrapArray(mappedAll) |
|
} |
|
return newInvalidAny(path) |
|
default: |
|
return newInvalidAny(path) |
|
} |
|
} |
|
|
|
func (any *arrayAny) Size() int { |
|
return any.val.Len() |
|
} |
|
|
|
func (any *arrayAny) WriteTo(stream *Stream) { |
|
stream.WriteVal(any.val) |
|
} |
|
|
|
func (any *arrayAny) GetInterface() interface{} { |
|
return any.val.Interface() |
|
}
|
|
|