feature_reflect_slice.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package jsoniter
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. "unsafe"
  7. )
  8. func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
  9. decoder := decoderOfType(cfg, prefix+"[slice]->", typ.Elem())
  10. return &sliceDecoder{typ, typ.Elem(), decoder}
  11. }
  12. func encoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
  13. encoder := encoderOfType(cfg, prefix+"[slice]->", typ.Elem())
  14. if typ.Elem().Kind() == reflect.Map {
  15. encoder = &OptionalEncoder{encoder}
  16. }
  17. return &sliceEncoder{typ, typ.Elem(), encoder}
  18. }
  19. type sliceEncoder struct {
  20. sliceType reflect.Type
  21. elemType reflect.Type
  22. elemEncoder ValEncoder
  23. }
  24. func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  25. slice := (*sliceHeader)(ptr)
  26. if slice.Data == nil {
  27. stream.WriteNil()
  28. return
  29. }
  30. if slice.Len == 0 {
  31. stream.WriteEmptyArray()
  32. return
  33. }
  34. stream.WriteArrayStart()
  35. elemPtr := unsafe.Pointer(slice.Data)
  36. encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
  37. for i := 1; i < slice.Len; i++ {
  38. stream.WriteMore()
  39. elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
  40. encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
  41. }
  42. stream.WriteArrayEnd()
  43. if stream.Error != nil && stream.Error != io.EOF {
  44. stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
  45. }
  46. }
  47. func (encoder *sliceEncoder) EncodeInterface(val interface{}, stream *Stream) {
  48. WriteToStream(val, stream, encoder)
  49. }
  50. func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  51. slice := (*sliceHeader)(ptr)
  52. return slice.Len == 0
  53. }
  54. type sliceDecoder struct {
  55. sliceType reflect.Type
  56. elemType reflect.Type
  57. elemDecoder ValDecoder
  58. }
  59. // sliceHeader is a safe version of SliceHeader used within this package.
  60. type sliceHeader struct {
  61. Data unsafe.Pointer
  62. Len int
  63. Cap int
  64. }
  65. func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  66. decoder.doDecode(ptr, iter)
  67. if iter.Error != nil && iter.Error != io.EOF {
  68. iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
  69. }
  70. }
  71. func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
  72. slice := (*sliceHeader)(ptr)
  73. if iter.ReadNil() {
  74. slice.Len = 0
  75. slice.Cap = 0
  76. slice.Data = nil
  77. return
  78. }
  79. reuseSlice(slice, decoder.sliceType, 4)
  80. slice.Len = 0
  81. offset := uintptr(0)
  82. iter.ReadArrayCB(func(iter *Iterator) bool {
  83. growOne(slice, decoder.sliceType, decoder.elemType)
  84. decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
  85. offset += decoder.elemType.Size()
  86. return true
  87. })
  88. }
  89. // grow grows the slice s so that it can hold extra more values, allocating
  90. // more capacity if needed. It also returns the old and new slice lengths.
  91. func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) {
  92. newLen := slice.Len + 1
  93. if newLen <= slice.Cap {
  94. slice.Len = newLen
  95. return
  96. }
  97. newCap := slice.Cap
  98. if newCap == 0 {
  99. newCap = 1
  100. } else {
  101. for newCap < newLen {
  102. if slice.Len < 1024 {
  103. newCap += newCap
  104. } else {
  105. newCap += newCap / 4
  106. }
  107. }
  108. }
  109. newVal := reflect.MakeSlice(sliceType, newLen, newCap).Interface()
  110. newValPtr := extractInterface(newVal).word
  111. dst := (*sliceHeader)(newValPtr).Data
  112. // copy old array into new array
  113. originalBytesCount := slice.Len * int(elementType.Size())
  114. srcSliceHeader := (unsafe.Pointer)(&sliceHeader{slice.Data, originalBytesCount, originalBytesCount})
  115. dstSliceHeader := (unsafe.Pointer)(&sliceHeader{dst, originalBytesCount, originalBytesCount})
  116. copy(*(*[]byte)(dstSliceHeader), *(*[]byte)(srcSliceHeader))
  117. slice.Data = dst
  118. slice.Len = newLen
  119. slice.Cap = newCap
  120. }
  121. func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) {
  122. if expectedCap <= slice.Cap {
  123. return
  124. }
  125. newVal := reflect.MakeSlice(sliceType, 0, expectedCap).Interface()
  126. newValPtr := extractInterface(newVal).word
  127. dst := (*sliceHeader)(newValPtr).Data
  128. slice.Data = dst
  129. slice.Cap = expectedCap
  130. }