blob: 547b4421e349eab0223c88d59ee7924797021152 [file] [log] [blame]
sslobodrd046be82019-01-16 10:02:22 -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 }
52 switch typ.Kind() {
53 case reflect.String:
54 return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
55 case reflect.Bool,
56 reflect.Uint8, reflect.Int8,
57 reflect.Uint16, reflect.Int16,
58 reflect.Uint32, reflect.Int32,
59 reflect.Uint64, reflect.Int64,
60 reflect.Uint, reflect.Int,
61 reflect.Float32, reflect.Float64,
62 reflect.Uintptr:
63 typ = reflect2.DefaultTypeOfKind(typ.Kind())
64 return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
65 default:
66 ptrType := reflect2.PtrTo(typ)
William Kurkiandaa6bb22019-03-07 12:26:28 -050067 if ptrType.Implements(unmarshalerType) {
68 return &referenceDecoder{
69 &unmarshalerDecoder{
70 valType: ptrType,
71 },
72 }
73 }
74 if typ.Implements(unmarshalerType) {
75 return &unmarshalerDecoder{
76 valType: typ,
77 }
78 }
79 if ptrType.Implements(textUnmarshalerType) {
sslobodrd046be82019-01-16 10:02:22 -050080 return &referenceDecoder{
81 &textUnmarshalerDecoder{
82 valType: ptrType,
83 },
84 }
85 }
William Kurkiandaa6bb22019-03-07 12:26:28 -050086 if typ.Implements(textUnmarshalerType) {
sslobodrd046be82019-01-16 10:02:22 -050087 return &textUnmarshalerDecoder{
88 valType: typ,
89 }
90 }
91 return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
92 }
93}
94
95func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
96 encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
97 if encoder != nil {
98 return encoder
99 }
100 for _, extension := range ctx.extraExtensions {
101 encoder := extension.CreateMapKeyEncoder(typ)
102 if encoder != nil {
103 return encoder
104 }
105 }
106 switch typ.Kind() {
107 case reflect.String:
108 return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
109 case reflect.Bool,
110 reflect.Uint8, reflect.Int8,
111 reflect.Uint16, reflect.Int16,
112 reflect.Uint32, reflect.Int32,
113 reflect.Uint64, reflect.Int64,
114 reflect.Uint, reflect.Int,
115 reflect.Float32, reflect.Float64,
116 reflect.Uintptr:
117 typ = reflect2.DefaultTypeOfKind(typ.Kind())
118 return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
119 default:
120 if typ == textMarshalerType {
121 return &directTextMarshalerEncoder{
122 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
123 }
124 }
125 if typ.Implements(textMarshalerType) {
126 return &textMarshalerEncoder{
127 valType: typ,
128 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
129 }
130 }
131 if typ.Kind() == reflect.Interface {
132 return &dynamicMapKeyEncoder{ctx, typ}
133 }
134 return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
135 }
136}
137
138type mapDecoder struct {
139 mapType *reflect2.UnsafeMapType
140 keyType reflect2.Type
141 elemType reflect2.Type
142 keyDecoder ValDecoder
143 elemDecoder ValDecoder
144}
145
146func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
147 mapType := decoder.mapType
148 c := iter.nextToken()
149 if c == 'n' {
150 iter.skipThreeBytes('u', 'l', 'l')
151 *(*unsafe.Pointer)(ptr) = nil
152 mapType.UnsafeSet(ptr, mapType.UnsafeNew())
153 return
154 }
155 if mapType.UnsafeIsNil(ptr) {
156 mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
157 }
158 if c != '{' {
159 iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
160 return
161 }
162 c = iter.nextToken()
163 if c == '}' {
164 return
165 }
166 if c != '"' {
167 iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
168 return
169 }
170 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) {
252 stream.WriteObjectStart()
253 iter := encoder.mapType.UnsafeIterate(ptr)
254 for i := 0; iter.HasNext(); i++ {
255 if i != 0 {
256 stream.WriteMore()
257 }
258 key, elem := iter.UnsafeNext()
259 encoder.keyEncoder.Encode(key, stream)
260 if stream.indention > 0 {
261 stream.writeTwoBytes(byte(':'), byte(' '))
262 } else {
263 stream.writeByte(':')
264 }
265 encoder.elemEncoder.Encode(elem, stream)
266 }
267 stream.WriteObjectEnd()
268}
269
270func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
271 iter := encoder.mapType.UnsafeIterate(ptr)
272 return !iter.HasNext()
273}
274
275type sortKeysMapEncoder struct {
276 mapType *reflect2.UnsafeMapType
277 keyEncoder ValEncoder
278 elemEncoder ValEncoder
279}
280
281func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
282 if *(*unsafe.Pointer)(ptr) == nil {
283 stream.WriteNil()
284 return
285 }
286 stream.WriteObjectStart()
287 mapIter := encoder.mapType.UnsafeIterate(ptr)
288 subStream := stream.cfg.BorrowStream(nil)
289 subIter := stream.cfg.BorrowIterator(nil)
290 keyValues := encodedKeyValues{}
291 for mapIter.HasNext() {
292 subStream.buf = make([]byte, 0, 64)
293 key, elem := mapIter.UnsafeNext()
294 encoder.keyEncoder.Encode(key, subStream)
295 if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
296 stream.Error = subStream.Error
297 }
298 encodedKey := subStream.Buffer()
299 subIter.ResetBytes(encodedKey)
300 decodedKey := subIter.ReadString()
301 if stream.indention > 0 {
302 subStream.writeTwoBytes(byte(':'), byte(' '))
303 } else {
304 subStream.writeByte(':')
305 }
306 encoder.elemEncoder.Encode(elem, subStream)
307 keyValues = append(keyValues, encodedKV{
308 key: decodedKey,
309 keyValue: subStream.Buffer(),
310 })
311 }
312 sort.Sort(keyValues)
313 for i, keyValue := range keyValues {
314 if i != 0 {
315 stream.WriteMore()
316 }
317 stream.Write(keyValue.keyValue)
318 }
319 stream.WriteObjectEnd()
320 stream.cfg.ReturnStream(subStream)
321 stream.cfg.ReturnIterator(subIter)
322}
323
324func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
325 iter := encoder.mapType.UnsafeIterate(ptr)
326 return !iter.HasNext()
327}
328
329type encodedKeyValues []encodedKV
330
331type encodedKV struct {
332 key string
333 keyValue []byte
334}
335
336func (sv encodedKeyValues) Len() int { return len(sv) }
337func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
338func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }