any.go raw

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