github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/ast/api_amd64.go (about) 1 //go:build amd64 && go1.16 && !go1.22 2 // +build amd64,go1.16,!go1.22 3 4 /* 5 * Copyright 2022 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package ast 21 22 import ( 23 "runtime" 24 "unsafe" 25 26 "github.com/chenzhuoyu/base64x" 27 "github.com/goshafaq/sonic/encoder" 28 "github.com/goshafaq/sonic/internal/native" 29 "github.com/goshafaq/sonic/internal/native/types" 30 "github.com/goshafaq/sonic/internal/rt" 31 uq "github.com/goshafaq/sonic/unquote" 32 ) 33 34 var typeByte = rt.UnpackEface(byte(0)).Type 35 36 //go:nocheckptr 37 func quote(buf *[]byte, val string) { 38 *buf = append(*buf, '"') 39 if len(val) == 0 { 40 *buf = append(*buf, '"') 41 return 42 } 43 44 sp := rt.IndexChar(val, 0) 45 nb := len(val) 46 b := (*rt.GoSlice)(unsafe.Pointer(buf)) 47 48 // input buffer 49 for nb > 0 { 50 // output buffer 51 dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len)) 52 dn := b.Cap - b.Len 53 // call native.Quote, dn is byte count it outputs 54 ret := native.Quote(sp, nb, dp, &dn, 0) 55 // update *buf length 56 b.Len += dn 57 58 // no need more output 59 if ret >= 0 { 60 break 61 } 62 63 // double buf size 64 *b = growslice(typeByte, *b, b.Cap*2) 65 // ret is the complement of consumed input 66 ret = ^ret 67 // update input buffer 68 nb -= ret 69 sp = unsafe.Pointer(uintptr(sp) + uintptr(ret)) 70 } 71 72 runtime.KeepAlive(buf) 73 runtime.KeepAlive(sp) 74 *buf = append(*buf, '"') 75 } 76 77 func unquote(src string) (string, types.ParsingError) { 78 return uq.String(src) 79 } 80 81 func decodeBase64(src string) ([]byte, error) { 82 return base64x.StdEncoding.DecodeString(src) 83 } 84 85 func encodeBase64(src []byte) string { 86 return base64x.StdEncoding.EncodeToString(src) 87 } 88 89 func (self *Parser) decodeValue() (val types.JsonState) { 90 sv := (*rt.GoString)(unsafe.Pointer(&self.s)) 91 flag := types.F_USE_NUMBER 92 if self.dbuf != nil { 93 flag = 0 94 val.Dbuf = self.dbuf 95 val.Dcap = types.MaxDigitNums 96 } 97 self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, uint64(flag)) 98 return 99 } 100 101 func (self *Parser) skip() (int, types.ParsingError) { 102 fsm := types.NewStateMachine() 103 start := native.SkipOne(&self.s, &self.p, fsm, 0) 104 types.FreeStateMachine(fsm) 105 106 if start < 0 { 107 return self.p, types.ParsingError(-start) 108 } 109 return start, 0 110 } 111 112 func (self *Node) encodeInterface(buf *[]byte) error { 113 //WARN: NOT compatible with json.Encoder 114 return encoder.EncodeInto(buf, self.packAny(), 0) 115 } 116 117 func (self *Parser) skipFast() (int, types.ParsingError) { 118 start := native.SkipOneFast(&self.s, &self.p) 119 if start < 0 { 120 return self.p, types.ParsingError(-start) 121 } 122 return start, 0 123 } 124 125 func (self *Parser) getByPath(path ...interface{}) (int, types.ParsingError) { 126 fsm := types.NewStateMachine() 127 start := native.GetByPath(&self.s, &self.p, &path, fsm) 128 types.FreeStateMachine(fsm) 129 runtime.KeepAlive(path) 130 if start < 0 { 131 return self.p, types.ParsingError(-start) 132 } 133 return start, 0 134 } 135 136 func (self *Searcher) GetByPath(path ...interface{}) (Node, error) { 137 var err types.ParsingError 138 var start int 139 140 self.parser.p = 0 141 start, err = self.parser.getByPath(path...) 142 if err != 0 { 143 // for compatibility with old version 144 if err == types.ERR_NOT_FOUND { 145 return Node{}, ErrNotExist 146 } 147 if err == types.ERR_UNSUPPORT_TYPE { 148 panic("path must be either int(>=0) or string") 149 } 150 return Node{}, self.parser.syntaxError(err) 151 } 152 153 t := switchRawType(self.parser.s[start]) 154 if t == _V_NONE { 155 return Node{}, self.parser.ExportError(err) 156 } 157 return newRawNode(self.parser.s[start:self.parser.p], t), nil 158 }