github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/any.go (about)

     1  package jsoni
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"reflect"
     9  	"strconv"
    10  	"unsafe"
    11  
    12  	"github.com/modern-go/reflect2"
    13  )
    14  
    15  // Any generic object representation.
    16  // The lazy json implementation holds []byte and parse lazily.
    17  type Any interface {
    18  	LastError() error
    19  	ValueType() ValueType
    20  	MustBeValid() Any
    21  	ToBool() bool
    22  	ToInt() int
    23  	ToInt32() int32
    24  	ToInt64() int64
    25  	ToUint() uint
    26  	ToUint32() uint32
    27  	ToUint64() uint64
    28  	ToFloat32() float32
    29  	ToFloat64() float64
    30  	ToString() string
    31  	ToVal(ctx context.Context, val interface{})
    32  	Get(path ...interface{}) Any
    33  	Size() int
    34  	Keys() []string
    35  	GetInterface(ctx context.Context) interface{}
    36  	WriteTo(ctx context.Context, stream *Stream)
    37  }
    38  
    39  type baseAny struct{}
    40  
    41  func (any *baseAny) Get(path ...interface{}) Any {
    42  	return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
    43  }
    44  
    45  func (any *baseAny) Size() int                          { return 0 }
    46  func (any *baseAny) Keys() []string                     { return []string{} }
    47  func (any *baseAny) ToVal(context.Context, interface{}) { panic("not implemented") }
    48  
    49  // WrapInt32 turn int32 into Any interface
    50  func WrapInt32(val int32) Any { return &int32Any{baseAny{}, val} }
    51  
    52  // WrapInt64 turn int64 into Any interface
    53  func WrapInt64(val int64) Any { return &int64Any{baseAny{}, val} }
    54  
    55  // WrapUint32 turn uint32 into Any interface
    56  func WrapUint32(val uint32) Any { return &uint32Any{baseAny{}, val} }
    57  
    58  // WrapUint64 turn uint64 into Any interface
    59  func WrapUint64(val uint64) Any { return &uint64Any{baseAny{}, val} }
    60  
    61  // WrapFloat64 turn float64 into Any interface
    62  func WrapFloat64(val float64) Any { return &floatAny{baseAny{}, val} }
    63  
    64  // WrapString turn string into Any interface
    65  func WrapString(val string) Any { return &stringAny{baseAny{}, val} }
    66  
    67  // Wrap turn a go object into Any interface
    68  func Wrap(val interface{}) Any {
    69  	if val == nil {
    70  		return &nilAny{}
    71  	}
    72  	asAny, isAny := val.(Any)
    73  	if isAny {
    74  		return asAny
    75  	}
    76  	typ := reflect2.TypeOf(val)
    77  	switch typ.Kind() {
    78  	case reflect.Slice:
    79  		return wrapArray(val)
    80  	case reflect.Struct:
    81  		return wrapStruct(val)
    82  	case reflect.Map:
    83  		return wrapMap(val)
    84  	case reflect.String:
    85  		return WrapString(val.(string))
    86  	case reflect.Int:
    87  		if strconv.IntSize == 32 {
    88  			return WrapInt32(int32(val.(int)))
    89  		}
    90  		return WrapInt64(int64(val.(int)))
    91  	case reflect.Int8:
    92  		return WrapInt32(int32(val.(int8)))
    93  	case reflect.Int16:
    94  		return WrapInt32(int32(val.(int16)))
    95  	case reflect.Int32:
    96  		return WrapInt32(val.(int32))
    97  	case reflect.Int64:
    98  		return WrapInt64(val.(int64))
    99  	case reflect.Uint:
   100  		if strconv.IntSize == 32 {
   101  			return WrapUint32(uint32(val.(uint)))
   102  		}
   103  		return WrapUint64(uint64(val.(uint)))
   104  	case reflect.Uintptr:
   105  		if ptrSize == 32 {
   106  			return WrapUint32(uint32(val.(uintptr)))
   107  		}
   108  		return WrapUint64(uint64(val.(uintptr)))
   109  	case reflect.Uint8:
   110  		return WrapUint32(uint32(val.(uint8)))
   111  	case reflect.Uint16:
   112  		return WrapUint32(uint32(val.(uint16)))
   113  	case reflect.Uint32:
   114  		return WrapUint32(val.(uint32))
   115  	case reflect.Uint64:
   116  		return WrapUint64(val.(uint64))
   117  	case reflect.Float32:
   118  		return WrapFloat64(float64(val.(float32)))
   119  	case reflect.Float64:
   120  		return WrapFloat64(val.(float64))
   121  	case reflect.Bool:
   122  		if val.(bool) == true {
   123  			return &trueAny{}
   124  		}
   125  		return &falseAny{}
   126  	}
   127  	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)}
   128  }
   129  
   130  // ReadAny read next JSON element as an Any object. It is a better json.RawMessage.
   131  func (iter *Iterator) ReadAny() Any {
   132  	return iter.readAny()
   133  }
   134  
   135  func (iter *Iterator) readAny() Any {
   136  	c := iter.nextToken()
   137  	switch c {
   138  	case '"':
   139  		iter.unreadByte()
   140  		return &stringAny{baseAny{}, iter.ReadString()}
   141  	case 'n':
   142  		iter.skip3Bytes('u', 'l', 'l') // null
   143  		return &nilAny{}
   144  	case 't':
   145  		iter.skip3Bytes('r', 'u', 'e') // true
   146  		return &trueAny{}
   147  	case 'f':
   148  		iter.skip4Bytes('a', 'l', 's', 'e') // false
   149  		return &falseAny{}
   150  	case '{':
   151  		return iter.readObjectAny()
   152  	case '[':
   153  		return iter.readArrayAny()
   154  	case '-':
   155  		return iter.readNumberAny(false)
   156  	case 0:
   157  		return &invalidAny{baseAny{}, errors.New("input is empty")}
   158  	default:
   159  		return iter.readNumberAny(true)
   160  	}
   161  }
   162  
   163  func (iter *Iterator) readNumberAny(positive bool) Any {
   164  	iter.startCapture(iter.head - 1)
   165  	iter.skipNumber()
   166  	lazyBuf := iter.stopCapture()
   167  	return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
   168  }
   169  
   170  func (iter *Iterator) readObjectAny() Any {
   171  	iter.startCapture(iter.head - 1)
   172  	iter.skipObject()
   173  	lazyBuf := iter.stopCapture()
   174  	return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
   175  }
   176  
   177  func (iter *Iterator) readArrayAny() Any {
   178  	iter.startCapture(iter.head - 1)
   179  	iter.skipArray()
   180  	lazyBuf := iter.stopCapture()
   181  	return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil}
   182  }
   183  
   184  func locateObjectField(iter *Iterator, target string) []byte {
   185  	var found []byte
   186  	iter.ReadObjectCB(func(iter *Iterator, field string) bool {
   187  		if field == target {
   188  			found = iter.SkipAndReturnBytes()
   189  			return false
   190  		}
   191  		iter.Skip()
   192  		return true
   193  	})
   194  	return found
   195  }
   196  
   197  func locateArrayElement(iter *Iterator, target int) []byte {
   198  	var found []byte
   199  	n := 0
   200  	iter.ReadArrayCB(func(iter *Iterator) bool {
   201  		if n == target {
   202  			found = iter.SkipAndReturnBytes()
   203  			return false
   204  		}
   205  		iter.Skip()
   206  		n++
   207  		return true
   208  	})
   209  	return found
   210  }
   211  
   212  func locatePath(iter *Iterator, path []interface{}) Any {
   213  	for i, pathKeyObj := range path {
   214  		switch pathKey := pathKeyObj.(type) {
   215  		case string:
   216  			valueBytes := locateObjectField(iter, pathKey)
   217  			if valueBytes == nil {
   218  				return newInvalidAny(path[i:])
   219  			}
   220  			iter.ResetBytes(valueBytes)
   221  		case int:
   222  			valueBytes := locateArrayElement(iter, pathKey)
   223  			if valueBytes == nil {
   224  				return newInvalidAny(path[i:])
   225  			}
   226  			iter.ResetBytes(valueBytes)
   227  		case int32:
   228  			if '*' == pathKey {
   229  				return iter.readAny().Get(path[i:]...)
   230  			}
   231  			return newInvalidAny(path[i:])
   232  		default:
   233  			return newInvalidAny(path[i:])
   234  		}
   235  	}
   236  	if iter.Error != nil && iter.Error != io.EOF {
   237  		return &invalidAny{baseAny{}, iter.Error}
   238  	}
   239  	return iter.readAny()
   240  }
   241  
   242  var anyType = PtrElem((*Any)(nil))
   243  
   244  func createDecoderOfAny(_ *ctx, typ reflect2.Type) ValDecoder {
   245  	if typ == anyType {
   246  		return &directAnyCodec{}
   247  	}
   248  	if typ.Implements(anyType) {
   249  		return &anyCodec{valType: typ}
   250  	}
   251  	return nil
   252  }
   253  
   254  func createEncoderOfAny(_ *ctx, typ reflect2.Type) ValEncoder {
   255  	if typ == anyType {
   256  		return &directAnyCodec{}
   257  	}
   258  	if typ.Implements(anyType) {
   259  		return &anyCodec{valType: typ}
   260  	}
   261  	return nil
   262  }
   263  
   264  type anyCodec struct {
   265  	valType reflect2.Type
   266  }
   267  
   268  func (c *anyCodec) Decode(context.Context, unsafe.Pointer, *Iterator) { panic("not implemented") }
   269  
   270  func (c *anyCodec) Encode(ctx context.Context, ptr unsafe.Pointer, stream *Stream) {
   271  	obj := c.valType.UnsafeIndirect(ptr)
   272  	any := obj.(Any)
   273  	any.WriteTo(ctx, stream)
   274  }
   275  
   276  func (c *anyCodec) IsEmpty(_ context.Context, ptr unsafe.Pointer, _ bool) bool {
   277  	obj := c.valType.UnsafeIndirect(ptr)
   278  	any := obj.(Any)
   279  	return any.Size() == 0
   280  }
   281  
   282  type directAnyCodec struct{}
   283  
   284  func (c *directAnyCodec) Decode(_ context.Context, ptr unsafe.Pointer, iter *Iterator) {
   285  	*(*Any)(ptr) = iter.readAny()
   286  }
   287  
   288  func (c *directAnyCodec) Encode(ctx context.Context, ptr unsafe.Pointer, stream *Stream) {
   289  	any := *(*Any)(ptr)
   290  	if any == nil {
   291  		stream.WriteNil()
   292  		return
   293  	}
   294  	any.WriteTo(ctx, stream)
   295  }
   296  
   297  func (c *directAnyCodec) IsEmpty(_ context.Context, ptr unsafe.Pointer, _ bool) bool {
   298  	any := *(*Any)(ptr)
   299  	return any.Size() == 0
   300  }