gtsocial-umbx

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

primitives.go (4644B)


      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 encoder
     18 
     19 import (
     20     `encoding`
     21     `encoding/json`
     22     `unsafe`
     23 
     24     `github.com/bytedance/sonic/internal/jit`
     25     `github.com/bytedance/sonic/internal/native`
     26     `github.com/bytedance/sonic/internal/rt`
     27 )
     28 
     29 /** Encoder Primitives **/
     30 
     31 func encodeNil(rb *[]byte) error {
     32     *rb = append(*rb, 'n', 'u', 'l', 'l')
     33     return nil
     34 }
     35 
     36 func encodeString(buf *[]byte, val string) error {
     37     var sidx int
     38     var pbuf *rt.GoSlice
     39     var pstr *rt.GoString
     40 
     41     /* opening quote */
     42     *buf = append(*buf, '"')
     43     pbuf = (*rt.GoSlice)(unsafe.Pointer(buf))
     44     pstr = (*rt.GoString)(unsafe.Pointer(&val))
     45 
     46     /* encode with native library */
     47     for sidx < pstr.Len {
     48         sn := pstr.Len - sidx
     49         dn := pbuf.Cap - pbuf.Len
     50         sp := padd(pstr.Ptr, sidx)
     51         dp := padd(pbuf.Ptr, pbuf.Len)
     52         nb := native.Quote(sp, sn, dp, &dn, 0)
     53 
     54         /* check for errors */
     55         if pbuf.Len += dn; nb >= 0 {
     56             break
     57         }
     58 
     59         /* not enough space, grow the slice and try again */
     60         sidx += ^nb
     61         *pbuf = growslice(rt.UnpackType(byteType), *pbuf, pbuf.Cap * 2)
     62     }
     63 
     64     /* closing quote */
     65     *buf = append(*buf, '"')
     66     return nil
     67 }
     68 
     69 func encodeTypedPointer(buf *[]byte, vt *rt.GoType, vp *unsafe.Pointer, sb *_Stack, fv uint64) error {
     70     if vt == nil {
     71         return encodeNil(buf)
     72     } else if fn, err := findOrCompile(vt, (fv&(1<<bitPointerValue)) != 0); err != nil {
     73         return err
     74     } else if vt.Indirect() {
     75         rt.MoreStack(_FP_size + native.MaxFrameSize)
     76         rt.StopProf()
     77         err := fn(buf, *vp, sb, fv)
     78         rt.StartProf()
     79         return err
     80     } else {
     81         rt.MoreStack(_FP_size + native.MaxFrameSize)
     82         rt.StopProf()
     83         err := fn(buf, unsafe.Pointer(vp), sb, fv)
     84         rt.StartProf()
     85         return err
     86     }
     87 }
     88 
     89 func encodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt Options) error {
     90     if ret, err := val.MarshalJSON(); err != nil {
     91         return err
     92     } else {
     93         if opt & CompactMarshaler != 0 {
     94             return compact(buf, ret)
     95         }
     96         if ok, s := Valid(ret); !ok {
     97             return error_marshaler(ret, s)
     98         }
     99         *buf = append(*buf, ret...)
    100         return nil
    101     }
    102 }
    103 
    104 func encodeTextMarshaler(buf *[]byte, val encoding.TextMarshaler, opt Options) error {
    105     if ret, err := val.MarshalText(); err != nil {
    106         return err
    107     } else {
    108         if opt & NoQuoteTextMarshaler != 0 {
    109             *buf = append(*buf, ret...)
    110             return nil
    111         }
    112         return encodeString(buf, rt.Mem2Str(ret) )
    113     }
    114 }
    115 
    116 func htmlEscape(dst []byte, src []byte) []byte {
    117     var sidx int
    118 
    119     dst  = append(dst, src[:0]...) // avoid check nil dst
    120     sbuf := (*rt.GoSlice)(unsafe.Pointer(&src))
    121     dbuf := (*rt.GoSlice)(unsafe.Pointer(&dst))
    122 
    123     /* grow dst if it is shorter */
    124     if cap(dst) - len(dst) < len(src) + native.BufPaddingSize {
    125         cap :=  len(src) * 3 / 2 + native.BufPaddingSize
    126         *dbuf = growslice(typeByte, *dbuf, cap)
    127     }
    128 
    129     for sidx < sbuf.Len {
    130         sp := padd(sbuf.Ptr, sidx)
    131         dp := padd(dbuf.Ptr, dbuf.Len)
    132 
    133         sn := sbuf.Len - sidx
    134         dn := dbuf.Cap - dbuf.Len
    135         nb := native.HTMLEscape(sp, sn, dp, &dn)
    136 
    137         /* check for errors */
    138         if dbuf.Len += dn; nb >= 0 {
    139             break
    140         }
    141 
    142         /* not enough space, grow the slice and try again */
    143         sidx += ^nb
    144         *dbuf = growslice(typeByte, *dbuf, dbuf.Cap * 2)
    145     }
    146     return dst
    147 }
    148 
    149 var (
    150     argPtrs   = []bool { true, true, true, false }
    151     localPtrs = []bool{}
    152 )
    153 
    154 var (
    155     _F_assertI2I = jit.Func(assertI2I)
    156 )
    157 
    158 func asText(v unsafe.Pointer) (string, error) {
    159     text := assertI2I(_T_encoding_TextMarshaler, *(*rt.GoIface)(v))
    160     r, e := (*(*encoding.TextMarshaler)(unsafe.Pointer(&text))).MarshalText()
    161     return rt.Mem2Str(r), e
    162 }
    163 
    164 func asJson(v unsafe.Pointer) (string, error) {
    165     text := assertI2I(_T_json_Marshaler, *(*rt.GoIface)(v))
    166     r, e := (*(*json.Marshaler)(unsafe.Pointer(&text))).MarshalJSON()
    167     return rt.Mem2Str(r), e
    168 }