github.com/night-codes/go-json@v0.9.15/internal/decoder/interface.go (about) 1 package decoder 2 3 import ( 4 "bytes" 5 "encoding" 6 "encoding/json" 7 "reflect" 8 "unsafe" 9 10 "github.com/night-codes/go-json/internal/errors" 11 "github.com/night-codes/go-json/internal/runtime" 12 ) 13 14 type interfaceDecoder struct { 15 typ *runtime.Type 16 structName string 17 fieldName string 18 sliceDecoder *sliceDecoder 19 mapDecoder *mapDecoder 20 floatDecoder *floatDecoder 21 numberDecoder *numberDecoder 22 stringDecoder *stringDecoder 23 } 24 25 func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder { 26 ifaceDecoder := &interfaceDecoder{ 27 typ: emptyInterfaceType, 28 structName: structName, 29 fieldName: fieldName, 30 floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { 31 *(*interface{})(p) = v 32 }), 33 numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { 34 *(*interface{})(p) = v 35 }), 36 stringDecoder: newStringDecoder(structName, fieldName), 37 } 38 ifaceDecoder.sliceDecoder = newSliceDecoder( 39 ifaceDecoder, 40 emptyInterfaceType, 41 emptyInterfaceType.Size(), 42 structName, fieldName, 43 ) 44 ifaceDecoder.mapDecoder = newMapDecoder( 45 interfaceMapType, 46 stringType, 47 ifaceDecoder.stringDecoder, 48 interfaceMapType.Elem(), 49 ifaceDecoder, 50 structName, 51 fieldName, 52 ) 53 return ifaceDecoder 54 } 55 56 func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder { 57 emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName) 58 stringDecoder := newStringDecoder(structName, fieldName) 59 return &interfaceDecoder{ 60 typ: typ, 61 structName: structName, 62 fieldName: fieldName, 63 sliceDecoder: newSliceDecoder( 64 emptyIfaceDecoder, 65 emptyInterfaceType, 66 emptyInterfaceType.Size(), 67 structName, fieldName, 68 ), 69 mapDecoder: newMapDecoder( 70 interfaceMapType, 71 stringType, 72 stringDecoder, 73 interfaceMapType.Elem(), 74 emptyIfaceDecoder, 75 structName, 76 fieldName, 77 ), 78 floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { 79 *(*interface{})(p) = v 80 }), 81 numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { 82 *(*interface{})(p) = v 83 }), 84 stringDecoder: stringDecoder, 85 } 86 } 87 88 func (d *interfaceDecoder) numDecoder(s *Stream) Decoder { 89 if s.UseNumber { 90 return d.numberDecoder 91 } 92 return d.floatDecoder 93 } 94 95 var ( 96 emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem()) 97 interfaceMapType = runtime.Type2RType( 98 reflect.TypeOf((*map[string]interface{})(nil)).Elem(), 99 ) 100 stringType = runtime.Type2RType( 101 reflect.TypeOf(""), 102 ) 103 ) 104 105 func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error { 106 start := s.cursor 107 if err := s.skipValue(depth); err != nil { 108 return err 109 } 110 src := s.buf[start:s.cursor] 111 dst := make([]byte, len(src)) 112 copy(dst, src) 113 114 if err := unmarshaler.UnmarshalJSON(dst); err != nil { 115 return err 116 } 117 return nil 118 } 119 120 func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error { 121 start := s.cursor 122 if err := s.skipValue(depth); err != nil { 123 return err 124 } 125 src := s.buf[start:s.cursor] 126 dst := make([]byte, len(src)) 127 copy(dst, src) 128 129 if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil { 130 return err 131 } 132 return nil 133 } 134 135 func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) { 136 cursor = skipWhiteSpace(buf, cursor) 137 start := cursor 138 end, err := skipValue(buf, cursor, depth) 139 if err != nil { 140 return 0, err 141 } 142 src := buf[start:end] 143 dst := make([]byte, len(src)) 144 copy(dst, src) 145 146 if err := unmarshaler.UnmarshalJSON(dst); err != nil { 147 return 0, err 148 } 149 return end, nil 150 } 151 152 func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) { 153 cursor = skipWhiteSpace(buf, cursor) 154 start := cursor 155 end, err := skipValue(buf, cursor, depth) 156 if err != nil { 157 return 0, err 158 } 159 src := buf[start:end] 160 dst := make([]byte, len(src)) 161 copy(dst, src) 162 163 if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil { 164 return 0, err 165 } 166 return end, nil 167 } 168 169 func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error { 170 start := s.cursor 171 if err := s.skipValue(depth); err != nil { 172 return err 173 } 174 src := s.buf[start:s.cursor] 175 if bytes.Equal(src, nullbytes) { 176 *(*unsafe.Pointer)(p) = nil 177 return nil 178 } 179 180 dst := make([]byte, len(src)) 181 copy(dst, src) 182 183 if err := unmarshaler.UnmarshalText(dst); err != nil { 184 return err 185 } 186 return nil 187 } 188 189 func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) { 190 cursor = skipWhiteSpace(buf, cursor) 191 start := cursor 192 end, err := skipValue(buf, cursor, depth) 193 if err != nil { 194 return 0, err 195 } 196 src := buf[start:end] 197 if bytes.Equal(src, nullbytes) { 198 *(*unsafe.Pointer)(p) = nil 199 return end, nil 200 } 201 if s, ok := unquoteBytes(src); ok { 202 src = s 203 } 204 if err := unmarshaler.UnmarshalText(src); err != nil { 205 return 0, err 206 } 207 return end, nil 208 } 209 210 func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error { 211 c := s.skipWhiteSpace() 212 for { 213 switch c { 214 case '{': 215 var v map[string]interface{} 216 ptr := unsafe.Pointer(&v) 217 if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil { 218 return err 219 } 220 *(*interface{})(p) = v 221 return nil 222 case '[': 223 var v []interface{} 224 ptr := unsafe.Pointer(&v) 225 if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil { 226 return err 227 } 228 *(*interface{})(p) = v 229 return nil 230 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 231 return d.numDecoder(s).DecodeStream(s, depth, p) 232 case '"': 233 s.cursor++ 234 start := s.cursor 235 for { 236 switch s.char() { 237 case '\\': 238 if _, err := decodeEscapeString(s, nil); err != nil { 239 return err 240 } 241 case '"': 242 literal := s.buf[start:s.cursor] 243 s.cursor++ 244 *(*interface{})(p) = string(literal) 245 return nil 246 case nul: 247 if s.read() { 248 continue 249 } 250 return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) 251 } 252 s.cursor++ 253 } 254 case 't': 255 if err := trueBytes(s); err != nil { 256 return err 257 } 258 **(**interface{})(unsafe.Pointer(&p)) = true 259 return nil 260 case 'f': 261 if err := falseBytes(s); err != nil { 262 return err 263 } 264 **(**interface{})(unsafe.Pointer(&p)) = false 265 return nil 266 case 'n': 267 if err := nullBytes(s); err != nil { 268 return err 269 } 270 *(*interface{})(p) = nil 271 return nil 272 case nul: 273 if s.read() { 274 c = s.char() 275 continue 276 } 277 } 278 break 279 } 280 return errors.ErrInvalidBeginningOfValue(c, s.totalOffset()) 281 } 282 283 type emptyInterface struct { 284 typ *runtime.Type 285 ptr unsafe.Pointer 286 } 287 288 func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { 289 runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ 290 typ: d.typ, 291 ptr: p, 292 })) 293 rv := reflect.ValueOf(runtimeInterfaceValue) 294 if rv.NumMethod() > 0 && rv.CanInterface() { 295 if u, ok := rv.Interface().(unmarshalerContext); ok { 296 return decodeStreamUnmarshalerContext(s, depth, u) 297 } 298 if u, ok := rv.Interface().(json.Unmarshaler); ok { 299 return decodeStreamUnmarshaler(s, depth, u) 300 } 301 if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { 302 return decodeStreamTextUnmarshaler(s, depth, u, p) 303 } 304 if s.skipWhiteSpace() == 'n' { 305 if err := nullBytes(s); err != nil { 306 return err 307 } 308 *(*interface{})(p) = nil 309 return nil 310 } 311 return d.errUnmarshalType(rv.Type(), s.totalOffset()) 312 } 313 iface := rv.Interface() 314 ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) 315 typ := ifaceHeader.typ 316 if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { 317 // concrete type is empty interface 318 return d.decodeStreamEmptyInterface(s, depth, p) 319 } 320 if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { 321 return d.decodeStreamEmptyInterface(s, depth, p) 322 } 323 if s.skipWhiteSpace() == 'n' { 324 if err := nullBytes(s); err != nil { 325 return err 326 } 327 *(*interface{})(p) = nil 328 return nil 329 } 330 decoder, err := CompileToGetDecoder(typ) 331 if err != nil { 332 return err 333 } 334 return decoder.DecodeStream(s, depth, ifaceHeader.ptr) 335 } 336 337 func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError { 338 return &errors.UnmarshalTypeError{ 339 Value: typ.String(), 340 Type: typ, 341 Offset: offset, 342 Struct: d.structName, 343 Field: d.fieldName, 344 } 345 } 346 347 func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 348 buf := ctx.Buf 349 runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ 350 typ: d.typ, 351 ptr: p, 352 })) 353 rv := reflect.ValueOf(runtimeInterfaceValue) 354 if rv.NumMethod() > 0 && rv.CanInterface() { 355 if u, ok := rv.Interface().(unmarshalerContext); ok { 356 return decodeUnmarshalerContext(ctx, buf, cursor, depth, u) 357 } 358 if u, ok := rv.Interface().(json.Unmarshaler); ok { 359 return decodeUnmarshaler(buf, cursor, depth, u) 360 } 361 if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { 362 return decodeTextUnmarshaler(buf, cursor, depth, u, p) 363 } 364 cursor = skipWhiteSpace(buf, cursor) 365 if buf[cursor] == 'n' { 366 if err := validateNull(buf, cursor); err != nil { 367 return 0, err 368 } 369 cursor += 4 370 **(**interface{})(unsafe.Pointer(&p)) = nil 371 return cursor, nil 372 } 373 return 0, d.errUnmarshalType(rv.Type(), cursor) 374 } 375 376 iface := rv.Interface() 377 ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) 378 typ := ifaceHeader.typ 379 if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { 380 // concrete type is empty interface 381 return d.decodeEmptyInterface(ctx, cursor, depth, p) 382 } 383 if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { 384 return d.decodeEmptyInterface(ctx, cursor, depth, p) 385 } 386 cursor = skipWhiteSpace(buf, cursor) 387 if buf[cursor] == 'n' { 388 if err := validateNull(buf, cursor); err != nil { 389 return 0, err 390 } 391 cursor += 4 392 **(**interface{})(unsafe.Pointer(&p)) = nil 393 return cursor, nil 394 } 395 decoder, err := CompileToGetDecoder(typ) 396 if err != nil { 397 return 0, err 398 } 399 return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr) 400 } 401 402 func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { 403 buf := ctx.Buf 404 cursor = skipWhiteSpace(buf, cursor) 405 switch buf[cursor] { 406 case '{': 407 var v map[string]interface{} 408 ptr := unsafe.Pointer(&v) 409 cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr) 410 if err != nil { 411 return 0, err 412 } 413 **(**interface{})(unsafe.Pointer(&p)) = v 414 return cursor, nil 415 case '[': 416 var v []interface{} 417 ptr := unsafe.Pointer(&v) 418 cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr) 419 if err != nil { 420 return 0, err 421 } 422 **(**interface{})(unsafe.Pointer(&p)) = v 423 return cursor, nil 424 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': 425 return d.floatDecoder.Decode(ctx, cursor, depth, p) 426 case '"': 427 var v string 428 ptr := unsafe.Pointer(&v) 429 cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr) 430 if err != nil { 431 return 0, err 432 } 433 **(**interface{})(unsafe.Pointer(&p)) = v 434 return cursor, nil 435 case 't': 436 if err := validateTrue(buf, cursor); err != nil { 437 return 0, err 438 } 439 cursor += 4 440 **(**interface{})(unsafe.Pointer(&p)) = true 441 return cursor, nil 442 case 'f': 443 if err := validateFalse(buf, cursor); err != nil { 444 return 0, err 445 } 446 cursor += 5 447 **(**interface{})(unsafe.Pointer(&p)) = false 448 return cursor, nil 449 case 'n': 450 if err := validateNull(buf, cursor); err != nil { 451 return 0, err 452 } 453 cursor += 4 454 **(**interface{})(unsafe.Pointer(&p)) = nil 455 return cursor, nil 456 } 457 return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor) 458 }