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