github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/unquote/unquote.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 unquote
    18  
    19  import (
    20      `unsafe`
    21      `runtime`
    22  
    23      `github.com/bytedance/sonic/internal/native`
    24      `github.com/bytedance/sonic/internal/native/types`
    25      `github.com/bytedance/sonic/internal/rt`
    26  )
    27  
    28  // String unescapes a escaped string (not including `"` at begining and end)
    29  // It validates invalid UTF8 and replace with `\ufffd`
    30  func String(s string) (ret string, err types.ParsingError) {
    31      mm := make([]byte, 0, len(s))
    32      err = intoBytesUnsafe(s, &mm, true)
    33      ret = rt.Mem2Str(mm)
    34      return
    35  }
    36  
    37  // IntoBytes is same with String besides it output result into a buffer m
    38  func IntoBytes(s string, m *[]byte) types.ParsingError {
    39      if cap(*m) < len(s) {
    40          return types.ERR_EOF
    41      } else {
    42          return intoBytesUnsafe(s, m, true)
    43      }
    44  }
    45  
    46  // String unescapes a escaped string (not including `"` at begining and end)
    47  //   - replace enables replacing invalid utf8 escaped char with `\uffd`
    48  func _String(s string, replace bool) (ret string, err error) {
    49      mm := make([]byte, 0, len(s))
    50      err = intoBytesUnsafe(s, &mm, replace)
    51      ret = rt.Mem2Str(mm)
    52      return
    53  }
    54  
    55  func intoBytesUnsafe(s string, m *[]byte, replace bool) types.ParsingError {
    56      pos := -1
    57      slv := (*rt.GoSlice)(unsafe.Pointer(m))
    58      str := (*rt.GoString)(unsafe.Pointer(&s))
    59  
    60      flags := uint64(0)
    61      if replace {
    62          /* unquote as the default configuration, replace invalid unicode with \ufffd */
    63          flags |= types.F_UNICODE_REPLACE
    64      }
    65  
    66      ret := native.Unquote(str.Ptr, str.Len, slv.Ptr, &pos, flags)
    67  
    68      /* check for errors */
    69      if ret < 0 {
    70          return types.ParsingError(-ret)
    71      }
    72  
    73      /* update the length */
    74      slv.Len = ret
    75      runtime.KeepAlive(s)
    76      return 0
    77  }
    78  
    79  
    80