-
Notifications
You must be signed in to change notification settings - Fork 5
/
encode_cache.go
104 lines (92 loc) · 2.53 KB
/
encode_cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package qs
import (
"reflect"
"sync"
)
type cacheStore struct {
m map[reflect.Type]cachedFields
mutex sync.RWMutex
}
func newCacheStore() *cacheStore {
return &cacheStore{
m: make(map[reflect.Type]cachedFields),
}
}
// Retrieve cachedFields corresponding to reflect.Type
func (cacheStore *cacheStore) Retrieve(typ reflect.Type) cachedFields {
return cacheStore.m[typ]
}
// Store func stores cachedFields that corresponds to reflect.Type
func (cacheStore *cacheStore) Store(typ reflect.Type, cachedFields cachedFields) {
cacheStore.mutex.Lock()
defer cacheStore.mutex.Unlock()
if _, ok := cacheStore.m[typ]; !ok {
cacheStore.m[typ] = cachedFields
}
}
type (
resultFunc func(name string, val string)
// cachedField
cachedField interface {
formatFnc(value reflect.Value, result resultFunc) error
}
cachedFields []cachedField
)
func newCacheFieldByType(typ reflect.Type, tagName []byte, tagOptions [][]byte) cachedField {
if typ.Implements(encoderType) {
return newCustomField(typ, tagName, tagOptions)
}
switch typ {
case timeType:
return newTimeField(tagName, tagOptions)
default:
return newCachedFieldByKind(typ.Kind(), tagName, tagOptions)
}
}
func newCachedFieldByKind(kind reflect.Kind, tagName []byte, tagOptions [][]byte) cachedField {
switch kind {
case reflect.String:
return newStringField(tagName, tagOptions)
case reflect.Bool:
return newBoolField(tagName, tagOptions)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return newIntField(tagName, tagOptions)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return newUintField(tagName, tagOptions)
case reflect.Float32:
return newFloat32Field(tagName, tagOptions)
case reflect.Float64:
return newFloat64Field(tagName, tagOptions)
case reflect.Complex64:
return newComplex64Field(tagName, tagOptions)
case reflect.Complex128:
return newComplex128Field(tagName, tagOptions)
case reflect.Struct:
return newEmbedField(0, tagName, tagOptions)
case reflect.Interface:
return newInterfaceField(tagName, tagOptions)
default:
return nil
}
}
func getType(fieldVal reflect.Value) reflect.Type {
stFieldTyp := fieldVal.Type()
for fieldVal.Kind() == reflect.Ptr {
fieldVal = fieldVal.Elem()
stFieldTyp = stFieldTyp.Elem()
}
return stFieldTyp
}
func countElem(value reflect.Value) int {
count := 0
for i := 0; i < value.Len(); i++ {
elem := value.Index(i)
for elem.Kind() == reflect.Ptr {
elem = elem.Elem()
}
if elem.IsValid() {
count++
}
}
return count
}