blob: fd52690c941056270345e694959453679ca7706a [file] [log] [blame]
khenaidooffe076b2019-01-15 16:08:08 -05001// +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// }