encode.go raw
1 /*
2 * Copyright 2021 ByteDance Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package ast
18
19 import (
20 "sync"
21 "unicode/utf8"
22
23 "github.com/bytedance/sonic/internal/rt"
24 "github.com/bytedance/sonic/option"
25 )
26
27 func quoteString(e *[]byte, s string) {
28 *e = append(*e, '"')
29 start := 0
30 for i := 0; i < len(s); {
31 if b := s[i]; b < utf8.RuneSelf {
32 if rt.SafeSet[b] {
33 i++
34 continue
35 }
36 if start < i {
37 *e = append(*e, s[start:i]...)
38 }
39 *e = append(*e, '\\')
40 switch b {
41 case '\\', '"':
42 *e = append(*e, b)
43 case '\n':
44 *e = append(*e, 'n')
45 case '\r':
46 *e = append(*e, 'r')
47 case '\t':
48 *e = append(*e, 't')
49 default:
50 // This encodes bytes < 0x20 except for \t, \n and \r.
51 // If escapeHTML is set, it also escapes <, >, and &
52 // because they can lead to security holes when
53 // user-controlled strings are rendered into JSON
54 // and served to some browsers.
55 *e = append(*e, `u00`...)
56 *e = append(*e, rt.Hex[b>>4])
57 *e = append(*e, rt.Hex[b&0xF])
58 }
59 i++
60 start = i
61 continue
62 }
63 c, size := utf8.DecodeRuneInString(s[i:])
64 // if c == utf8.RuneError && size == 1 {
65 // if start < i {
66 // e.Write(s[start:i])
67 // }
68 // e.WriteString(`\ufffd`)
69 // i += size
70 // start = i
71 // continue
72 // }
73 if c == '\u2028' || c == '\u2029' {
74 if start < i {
75 *e = append(*e, s[start:i]...)
76 }
77 *e = append(*e, `\u202`...)
78 *e = append(*e, rt.Hex[c&0xF])
79 i += size
80 start = i
81 continue
82 }
83 i += size
84 }
85 if start < len(s) {
86 *e = append(*e, s[start:]...)
87 }
88 *e = append(*e, '"')
89 }
90
91 var bytesPool = sync.Pool{}
92
93 func (self *Node) MarshalJSON() ([]byte, error) {
94 if self == nil {
95 return bytesNull, nil
96 }
97
98 buf := newBuffer()
99 err := self.encode(buf)
100 if err != nil {
101 freeBuffer(buf)
102 return nil, err
103 }
104 var ret []byte
105 if !rt.CanSizeResue(cap(*buf)) {
106 ret = *buf
107 } else {
108 ret = make([]byte, len(*buf))
109 copy(ret, *buf)
110 freeBuffer(buf)
111 }
112 return ret, err
113 }
114
115 func newBuffer() *[]byte {
116 if ret := bytesPool.Get(); ret != nil {
117 return ret.(*[]byte)
118 } else {
119 buf := make([]byte, 0, option.DefaultAstBufferSize)
120 return &buf
121 }
122 }
123
124 func freeBuffer(buf *[]byte) {
125 if !rt.CanSizeResue(cap(*buf)) {
126 return
127 }
128 *buf = (*buf)[:0]
129 bytesPool.Put(buf)
130 }
131
132 func (self *Node) encode(buf *[]byte) error {
133 if self.isRaw() {
134 return self.encodeRaw(buf)
135 }
136 switch int(self.itype()) {
137 case V_NONE : return ErrNotExist
138 case V_ERROR : return self.Check()
139 case V_NULL : return self.encodeNull(buf)
140 case V_TRUE : return self.encodeTrue(buf)
141 case V_FALSE : return self.encodeFalse(buf)
142 case V_ARRAY : return self.encodeArray(buf)
143 case V_OBJECT: return self.encodeObject(buf)
144 case V_STRING: return self.encodeString(buf)
145 case V_NUMBER: return self.encodeNumber(buf)
146 case V_ANY : return self.encodeInterface(buf)
147 default : return ErrUnsupportType
148 }
149 }
150
151 func (self *Node) encodeRaw(buf *[]byte) error {
152 lock := self.rlock()
153 if !self.isRaw() {
154 self.runlock()
155 return self.encode(buf)
156 }
157 raw := self.toString()
158 if lock {
159 self.runlock()
160 }
161 *buf = append(*buf, raw...)
162 return nil
163 }
164
165 func (self *Node) encodeNull(buf *[]byte) error {
166 *buf = append(*buf, strNull...)
167 return nil
168 }
169
170 func (self *Node) encodeTrue(buf *[]byte) error {
171 *buf = append(*buf, bytesTrue...)
172 return nil
173 }
174
175 func (self *Node) encodeFalse(buf *[]byte) error {
176 *buf = append(*buf, bytesFalse...)
177 return nil
178 }
179
180 func (self *Node) encodeNumber(buf *[]byte) error {
181 str := self.toString()
182 *buf = append(*buf, str...)
183 return nil
184 }
185
186 func (self *Node) encodeString(buf *[]byte) error {
187 if self.l == 0 {
188 *buf = append(*buf, '"', '"')
189 return nil
190 }
191
192 quote(buf, self.toString())
193 return nil
194 }
195
196 func (self *Node) encodeArray(buf *[]byte) error {
197 if self.isLazy() {
198 if err := self.skipAllIndex(); err != nil {
199 return err
200 }
201 }
202
203 nb := self.len()
204 if nb == 0 {
205 *buf = append(*buf, bytesArray...)
206 return nil
207 }
208
209 *buf = append(*buf, '[')
210
211 var started bool
212 for i := 0; i < nb; i++ {
213 n := self.nodeAt(i)
214 if !n.Exists() {
215 continue
216 }
217 if started {
218 *buf = append(*buf, ',')
219 }
220 started = true
221 if err := n.encode(buf); err != nil {
222 return err
223 }
224 }
225
226 *buf = append(*buf, ']')
227 return nil
228 }
229
230 func (self *Pair) encode(buf *[]byte) error {
231 if len(*buf) == 0 {
232 *buf = append(*buf, '"', '"', ':')
233 return self.Value.encode(buf)
234 }
235
236 quote(buf, self.Key)
237 *buf = append(*buf, ':')
238
239 return self.Value.encode(buf)
240 }
241
242 func (self *Node) encodeObject(buf *[]byte) error {
243 if self.isLazy() {
244 if err := self.skipAllKey(); err != nil {
245 return err
246 }
247 }
248
249 nb := self.len()
250 if nb == 0 {
251 *buf = append(*buf, bytesObject...)
252 return nil
253 }
254
255 *buf = append(*buf, '{')
256
257 var started bool
258 for i := 0; i < nb; i++ {
259 n := self.pairAt(i)
260 if n == nil || !n.Value.Exists() {
261 continue
262 }
263 if started {
264 *buf = append(*buf, ',')
265 }
266 started = true
267 if err := n.encode(buf); err != nil {
268 return err
269 }
270 }
271
272 *buf = append(*buf, '}')
273 return nil
274 }
275