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() }