github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/internal/json/api_amd64.go (about) 1 //go:build amd64 && go1.16 2 // +build amd64,go1.16 3 4 // Copyright 2023 CloudWeGo Authors. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package json 19 20 import ( 21 "runtime" 22 "unsafe" 23 24 "github.com/cloudwego/base64x" 25 "github.com/cloudwego/dynamicgo/internal/native" 26 "github.com/cloudwego/dynamicgo/internal/native/types" 27 "github.com/cloudwego/dynamicgo/internal/rt" 28 ) 29 30 31 var typeByte = rt.UnpackEface(byte(0)).Type 32 33 //go:nocheckptr 34 // NoQuote only escape inner '\' and '"' of one string, but it does add quotes besides string. 35 func NoQuote(buf *[]byte, val string) { 36 sp := rt.IndexChar(val, 0) 37 nb := len(val) 38 b := (*rt.GoSlice)(unsafe.Pointer(buf)) 39 40 // input buffer 41 for nb > 0 { 42 // output buffer 43 dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len)) 44 dn := b.Cap - b.Len 45 // call native.Quote, dn is byte count it outputs 46 ret := native.Quote(sp, nb, dp, &dn, 0) 47 // update *buf length 48 b.Len += dn 49 50 // no need more output 51 if ret >= 0 { 52 break 53 } 54 55 // double buf size 56 *b = rt.Growslice(typeByte, *b, b.Cap*2) 57 // ret is the complement of consumed input 58 ret = ^ret 59 // update input buffer 60 nb -= ret 61 sp = unsafe.Pointer(uintptr(sp) + uintptr(ret)) 62 } 63 64 runtime.KeepAlive(buf) 65 runtime.KeepAlive(sp) 66 } 67 68 func i64toa(buf *[]byte, val int64) int { 69 rt.GuardSlice(buf, types.MaxInt64StringLen) 70 s := len(*buf) 71 ret := native.I64toa((*byte)(rt.IndexPtr((*rt.GoSlice)(unsafe.Pointer(buf)).Ptr, typeByte.Size, s)), val) 72 if ret < 0 { 73 *buf = append((*buf)[s:], '0') 74 return 1 75 } 76 *buf = (*buf)[:s+ret] 77 return ret 78 } 79 80 func f64toa(buf *[]byte, val float64) int { 81 rt.GuardSlice(buf, types.MaxFloat64StringLen) 82 s := len(*buf) 83 ret := native.F64toa((*byte)(rt.IndexPtr((*rt.GoSlice)(unsafe.Pointer(buf)).Ptr, typeByte.Size, s)), val) 84 if ret < 0 { 85 *buf = append((*buf)[s:], '0') 86 return 1 87 } 88 *buf = (*buf)[:s+ret] 89 return ret 90 } 91 92 func encodeBase64(src []byte) string { 93 return base64x.StdEncoding.EncodeToString(src) 94 }