encode.go (6270B)
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 ) 25 26 const ( 27 _MaxBuffer = 1024 // 1KB buffer size 28 ) 29 30 func quoteString(e *[]byte, s string) { 31 *e = append(*e, '"') 32 start := 0 33 for i := 0; i < len(s); { 34 if b := s[i]; b < utf8.RuneSelf { 35 if safeSet[b] { 36 i++ 37 continue 38 } 39 if start < i { 40 *e = append(*e, s[start:i]...) 41 } 42 *e = append(*e, '\\') 43 switch b { 44 case '\\', '"': 45 *e = append(*e, b) 46 case '\n': 47 *e = append(*e, 'n') 48 case '\r': 49 *e = append(*e, 'r') 50 case '\t': 51 *e = append(*e, 't') 52 default: 53 // This encodes bytes < 0x20 except for \t, \n and \r. 54 // If escapeHTML is set, it also escapes <, >, and & 55 // because they can lead to security holes when 56 // user-controlled strings are rendered into JSON 57 // and served to some browsers. 58 *e = append(*e, `u00`...) 59 *e = append(*e, hex[b>>4]) 60 *e = append(*e, hex[b&0xF]) 61 } 62 i++ 63 start = i 64 continue 65 } 66 c, size := utf8.DecodeRuneInString(s[i:]) 67 // if c == utf8.RuneError && size == 1 { 68 // if start < i { 69 // e.Write(s[start:i]) 70 // } 71 // e.WriteString(`\ufffd`) 72 // i += size 73 // start = i 74 // continue 75 // } 76 if c == '\u2028' || c == '\u2029' { 77 if start < i { 78 *e = append(*e, s[start:i]...) 79 } 80 *e = append(*e, `\u202`...) 81 *e = append(*e, hex[c&0xF]) 82 i += size 83 start = i 84 continue 85 } 86 i += size 87 } 88 if start < len(s) { 89 *e = append(*e, s[start:]...) 90 } 91 *e = append(*e, '"') 92 } 93 94 var bytesPool = sync.Pool{} 95 96 func (self *Node) MarshalJSON() ([]byte, error) { 97 buf := newBuffer() 98 err := self.encode(buf) 99 if err != nil { 100 freeBuffer(buf) 101 return nil, err 102 } 103 104 ret := make([]byte, len(*buf)) 105 copy(ret, *buf) 106 freeBuffer(buf) 107 return ret, err 108 } 109 110 func newBuffer() *[]byte { 111 if ret := bytesPool.Get(); ret != nil { 112 return ret.(*[]byte) 113 } else { 114 buf := make([]byte, 0, _MaxBuffer) 115 return &buf 116 } 117 } 118 119 func freeBuffer(buf *[]byte) { 120 *buf = (*buf)[:0] 121 bytesPool.Put(buf) 122 } 123 124 func (self *Node) encode(buf *[]byte) error { 125 if self.IsRaw() { 126 return self.encodeRaw(buf) 127 } 128 switch self.Type() { 129 case V_NONE : return ErrNotExist 130 case V_ERROR : return self.Check() 131 case V_NULL : return self.encodeNull(buf) 132 case V_TRUE : return self.encodeTrue(buf) 133 case V_FALSE : return self.encodeFalse(buf) 134 case V_ARRAY : return self.encodeArray(buf) 135 case V_OBJECT: return self.encodeObject(buf) 136 case V_STRING: return self.encodeString(buf) 137 case V_NUMBER: return self.encodeNumber(buf) 138 case V_ANY : return self.encodeInterface(buf) 139 default : return ErrUnsupportType 140 } 141 } 142 143 func (self *Node) encodeRaw(buf *[]byte) error { 144 raw, err := self.Raw() 145 if err != nil { 146 return err 147 } 148 *buf = append(*buf, raw...) 149 return nil 150 } 151 152 func (self *Node) encodeNull(buf *[]byte) error { 153 *buf = append(*buf, bytesNull...) 154 return nil 155 } 156 157 func (self *Node) encodeTrue(buf *[]byte) error { 158 *buf = append(*buf, bytesTrue...) 159 return nil 160 } 161 162 func (self *Node) encodeFalse(buf *[]byte) error { 163 *buf = append(*buf, bytesFalse...) 164 return nil 165 } 166 167 func (self *Node) encodeNumber(buf *[]byte) error { 168 str := rt.StrFrom(self.p, self.v) 169 *buf = append(*buf, str...) 170 return nil 171 } 172 173 func (self *Node) encodeString(buf *[]byte) error { 174 if self.v == 0 { 175 *buf = append(*buf, '"', '"') 176 return nil 177 } 178 179 quote(buf, rt.StrFrom(self.p, self.v)) 180 return nil 181 } 182 183 func (self *Node) encodeArray(buf *[]byte) error { 184 if self.isLazy() { 185 if err := self.skipAllIndex(); err != nil { 186 return err 187 } 188 } 189 190 nb := self.len() 191 if nb == 0 { 192 *buf = append(*buf, bytesArray...) 193 return nil 194 } 195 196 *buf = append(*buf, '[') 197 198 var p = (*Node)(self.p) 199 err := p.encode(buf) 200 if err != nil { 201 return err 202 } 203 for i := 1; i < nb; i++ { 204 *buf = append(*buf, ',') 205 p = p.unsafe_next() 206 err := p.encode(buf) 207 if err != nil { 208 return err 209 } 210 } 211 212 *buf = append(*buf, ']') 213 return nil 214 } 215 216 func (self *Pair) encode(buf *[]byte) error { 217 if len(*buf) == 0 { 218 *buf = append(*buf, '"', '"', ':') 219 return self.Value.encode(buf) 220 } 221 222 quote(buf, self.Key) 223 *buf = append(*buf, ':') 224 225 return self.Value.encode(buf) 226 } 227 228 func (self *Node) encodeObject(buf *[]byte) error { 229 if self.isLazy() { 230 if err := self.skipAllKey(); err != nil { 231 return err 232 } 233 } 234 235 nb := self.len() 236 if nb == 0 { 237 *buf = append(*buf, bytesObject...) 238 return nil 239 } 240 241 *buf = append(*buf, '{') 242 243 var p = (*Pair)(self.p) 244 err := p.encode(buf) 245 if err != nil { 246 return err 247 } 248 for i := 1; i < nb; i++ { 249 *buf = append(*buf, ',') 250 p = p.unsafe_next() 251 err := p.encode(buf) 252 if err != nil { 253 return err 254 } 255 } 256 257 *buf = append(*buf, '}') 258 return nil 259 }