github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/ast/encode.go (about)

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