github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/any_array.go (about) 1 package jsoni 2 3 import ( 4 "context" 5 "reflect" 6 "unsafe" 7 ) 8 9 type arrayLazyAny struct { 10 baseAny 11 cfg *frozenConfig 12 buf []byte 13 err error 14 } 15 16 func (a *arrayLazyAny) ValueType() ValueType { return ArrayValue } 17 func (a *arrayLazyAny) MustBeValid() Any { return a } 18 func (a *arrayLazyAny) LastError() error { return a.err } 19 func (a *arrayLazyAny) ToBool() bool { 20 iter := a.cfg.BorrowIterator(a.buf) 21 defer a.cfg.ReturnIterator(iter) 22 return iter.ReadArray() 23 } 24 25 func (a *arrayLazyAny) ToInt() int { 26 if a.ToBool() { 27 return 1 28 } 29 return 0 30 } 31 32 func (a *arrayLazyAny) ToInt32() int32 { return int32(a.ToInt()) } 33 func (a *arrayLazyAny) ToInt64() int64 { return int64(a.ToInt()) } 34 func (a *arrayLazyAny) ToUint() uint { return uint(a.ToInt()) } 35 func (a *arrayLazyAny) ToUint32() uint32 { return uint32(a.ToInt()) } 36 func (a *arrayLazyAny) ToUint64() uint64 { return uint64(a.ToInt()) } 37 func (a *arrayLazyAny) ToFloat32() float32 { return float32(a.ToInt()) } 38 func (a *arrayLazyAny) ToFloat64() float64 { return float64(a.ToInt()) } 39 func (a *arrayLazyAny) ToString() string { return *(*string)(unsafe.Pointer(&a.buf)) } 40 41 func (a *arrayLazyAny) ToVal(ctx context.Context, val interface{}) { 42 iter := a.cfg.BorrowIterator(a.buf) 43 defer a.cfg.ReturnIterator(iter) 44 iter.ReadVal(ctx, val) 45 } 46 47 func (a *arrayLazyAny) Get(path ...interface{}) Any { 48 if len(path) == 0 { 49 return a 50 } 51 switch firstPath := path[0].(type) { 52 case int: 53 iter := a.cfg.BorrowIterator(a.buf) 54 defer a.cfg.ReturnIterator(iter) 55 valueBytes := locateArrayElement(iter, firstPath) 56 if valueBytes == nil { 57 return newInvalidAny(path) 58 } 59 iter.ResetBytes(valueBytes) 60 return locatePath(iter, path[1:]) 61 case int32: 62 if '*' == firstPath { 63 iter := a.cfg.BorrowIterator(a.buf) 64 defer a.cfg.ReturnIterator(iter) 65 arr := make([]Any, 0) 66 iter.ReadArrayCB(func(iter *Iterator) bool { 67 found := iter.readAny().Get(path[1:]...) 68 if found.ValueType() != InvalidValue { 69 arr = append(arr, found) 70 } 71 return true 72 }) 73 return wrapArray(arr) 74 } 75 return newInvalidAny(path) 76 default: 77 return newInvalidAny(path) 78 } 79 } 80 81 func (a *arrayLazyAny) Size() int { 82 size := 0 83 iter := a.cfg.BorrowIterator(a.buf) 84 defer a.cfg.ReturnIterator(iter) 85 iter.ReadArrayCB(func(iter *Iterator) bool { 86 size++ 87 iter.Skip() 88 return true 89 }) 90 return size 91 } 92 93 func (a *arrayLazyAny) WriteTo(ctx context.Context, stream *Stream) { stream.Write(a.buf) } 94 95 func (a *arrayLazyAny) GetInterface(ctx context.Context) interface{} { 96 iter := a.cfg.BorrowIterator(a.buf) 97 defer a.cfg.ReturnIterator(iter) 98 return iter.Read(ctx) 99 } 100 101 type arrayAny struct { 102 baseAny 103 val reflect.Value 104 } 105 106 func wrapArray(val interface{}) *arrayAny { 107 return &arrayAny{baseAny{}, reflect.ValueOf(val)} 108 } 109 110 func (a *arrayAny) ValueType() ValueType { return ArrayValue } 111 func (a *arrayAny) MustBeValid() Any { return a } 112 func (a *arrayAny) LastError() error { return nil } 113 func (a *arrayAny) ToBool() bool { return a.val.Len() != 0 } 114 func (a *arrayAny) ToInt() int { 115 if a.val.Len() == 0 { 116 return 0 117 } 118 return 1 119 } 120 121 func (a *arrayAny) ToInt32() int32 { return int32(a.ToInt()) } 122 func (a *arrayAny) ToInt64() int64 { return int64(a.ToInt()) } 123 func (a *arrayAny) ToUint() uint { return uint(a.ToInt()) } 124 func (a *arrayAny) ToUint32() uint32 { return uint32(a.ToInt()) } 125 func (a *arrayAny) ToUint64() uint64 { return uint64(a.ToInt()) } 126 func (a *arrayAny) ToFloat32() float32 { return float32(a.ToInt()) } 127 func (a *arrayAny) ToFloat64() float64 { return float64(a.ToInt()) } 128 129 func (a *arrayAny) ToString() string { 130 str, _ := MarshalToString(a.val.Interface()) 131 return str 132 } 133 134 func (a *arrayAny) Get(path ...interface{}) Any { 135 if len(path) == 0 { 136 return a 137 } 138 switch firstPath := path[0].(type) { 139 case int: 140 if firstPath < 0 || firstPath >= a.val.Len() { 141 return newInvalidAny(path) 142 } 143 return Wrap(a.val.Index(firstPath).Interface()) 144 case int32: 145 if '*' == firstPath { 146 mappedAll := make([]Any, 0) 147 for i := 0; i < a.val.Len(); i++ { 148 mapped := Wrap(a.val.Index(i).Interface()).Get(path[1:]...) 149 if mapped.ValueType() != InvalidValue { 150 mappedAll = append(mappedAll, mapped) 151 } 152 } 153 return wrapArray(mappedAll) 154 } 155 return newInvalidAny(path) 156 default: 157 return newInvalidAny(path) 158 } 159 } 160 161 func (a *arrayAny) Size() int { return a.val.Len() } 162 func (a *arrayAny) WriteTo(ctx context.Context, stream *Stream) { stream.WriteVal(ctx, a.val) } 163 func (a *arrayAny) GetInterface(context.Context) interface{} { return a.val.Interface() }