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