/
val_encoder_native_slice.go
62 lines (56 loc) · 1.05 KB
/
val_encoder_native_slice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package jzon
import (
"reflect"
"unsafe"
)
type sliceEncoderBuilder struct {
encoder *sliceEncoder
elemType reflect.Type
}
func newSliceEncoder(typ reflect.Type) *sliceEncoderBuilder {
elemType := typ.Elem()
return &sliceEncoderBuilder{
encoder: &sliceEncoder{
elemSize: elemType.Size(),
},
elemType: elemType,
}
}
type sliceEncoder struct {
elemSize uintptr
elemEncoder ValEncoder
}
func (*sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
sh := (*sliceHeader)(ptr)
return sh.Data == 0 || sh.Len == 0
}
// Disable new -d=checkptr behaviour for Go 1.14
//go:nocheckptr
func (enc *sliceEncoder) Encode(ptr unsafe.Pointer, s *Streamer, _ *EncOpts) {
if s.Error != nil {
return
}
if ptr == nil {
s.Null()
return
}
sh := (*sliceHeader)(ptr)
if sh.Data == 0 {
s.Null()
return
}
if sh.Len == 0 {
s.RawString("[]")
return
}
s.ArrayStart()
curPtr := sh.Data
for i := 0; i < sh.Len; i++ {
enc.elemEncoder.Encode(unsafe.Pointer(curPtr), s, nil)
if s.Error != nil {
return
}
curPtr += enc.elemSize
}
s.ArrayEnd()
}