1
16
17 package encoder
18
19 import (
20 `encoding`
21 `encoding/json`
22 `unsafe`
23
24 `github.com/bytedance/sonic/internal/jit`
25 `github.com/bytedance/sonic/internal/native`
26 `github.com/bytedance/sonic/internal/rt`
27 )
28
29
30
31 func encodeNil(rb *[]byte) error {
32 *rb = append(*rb, 'n', 'u', 'l', 'l')
33 return nil
34 }
35
36 func encodeString(buf *[]byte, val string) error {
37 var sidx int
38 var pbuf *rt.GoSlice
39 var pstr *rt.GoString
40
41
42 *buf = append(*buf, '"')
43 pbuf = (*rt.GoSlice)(unsafe.Pointer(buf))
44 pstr = (*rt.GoString)(unsafe.Pointer(&val))
45
46
47 for sidx < pstr.Len {
48 sn := pstr.Len - sidx
49 dn := pbuf.Cap - pbuf.Len
50 sp := padd(pstr.Ptr, sidx)
51 dp := padd(pbuf.Ptr, pbuf.Len)
52 nb := native.Quote(sp, sn, dp, &dn, 0)
53
54
55 if pbuf.Len += dn; nb >= 0 {
56 break
57 }
58
59
60 sidx += ^nb
61 *pbuf = growslice(rt.UnpackType(byteType), *pbuf, pbuf.Cap * 2)
62 }
63
64
65 *buf = append(*buf, '"')
66 return nil
67 }
68
69 func encodeTypedPointer(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *_Stack, fv uint64) error {
70 if vt == nil {
71 return encodeNil(buf)
72 } else if fn, err := findOrCompile(vt, (fv&(1<<bitPointerValue)) != 0); err != nil {
73 return err
74 } else if vt.Indirect() {
75 rt.MoreStack(_FP_size + native.MaxFrameSize)
76 rt.StopProf()
77 err := fn(buf, *vp, sb, fv)
78 rt.StartProf()
79 return err
80 } else {
81 rt.MoreStack(_FP_size + native.MaxFrameSize)
82 rt.StopProf()
83 err := fn(buf, unsafe.Pointer(vp), sb, fv)
84 rt.StartProf()
85 return err
86 }
87 }
88
89 func encodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt Options) error {
90 if ret, err := val.MarshalJSON(); err != nil {
91 return err
92 } else {
93 if opt & CompactMarshaler != 0 {
94 return compact(buf, ret)
95 }
96 if opt & NoValidateJSONMarshaler == 0 {
97 if ok, s := Valid(ret); !ok {
98 return error_marshaler(ret, s)
99 }
100 }
101 *buf = append(*buf, ret...)
102 return nil
103 }
104 }
105
106 func encodeTextMarshaler(buf *[]byte, val encoding.TextMarshaler, opt Options) error {
107 if ret, err := val.MarshalText(); err != nil {
108 return err
109 } else {
110 if opt & NoQuoteTextMarshaler != 0 {
111 *buf = append(*buf, ret...)
112 return nil
113 }
114 return encodeString(buf, rt.Mem2Str(ret) )
115 }
116 }
117
118 func htmlEscape(dst []byte, src []byte) []byte {
119 var sidx int
120
121 dst = append(dst, src[:0]...)
122 sbuf := (*rt.GoSlice)(unsafe.Pointer(&src))
123 dbuf := (*rt.GoSlice)(unsafe.Pointer(&dst))
124
125
126 if cap(dst) - len(dst) < len(src) + native.BufPaddingSize {
127 cap := len(src) * 3 / 2 + native.BufPaddingSize
128 *dbuf = growslice(typeByte, *dbuf, cap)
129 }
130
131 for sidx < sbuf.Len {
132 sp := padd(sbuf.Ptr, sidx)
133 dp := padd(dbuf.Ptr, dbuf.Len)
134
135 sn := sbuf.Len - sidx
136 dn := dbuf.Cap - dbuf.Len
137 nb := native.HTMLEscape(sp, sn, dp, &dn)
138
139
140 if dbuf.Len += dn; nb >= 0 {
141 break
142 }
143
144
145 sidx += ^nb
146 *dbuf = growslice(typeByte, *dbuf, dbuf.Cap * 2)
147 }
148 return dst
149 }
150
151 var (
152 argPtrs = []bool { true, true, true, false }
153 localPtrs = []bool{}
154 )
155
156 var (
157 _F_assertI2I = jit.Func(rt.AssertI2I2)
158 )
159
160 func asText(v unsafe.Pointer) (string, error) {
161 text := rt.AssertI2I2(_T_encoding_TextMarshaler, *(*rt.GoIface)(v))
162 r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
163 return rt.Mem2Str(r), e
164 }
165
166 func asJson(v unsafe.Pointer) (string, error) {
167 text := rt.AssertI2I2(_T_json_Marshaler, *(*rt.GoIface)(v))
168 r, e := (*(*json.Marshaler)(unsafe.Pointer(&text))).MarshalJSON()
169 return rt.Mem2Str(r), e
170 }
171
View as plain text