reflect_array.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "unsafe"
  7. )
  8. func decoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  9. decoder := decoderOfType(cfg, prefix+"[array]->", typ.Elem())
  10. return &arrayDecoder{typ, typ.Elem(), decoder}
  11. }
  12. func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  13. if typ.Len() == 0 {
  14. return emptyArrayEncoder{}
  15. }
  16. encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem())
  17. return &arrayEncoder{typ, typ.Elem(), encoder}
  18. }
  19. type emptyArrayEncoder struct{}
  20. func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  21. stream.WriteEmptyArray()
  22. }
  23. func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  24. return true
  25. }
  26. type arrayEncoder struct {
  27. arrayType reflect.Type
  28. elemType reflect.Type
  29. elemEncoder ValEncoder
  30. }
  31. func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  32. stream.WriteArrayStart()
  33. elemPtr := unsafe.Pointer(ptr)
  34. encoder.elemEncoder.Encode(elemPtr, stream)
  35. for i := 1; i < encoder.arrayType.Len(); i++ {
  36. stream.WriteMore()
  37. elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
  38. encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
  39. }
  40. stream.WriteArrayEnd()
  41. if stream.Error != nil && stream.Error != io.EOF {
  42. stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
  43. }
  44. }
  45. func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  46. return false
  47. }
  48. type arrayDecoder struct {
  49. arrayType reflect.Type
  50. elemType reflect.Type
  51. elemDecoder ValDecoder
  52. }
  53. func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  54. decoder.doDecode(ptr, iter)
  55. if iter.Error != nil && iter.Error != io.EOF {
  56. iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
  57. }
  58. }
  59. func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  60. offset := uintptr(0)
  61. iter.ReadArrayCB(func(iter *Iterator) bool {
  62. if offset < decoder.arrayType.Size() {
  63. decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
  64. offset += decoder.elemType.Size()
  65. } else {
  66. iter.Skip()
  67. }
  68. return true
  69. })
  70. }