reflect_map.go raw
1 package jsoniter
2
3 import (
4 "fmt"
5 "io"
6 "reflect"
7 "sort"
8 "unsafe"
9
10 "github.com/modern-go/reflect2"
11 )
12
13 func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
14 mapType := typ.(*reflect2.UnsafeMapType)
15 keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key())
16 elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem())
17 return &mapDecoder{
18 mapType: mapType,
19 keyType: mapType.Key(),
20 elemType: mapType.Elem(),
21 keyDecoder: keyDecoder,
22 elemDecoder: elemDecoder,
23 }
24 }
25
26 func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
27 mapType := typ.(*reflect2.UnsafeMapType)
28 if ctx.sortMapKeys {
29 return &sortKeysMapEncoder{
30 mapType: mapType,
31 keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
32 elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
33 }
34 }
35 return &mapEncoder{
36 mapType: mapType,
37 keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
38 elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
39 }
40 }
41
42 func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
43 decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ)
44 if decoder != nil {
45 return decoder
46 }
47 for _, extension := range ctx.extraExtensions {
48 decoder := extension.CreateMapKeyDecoder(typ)
49 if decoder != nil {
50 return decoder
51 }
52 }
53
54 ptrType := reflect2.PtrTo(typ)
55 if ptrType.Implements(unmarshalerType) {
56 return &referenceDecoder{
57 &unmarshalerDecoder{
58 valType: ptrType,
59 },
60 }
61 }
62 if typ.Implements(unmarshalerType) {
63 return &unmarshalerDecoder{
64 valType: typ,
65 }
66 }
67 if ptrType.Implements(textUnmarshalerType) {
68 return &referenceDecoder{
69 &textUnmarshalerDecoder{
70 valType: ptrType,
71 },
72 }
73 }
74 if typ.Implements(textUnmarshalerType) {
75 return &textUnmarshalerDecoder{
76 valType: typ,
77 }
78 }
79
80 switch typ.Kind() {
81 case reflect.String:
82 return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
83 case reflect.Bool,
84 reflect.Uint8, reflect.Int8,
85 reflect.Uint16, reflect.Int16,
86 reflect.Uint32, reflect.Int32,
87 reflect.Uint64, reflect.Int64,
88 reflect.Uint, reflect.Int,
89 reflect.Float32, reflect.Float64,
90 reflect.Uintptr:
91 typ = reflect2.DefaultTypeOfKind(typ.Kind())
92 return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
93 default:
94 return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
95 }
96 }
97
98 func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
99 encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
100 if encoder != nil {
101 return encoder
102 }
103 for _, extension := range ctx.extraExtensions {
104 encoder := extension.CreateMapKeyEncoder(typ)
105 if encoder != nil {
106 return encoder
107 }
108 }
109
110 if typ.Kind() != reflect.String {
111 if typ == textMarshalerType {
112 return &directTextMarshalerEncoder{
113 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
114 }
115 }
116 if typ.Implements(textMarshalerType) {
117 return &textMarshalerEncoder{
118 valType: typ,
119 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
120 }
121 }
122 }
123
124 switch typ.Kind() {
125 case reflect.String:
126 return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
127 case reflect.Bool,
128 reflect.Uint8, reflect.Int8,
129 reflect.Uint16, reflect.Int16,
130 reflect.Uint32, reflect.Int32,
131 reflect.Uint64, reflect.Int64,
132 reflect.Uint, reflect.Int,
133 reflect.Float32, reflect.Float64,
134 reflect.Uintptr:
135 typ = reflect2.DefaultTypeOfKind(typ.Kind())
136 return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
137 default:
138 if typ.Kind() == reflect.Interface {
139 return &dynamicMapKeyEncoder{ctx, typ}
140 }
141 return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
142 }
143 }
144
145 type mapDecoder struct {
146 mapType *reflect2.UnsafeMapType
147 keyType reflect2.Type
148 elemType reflect2.Type
149 keyDecoder ValDecoder
150 elemDecoder ValDecoder
151 }
152
153 func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
154 mapType := decoder.mapType
155 c := iter.nextToken()
156 if c == 'n' {
157 iter.skipThreeBytes('u', 'l', 'l')
158 *(*unsafe.Pointer)(ptr) = nil
159 mapType.UnsafeSet(ptr, mapType.UnsafeNew())
160 return
161 }
162 if mapType.UnsafeIsNil(ptr) {
163 mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
164 }
165 if c != '{' {
166 iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
167 return
168 }
169 c = iter.nextToken()
170 if c == '}' {
171 return
172 }
173 iter.unreadByte()
174 key := decoder.keyType.UnsafeNew()
175 decoder.keyDecoder.Decode(key, iter)
176 c = iter.nextToken()
177 if c != ':' {
178 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
179 return
180 }
181 elem := decoder.elemType.UnsafeNew()
182 decoder.elemDecoder.Decode(elem, iter)
183 decoder.mapType.UnsafeSetIndex(ptr, key, elem)
184 for c = iter.nextToken(); c == ','; c = iter.nextToken() {
185 key := decoder.keyType.UnsafeNew()
186 decoder.keyDecoder.Decode(key, iter)
187 c = iter.nextToken()
188 if c != ':' {
189 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
190 return
191 }
192 elem := decoder.elemType.UnsafeNew()
193 decoder.elemDecoder.Decode(elem, iter)
194 decoder.mapType.UnsafeSetIndex(ptr, key, elem)
195 }
196 if c != '}' {
197 iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
198 }
199 }
200
201 type numericMapKeyDecoder struct {
202 decoder ValDecoder
203 }
204
205 func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
206 c := iter.nextToken()
207 if c != '"' {
208 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
209 return
210 }
211 decoder.decoder.Decode(ptr, iter)
212 c = iter.nextToken()
213 if c != '"' {
214 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
215 return
216 }
217 }
218
219 type numericMapKeyEncoder struct {
220 encoder ValEncoder
221 }
222
223 func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
224 stream.writeByte('"')
225 encoder.encoder.Encode(ptr, stream)
226 stream.writeByte('"')
227 }
228
229 func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
230 return false
231 }
232
233 type dynamicMapKeyEncoder struct {
234 ctx *ctx
235 valType reflect2.Type
236 }
237
238 func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
239 obj := encoder.valType.UnsafeIndirect(ptr)
240 encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
241 }
242
243 func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
244 obj := encoder.valType.UnsafeIndirect(ptr)
245 return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
246 }
247
248 type mapEncoder struct {
249 mapType *reflect2.UnsafeMapType
250 keyEncoder ValEncoder
251 elemEncoder ValEncoder
252 }
253
254 func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
255 if *(*unsafe.Pointer)(ptr) == nil {
256 stream.WriteNil()
257 return
258 }
259 stream.WriteObjectStart()
260 iter := encoder.mapType.UnsafeIterate(ptr)
261 for i := 0; iter.HasNext(); i++ {
262 if i != 0 {
263 stream.WriteMore()
264 }
265 key, elem := iter.UnsafeNext()
266 encoder.keyEncoder.Encode(key, stream)
267 if stream.indention > 0 {
268 stream.writeTwoBytes(byte(':'), byte(' '))
269 } else {
270 stream.writeByte(':')
271 }
272 encoder.elemEncoder.Encode(elem, stream)
273 }
274 stream.WriteObjectEnd()
275 }
276
277 func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
278 iter := encoder.mapType.UnsafeIterate(ptr)
279 return !iter.HasNext()
280 }
281
282 type sortKeysMapEncoder struct {
283 mapType *reflect2.UnsafeMapType
284 keyEncoder ValEncoder
285 elemEncoder ValEncoder
286 }
287
288 func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
289 if *(*unsafe.Pointer)(ptr) == nil {
290 stream.WriteNil()
291 return
292 }
293 stream.WriteObjectStart()
294 mapIter := encoder.mapType.UnsafeIterate(ptr)
295 subStream := stream.cfg.BorrowStream(nil)
296 subStream.Attachment = stream.Attachment
297 subIter := stream.cfg.BorrowIterator(nil)
298 keyValues := encodedKeyValues{}
299 for mapIter.HasNext() {
300 key, elem := mapIter.UnsafeNext()
301 subStreamIndex := subStream.Buffered()
302 encoder.keyEncoder.Encode(key, subStream)
303 if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
304 stream.Error = subStream.Error
305 }
306 encodedKey := subStream.Buffer()[subStreamIndex:]
307 subIter.ResetBytes(encodedKey)
308 decodedKey := subIter.ReadString()
309 if stream.indention > 0 {
310 subStream.writeTwoBytes(byte(':'), byte(' '))
311 } else {
312 subStream.writeByte(':')
313 }
314 encoder.elemEncoder.Encode(elem, subStream)
315 keyValues = append(keyValues, encodedKV{
316 key: decodedKey,
317 keyValue: subStream.Buffer()[subStreamIndex:],
318 })
319 }
320 sort.Sort(keyValues)
321 for i, keyValue := range keyValues {
322 if i != 0 {
323 stream.WriteMore()
324 }
325 stream.Write(keyValue.keyValue)
326 }
327 if subStream.Error != nil && stream.Error == nil {
328 stream.Error = subStream.Error
329 }
330 stream.WriteObjectEnd()
331 stream.cfg.ReturnStream(subStream)
332 stream.cfg.ReturnIterator(subIter)
333 }
334
335 func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
336 iter := encoder.mapType.UnsafeIterate(ptr)
337 return !iter.HasNext()
338 }
339
340 type encodedKeyValues []encodedKV
341
342 type encodedKV struct {
343 key string
344 keyValue []byte
345 }
346
347 func (sv encodedKeyValues) Len() int { return len(sv) }
348 func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
349 func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }
350