feature_reflect_slice.go 4.2 KB

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