123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- // +build !go1.7 safe appengine
- // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
- // Use of this source code is governed by a MIT license found in the LICENSE file.
- package codec
- import (
- "reflect"
- "sync/atomic"
- "time"
- )
- const safeMode = true
- // stringView returns a view of the []byte as a string.
- // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
- // In regular safe mode, it is an allocation and copy.
- //
- // Usage: Always maintain a reference to v while result of this call is in use,
- // and call keepAlive4BytesView(v) at point where done with view.
- func stringView(v []byte) string {
- return string(v)
- }
- // bytesView returns a view of the string as a []byte.
- // In unsafe mode, it doesn't incur allocation and copying caused by conversion.
- // In regular safe mode, it is an allocation and copy.
- //
- // Usage: Always maintain a reference to v while result of this call is in use,
- // and call keepAlive4BytesView(v) at point where done with view.
- func bytesView(v string) []byte {
- return []byte(v)
- }
- // isNil says whether the value v is nil.
- // This applies to references like map/ptr/unsafepointer/chan/func,
- // and non-reference values like interface/slice.
- func isNil(v interface{}) (rv reflect.Value, isnil bool) {
- rv = rv4i(v)
- if isnilBitset.isset(byte(rv.Kind())) {
- isnil = rv.IsNil()
- }
- return
- }
- func rv4i(i interface{}) reflect.Value {
- return reflect.ValueOf(i)
- }
- func rv2i(rv reflect.Value) interface{} {
- return rv.Interface()
- }
- func rvIsNil(rv reflect.Value) bool {
- return rv.IsNil()
- }
- func rvSetSliceLen(rv reflect.Value, length int) {
- rv.SetLen(length)
- }
- func rvZeroAddrK(t reflect.Type, k reflect.Kind) reflect.Value {
- return reflect.New(t).Elem()
- }
- func rvConvert(v reflect.Value, t reflect.Type) (rv reflect.Value) {
- return v.Convert(t)
- }
- func rt2id(rt reflect.Type) uintptr {
- return rv4i(rt).Pointer()
- }
- func i2rtid(i interface{}) uintptr {
- return rv4i(reflect.TypeOf(i)).Pointer()
- }
- // --------------------------
- func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
- switch v.Kind() {
- case reflect.Invalid:
- return true
- case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
- return v.Len() == 0
- case reflect.Bool:
- return !v.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return v.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return v.Float() == 0
- case reflect.Interface, reflect.Ptr:
- if deref {
- if v.IsNil() {
- return true
- }
- return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
- }
- return v.IsNil()
- case reflect.Struct:
- return isEmptyStruct(v, tinfos, deref, checkStruct)
- }
- return false
- }
- // --------------------------
- type atomicClsErr struct {
- v atomic.Value
- }
- func (x *atomicClsErr) load() (e clsErr) {
- if i := x.v.Load(); i != nil {
- e = i.(clsErr)
- }
- return
- }
- func (x *atomicClsErr) store(p clsErr) {
- x.v.Store(p)
- }
- // --------------------------
- type atomicTypeInfoSlice struct { // expected to be 2 words
- v atomic.Value
- }
- func (x *atomicTypeInfoSlice) load() (e []rtid2ti) {
- if i := x.v.Load(); i != nil {
- e = i.([]rtid2ti)
- }
- return
- }
- func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
- x.v.Store(p)
- }
- // --------------------------
- type atomicRtidFnSlice struct { // expected to be 2 words
- v atomic.Value
- }
- func (x *atomicRtidFnSlice) load() (e []codecRtidFn) {
- if i := x.v.Load(); i != nil {
- e = i.([]codecRtidFn)
- }
- return
- }
- func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
- x.v.Store(p)
- }
- // --------------------------
- func (n *fauxUnion) ru() reflect.Value {
- return rv4i(&n.u).Elem()
- }
- func (n *fauxUnion) ri() reflect.Value {
- return rv4i(&n.i).Elem()
- }
- func (n *fauxUnion) rf() reflect.Value {
- return rv4i(&n.f).Elem()
- }
- func (n *fauxUnion) rl() reflect.Value {
- return rv4i(&n.l).Elem()
- }
- func (n *fauxUnion) rs() reflect.Value {
- return rv4i(&n.s).Elem()
- }
- func (n *fauxUnion) rt() reflect.Value {
- return rv4i(&n.t).Elem()
- }
- func (n *fauxUnion) rb() reflect.Value {
- return rv4i(&n.b).Elem()
- }
- // --------------------------
- func rvSetBytes(rv reflect.Value, v []byte) {
- rv.SetBytes(v)
- }
- func rvSetString(rv reflect.Value, v string) {
- rv.SetString(v)
- }
- func rvSetBool(rv reflect.Value, v bool) {
- rv.SetBool(v)
- }
- func rvSetTime(rv reflect.Value, v time.Time) {
- rv.Set(rv4i(v))
- }
- func rvSetFloat32(rv reflect.Value, v float32) {
- rv.SetFloat(float64(v))
- }
- func rvSetFloat64(rv reflect.Value, v float64) {
- rv.SetFloat(v)
- }
- func rvSetInt(rv reflect.Value, v int) {
- rv.SetInt(int64(v))
- }
- func rvSetInt8(rv reflect.Value, v int8) {
- rv.SetInt(int64(v))
- }
- func rvSetInt16(rv reflect.Value, v int16) {
- rv.SetInt(int64(v))
- }
- func rvSetInt32(rv reflect.Value, v int32) {
- rv.SetInt(int64(v))
- }
- func rvSetInt64(rv reflect.Value, v int64) {
- rv.SetInt(v)
- }
- func rvSetUint(rv reflect.Value, v uint) {
- rv.SetUint(uint64(v))
- }
- func rvSetUintptr(rv reflect.Value, v uintptr) {
- rv.SetUint(uint64(v))
- }
- func rvSetUint8(rv reflect.Value, v uint8) {
- rv.SetUint(uint64(v))
- }
- func rvSetUint16(rv reflect.Value, v uint16) {
- rv.SetUint(uint64(v))
- }
- func rvSetUint32(rv reflect.Value, v uint32) {
- rv.SetUint(uint64(v))
- }
- func rvSetUint64(rv reflect.Value, v uint64) {
- rv.SetUint(v)
- }
- // ----------------
- // rvSetDirect is rv.Set for all kinds except reflect.Interface
- func rvSetDirect(rv reflect.Value, v reflect.Value) {
- rv.Set(v)
- }
- // rvSlice returns a slice of the slice of lenth
- func rvSlice(rv reflect.Value, length int) reflect.Value {
- return rv.Slice(0, length)
- }
- // ----------------
- func rvSliceIndex(rv reflect.Value, i int, ti *typeInfo) reflect.Value {
- return rv.Index(i)
- }
- func rvGetSliceLen(rv reflect.Value) int {
- return rv.Len()
- }
- func rvGetSliceCap(rv reflect.Value) int {
- return rv.Cap()
- }
- func rvGetArrayBytesRO(rv reflect.Value, scratch []byte) (bs []byte) {
- l := rv.Len()
- if rv.CanAddr() {
- return rvGetBytes(rv.Slice(0, l))
- }
- if l <= cap(scratch) {
- bs = scratch[:l]
- } else {
- bs = make([]byte, l)
- }
- reflect.Copy(rv4i(bs), rv)
- return
- }
- func rvGetArray4Slice(rv reflect.Value) (v reflect.Value) {
- v = rvZeroAddrK(reflectArrayOf(rvGetSliceLen(rv), rv.Type().Elem()), reflect.Array)
- reflect.Copy(v, rv)
- return
- }
- func rvGetSlice4Array(rv reflect.Value, tslice reflect.Type) (v reflect.Value) {
- return rv.Slice(0, rv.Len())
- }
- func rvCopySlice(dest, src reflect.Value) {
- reflect.Copy(dest, src)
- }
- // ------------
- func rvGetBool(rv reflect.Value) bool {
- return rv.Bool()
- }
- func rvGetBytes(rv reflect.Value) []byte {
- return rv.Bytes()
- }
- func rvGetTime(rv reflect.Value) time.Time {
- return rv2i(rv).(time.Time)
- }
- func rvGetString(rv reflect.Value) string {
- return rv.String()
- }
- func rvGetFloat64(rv reflect.Value) float64 {
- return rv.Float()
- }
- func rvGetFloat32(rv reflect.Value) float32 {
- return float32(rv.Float())
- }
- func rvGetInt(rv reflect.Value) int {
- return int(rv.Int())
- }
- func rvGetInt8(rv reflect.Value) int8 {
- return int8(rv.Int())
- }
- func rvGetInt16(rv reflect.Value) int16 {
- return int16(rv.Int())
- }
- func rvGetInt32(rv reflect.Value) int32 {
- return int32(rv.Int())
- }
- func rvGetInt64(rv reflect.Value) int64 {
- return rv.Int()
- }
- func rvGetUint(rv reflect.Value) uint {
- return uint(rv.Uint())
- }
- func rvGetUint8(rv reflect.Value) uint8 {
- return uint8(rv.Uint())
- }
- func rvGetUint16(rv reflect.Value) uint16 {
- return uint16(rv.Uint())
- }
- func rvGetUint32(rv reflect.Value) uint32 {
- return uint32(rv.Uint())
- }
- func rvGetUint64(rv reflect.Value) uint64 {
- return rv.Uint()
- }
- func rvGetUintptr(rv reflect.Value) uintptr {
- return uintptr(rv.Uint())
- }
- // ------------ map range and map indexing ----------
- func mapGet(m, k, v reflect.Value) (vv reflect.Value) {
- return m.MapIndex(k)
- }
- func mapSet(m, k, v reflect.Value) {
- m.SetMapIndex(k, v)
- }
- func mapDelete(m, k reflect.Value) {
- m.SetMapIndex(k, reflect.Value{})
- }
- // return an addressable reflect value that can be used in mapRange and mapGet operations.
- //
- // all calls to mapGet or mapRange will call here to get an addressable reflect.Value.
- func mapAddressableRV(t reflect.Type, k reflect.Kind) (r reflect.Value) {
- return // reflect.New(t).Elem()
- }
- // ---------- ENCODER optimized ---------------
- func (e *Encoder) jsondriver() *jsonEncDriver {
- return e.e.(*jsonEncDriver)
- }
- // ---------- DECODER optimized ---------------
- func (d *Decoder) checkBreak() bool {
- return d.d.CheckBreak()
- }
- func (d *Decoder) jsondriver() *jsonDecDriver {
- return d.d.(*jsonDecDriver)
- }
|