helper_not_unsafe.go

  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// }