gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }