1// +build !go1.7 safe appengine 2 3// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved. 4// Use of this source code is governed by a MIT license found in the LICENSE file. 5 6package codec 7 8import ( 9 "reflect" 10 "sync/atomic" 11 "time" 12) 13 14const safeMode = true 15 16// stringView returns a view of the []byte as a string. 17// In unsafe mode, it doesn't incur allocation and copying caused by conversion. 18// In regular safe mode, it is an allocation and copy. 19// 20// Usage: Always maintain a reference to v while result of this call is in use, 21// and call keepAlive4BytesView(v) at point where done with view. 22func stringView(v []byte) string { 23 return string(v) 24} 25 26// bytesView returns a view of the string as a []byte. 27// In unsafe mode, it doesn't incur allocation and copying caused by conversion. 28// In regular safe mode, it is an allocation and copy. 29// 30// Usage: Always maintain a reference to v while result of this call is in use, 31// and call keepAlive4BytesView(v) at point where done with view. 32func bytesView(v string) []byte { 33 return []byte(v) 34} 35 36func definitelyNil(v interface{}) bool { 37 // this is a best-effort option. 38 // We just return false, so we don't unnecessarily incur the cost of reflection this early. 39 return false 40} 41 42func rv2i(rv reflect.Value) interface{} { 43 return rv.Interface() 44} 45 46func rt2id(rt reflect.Type) uintptr { 47 return reflect.ValueOf(rt).Pointer() 48} 49 50func rv2rtid(rv reflect.Value) uintptr { 51 return reflect.ValueOf(rv.Type()).Pointer() 52} 53 54func i2rtid(i interface{}) uintptr { 55 return reflect.ValueOf(reflect.TypeOf(i)).Pointer() 56} 57 58// -------------------------- 59 60func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool { 61 switch v.Kind() { 62 case reflect.Invalid: 63 return true 64 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 65 return v.Len() == 0 66 case reflect.Bool: 67 return !v.Bool() 68 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 69 return v.Int() == 0 70 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 71 return v.Uint() == 0 72 case reflect.Float32, reflect.Float64: 73 return v.Float() == 0 74 case reflect.Interface, reflect.Ptr: 75 if deref { 76 if v.IsNil() { 77 return true 78 } 79 return isEmptyValue(v.Elem(), tinfos, deref, checkStruct) 80 } 81 return v.IsNil() 82 case reflect.Struct: 83 return isEmptyStruct(v, tinfos, deref, checkStruct) 84 } 85 return false 86} 87 88// -------------------------- 89// type ptrToRvMap struct{} 90 91// func (*ptrToRvMap) init() {} 92// func (*ptrToRvMap) get(i interface{}) reflect.Value { 93// return reflect.ValueOf(i).Elem() 94// } 95 96// -------------------------- 97type atomicTypeInfoSlice struct { // expected to be 2 words 98 v atomic.Value 99} 100 101func (x *atomicTypeInfoSlice) load() []rtid2ti { 102 i := x.v.Load() 103 if i == nil { 104 return nil 105 } 106 return i.([]rtid2ti) 107} 108 109func (x *atomicTypeInfoSlice) store(p []rtid2ti) { 110 x.v.Store(p) 111} 112 113// -------------------------- 114func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) { 115 rv.SetBytes(d.rawBytes()) 116} 117 118func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) { 119 rv.SetString(d.d.DecodeString()) 120} 121 122func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) { 123 rv.SetBool(d.d.DecodeBool()) 124} 125 126func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) { 127 rv.Set(reflect.ValueOf(d.d.DecodeTime())) 128} 129 130func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) { 131 fv := d.d.DecodeFloat64() 132 if chkOvf.Float32(fv) { 133 d.errorf("float32 overflow: %v", fv) 134 } 135 rv.SetFloat(fv) 136} 137 138func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) { 139 rv.SetFloat(d.d.DecodeFloat64()) 140} 141 142func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) { 143 rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize)) 144} 145 146func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) { 147 rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8)) 148} 149 150func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) { 151 rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16)) 152} 153 154func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) { 155 rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32)) 156} 157 158func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) { 159 rv.SetInt(d.d.DecodeInt64()) 160} 161 162func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) { 163 rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize)) 164} 165 166func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) { 167 rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize)) 168} 169 170func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) { 171 rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8)) 172} 173 174func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) { 175 rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16)) 176} 177 178func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) { 179 rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32)) 180} 181 182func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) { 183 rv.SetUint(d.d.DecodeUint64()) 184} 185 186// ---------------- 187 188func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) { 189 e.e.EncodeBool(rv.Bool()) 190} 191 192func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) { 193 e.e.EncodeTime(rv2i(rv).(time.Time)) 194} 195 196func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) { 197 e.e.EncodeString(cUTF8, rv.String()) 198} 199 200func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) { 201 e.e.EncodeFloat64(rv.Float()) 202} 203 204func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) { 205 e.e.EncodeFloat32(float32(rv.Float())) 206} 207 208func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) { 209 e.e.EncodeInt(rv.Int()) 210} 211 212func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) { 213 e.e.EncodeInt(rv.Int()) 214} 215 216func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) { 217 e.e.EncodeInt(rv.Int()) 218} 219 220func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) { 221 e.e.EncodeInt(rv.Int()) 222} 223 224func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) { 225 e.e.EncodeInt(rv.Int()) 226} 227 228func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) { 229 e.e.EncodeUint(rv.Uint()) 230} 231 232func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) { 233 e.e.EncodeUint(rv.Uint()) 234} 235 236func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) { 237 e.e.EncodeUint(rv.Uint()) 238} 239 240func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) { 241 e.e.EncodeUint(rv.Uint()) 242} 243 244func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) { 245 e.e.EncodeUint(rv.Uint()) 246} 247 248func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) { 249 e.e.EncodeUint(rv.Uint()) 250} 251 252// // keepAlive4BytesView maintains a reference to the input parameter for bytesView. 253// // 254// // Usage: call this at point where done with the bytes view. 255// func keepAlive4BytesView(v string) {} 256 257// // keepAlive4BytesView maintains a reference to the input parameter for stringView. 258// // 259// // Usage: call this at point where done with the string view. 260// func keepAlive4StringView(v []byte) {} 261 262// func definitelyNil(v interface{}) bool { 263// rv := reflect.ValueOf(v) 264// switch rv.Kind() { 265// case reflect.Invalid: 266// return true 267// case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func: 268// return rv.IsNil() 269// default: 270// return false 271// } 272// } 273