feature_reflect_array.go 3.9 KB

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