blob: 7f66a88b043d4b145afe2ce33736f4c6bedee10a [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)
67 if ptrType.Implements(textMarshalerType) {
68 return &referenceDecoder{
69 &textUnmarshalerDecoder{
70 valType: ptrType,
71 },
72 }
73 }
74 if typ.Implements(textMarshalerType) {
75 return &textUnmarshalerDecoder{
76 valType: typ,
77 }
78 }
79 return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
80 }
81}
82
83func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
84 encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ)
85 if encoder != nil {
86 return encoder
87 }
88 for _, extension := range ctx.extraExtensions {
89 encoder := extension.CreateMapKeyEncoder(typ)
90 if encoder != nil {
91 return encoder
92 }
93 }
94 switch typ.Kind() {
95 case reflect.String:
96 return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
97 case reflect.Bool,
98 reflect.Uint8, reflect.Int8,
99 reflect.Uint16, reflect.Int16,
100 reflect.Uint32, reflect.Int32,
101 reflect.Uint64, reflect.Int64,
102 reflect.Uint, reflect.Int,
103 reflect.Float32, reflect.Float64,
104 reflect.Uintptr:
105 typ = reflect2.DefaultTypeOfKind(typ.Kind())
106 return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
107 default:
108 if typ == textMarshalerType {
109 return &directTextMarshalerEncoder{
110 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
111 }
112 }
113 if typ.Implements(textMarshalerType) {
114 return &textMarshalerEncoder{
115 valType: typ,
116 stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
117 }
118 }
119 if typ.Kind() == reflect.Interface {
120 return &dynamicMapKeyEncoder{ctx, typ}
121 }
122 return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
123 }
124}
125
126type mapDecoder struct {
127 mapType *reflect2.UnsafeMapType
128 keyType reflect2.Type
129 elemType reflect2.Type
130 keyDecoder ValDecoder
131 elemDecoder ValDecoder
132}
133
134func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
135 mapType := decoder.mapType
136 c := iter.nextToken()
137 if c == 'n' {
138 iter.skipThreeBytes('u', 'l', 'l')
139 *(*unsafe.Pointer)(ptr) = nil
140 mapType.UnsafeSet(ptr, mapType.UnsafeNew())
141 return
142 }
143 if mapType.UnsafeIsNil(ptr) {
144 mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
145 }
146 if c != '{' {
147 iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
148 return
149 }
150 c = iter.nextToken()
151 if c == '}' {
152 return
153 }
154 if c != '"' {
155 iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
156 return
157 }
158 iter.unreadByte()
159 key := decoder.keyType.UnsafeNew()
160 decoder.keyDecoder.Decode(key, iter)
161 c = iter.nextToken()
162 if c != ':' {
163 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
164 return
165 }
166 elem := decoder.elemType.UnsafeNew()
167 decoder.elemDecoder.Decode(elem, iter)
168 decoder.mapType.UnsafeSetIndex(ptr, key, elem)
169 for c = iter.nextToken(); c == ','; c = iter.nextToken() {
170 key := decoder.keyType.UnsafeNew()
171 decoder.keyDecoder.Decode(key, iter)
172 c = iter.nextToken()
173 if c != ':' {
174 iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
175 return
176 }
177 elem := decoder.elemType.UnsafeNew()
178 decoder.elemDecoder.Decode(elem, iter)
179 decoder.mapType.UnsafeSetIndex(ptr, key, elem)
180 }
181 if c != '}' {
182 iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
183 }
184}
185
186type numericMapKeyDecoder struct {
187 decoder ValDecoder
188}
189
190func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
191 c := iter.nextToken()
192 if c != '"' {
193 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
194 return
195 }
196 decoder.decoder.Decode(ptr, iter)
197 c = iter.nextToken()
198 if c != '"' {
199 iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
200 return
201 }
202}
203
204type numericMapKeyEncoder struct {
205 encoder ValEncoder
206}
207
208func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
209 stream.writeByte('"')
210 encoder.encoder.Encode(ptr, stream)
211 stream.writeByte('"')
212}
213
214func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
215 return false
216}
217
218type dynamicMapKeyEncoder struct {
219 ctx *ctx
220 valType reflect2.Type
221}
222
223func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
224 obj := encoder.valType.UnsafeIndirect(ptr)
225 encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
226}
227
228func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
229 obj := encoder.valType.UnsafeIndirect(ptr)
230 return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
231}
232
233type mapEncoder struct {
234 mapType *reflect2.UnsafeMapType
235 keyEncoder ValEncoder
236 elemEncoder ValEncoder
237}
238
239func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
240 stream.WriteObjectStart()
241 iter := encoder.mapType.UnsafeIterate(ptr)
242 for i := 0; iter.HasNext(); i++ {
243 if i != 0 {
244 stream.WriteMore()
245 }
246 key, elem := iter.UnsafeNext()
247 encoder.keyEncoder.Encode(key, stream)
248 if stream.indention > 0 {
249 stream.writeTwoBytes(byte(':'), byte(' '))
250 } else {
251 stream.writeByte(':')
252 }
253 encoder.elemEncoder.Encode(elem, stream)
254 }
255 stream.WriteObjectEnd()
256}
257
258func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
259 iter := encoder.mapType.UnsafeIterate(ptr)
260 return !iter.HasNext()
261}
262
263type sortKeysMapEncoder struct {
264 mapType *reflect2.UnsafeMapType
265 keyEncoder ValEncoder
266 elemEncoder ValEncoder
267}
268
269func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
270 if *(*unsafe.Pointer)(ptr) == nil {
271 stream.WriteNil()
272 return
273 }
274 stream.WriteObjectStart()
275 mapIter := encoder.mapType.UnsafeIterate(ptr)
276 subStream := stream.cfg.BorrowStream(nil)
277 subIter := stream.cfg.BorrowIterator(nil)
278 keyValues := encodedKeyValues{}
279 for mapIter.HasNext() {
280 subStream.buf = make([]byte, 0, 64)
281 key, elem := mapIter.UnsafeNext()
282 encoder.keyEncoder.Encode(key, subStream)
283 if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
284 stream.Error = subStream.Error
285 }
286 encodedKey := subStream.Buffer()
287 subIter.ResetBytes(encodedKey)
288 decodedKey := subIter.ReadString()
289 if stream.indention > 0 {
290 subStream.writeTwoBytes(byte(':'), byte(' '))
291 } else {
292 subStream.writeByte(':')
293 }
294 encoder.elemEncoder.Encode(elem, subStream)
295 keyValues = append(keyValues, encodedKV{
296 key: decodedKey,
297 keyValue: subStream.Buffer(),
298 })
299 }
300 sort.Sort(keyValues)
301 for i, keyValue := range keyValues {
302 if i != 0 {
303 stream.WriteMore()
304 }
305 stream.Write(keyValue.keyValue)
306 }
307 stream.WriteObjectEnd()
308 stream.cfg.ReturnStream(subStream)
309 stream.cfg.ReturnIterator(subIter)
310}
311
312func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
313 iter := encoder.mapType.UnsafeIterate(ptr)
314 return !iter.HasNext()
315}
316
317type encodedKeyValues []encodedKV
318
319type encodedKV struct {
320 key string
321 keyValue []byte
322}
323
324func (sv encodedKeyValues) Len() int { return len(sv) }
325func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
326func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }