github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/internal/native/types/types.go (about) 1 /* 2 * Copyright 2023 CloudWeGo Authors. 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 types 18 19 import ( 20 "fmt" 21 "sync" 22 "unsafe" 23 24 ) 25 26 const ( 27 MaxInt64StringLen = 21 28 MaxFloat64StringLen = 32 29 ) 30 31 type ValueType int64 32 33 func (v ValueType) String() string { 34 return _ValueTypes[v] 35 } 36 37 var _ValueTypes = []string{ 38 0: "none", 39 1: "error", 40 V_NULL: "null", 41 V_TRUE: "bool", 42 V_FALSE: "bool", 43 V_ARRAY: "array", 44 V_OBJECT: "object", 45 V_STRING: "string", 46 V_DOUBLE: "double", 47 V_INTEGER: "integer", 48 33: "number", 49 34: "any", 50 } 51 52 type ParsingError uint 53 54 type SearchingError uint 55 56 const ( 57 V_EOF ValueType = 1 58 V_NULL ValueType = 2 59 V_TRUE ValueType = 3 60 V_FALSE ValueType = 4 61 V_ARRAY ValueType = 5 62 V_OBJECT ValueType = 6 63 V_STRING ValueType = 7 64 V_DOUBLE ValueType = 8 65 V_INTEGER ValueType = 9 66 _ ValueType = 10 // V_KEY_SEP 67 _ ValueType = 11 // V_ELEM_SEP 68 _ ValueType = 12 // V_ARRAY_END 69 _ ValueType = 13 // V_OBJECT_END 70 V_MAX 71 ) 72 73 const ( 74 B_DOUBLE_UNQUOTE = 0 75 B_UNICODE_REPLACE = 1 76 ) 77 78 const ( 79 // for unquote 80 F_DOUBLE_UNQUOTE = 1 << B_DOUBLE_UNQUOTE 81 F_UNICODE_REPLACE = 1 << B_UNICODE_REPLACE 82 // for j2t_fsm_exec 83 F_ALLOW_UNKNOWN = 1 84 F_WRITE_DEFAULT = 1 << 1 85 F_VALUE_MAPPING = 1 << 2 86 F_HTTP_MAPPING = 1 << 3 87 F_STRING_INT = 1 << 4 88 F_WRITE_REQUIRE = 1 << 5 89 F_NO_BASE64 = 1 << 6 90 F_WRITE_OPTIONAL = 1 << 7 91 F_TRACE_BACK = 1 << 8 92 ) 93 94 const ( 95 MAX_RECURSE = 4096 96 ) 97 98 const ( 99 SPACE_MASK = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n') 100 ) 101 102 const ( 103 ERR_WRAP_SHIFT_CODE = 8 104 ERR_WRAP_SHIFT_POS = 32 105 ) 106 107 const ( 108 ERR_EOF ParsingError = 1 109 ERR_INVALID_CHAR ParsingError = 2 110 ERR_INVALID_ESCAPE ParsingError = 3 111 ERR_INVALID_UNICODE ParsingError = 4 112 ERR_INTEGER_OVERFLOW ParsingError = 5 113 ERR_INVALID_NUMBER_FMT ParsingError = 6 114 ERR_RECURSE_EXCEED_MAX ParsingError = 7 115 ERR_FLOAT_INFINITY ParsingError = 8 116 ERR_DISMATCH_TYPE ParsingError = 9 117 ERR_NULL_REQUIRED ParsingError = 10 118 ERR_UNSUPPORT_THRIFT_TYPE ParsingError = 11 119 ERR_UNKNOWN_FIELD ParsingError = 12 120 ERR_DISMATCH_TYPE2 ParsingError = 13 121 ERR_DECODE_BASE64 ParsingError = 14 122 ERR_OOM_BM ParsingError = 16 123 ERR_OOM_BUF ParsingError = 17 124 ERR_OOM_KEY ParsingError = 18 125 ERR_OOM_FIELD ParsingError = 22 126 ERR_OOM_FVAL ParsingError = 23 127 ERR_HTTP_MAPPING ParsingError = 19 128 ERR_HTTP_MAPPING_END ParsingError = 21 129 ERR_UNSUPPORT_VM_TYPE ParsingError = 20 130 ERR_VALUE_MAPPING_END ParsingError = 24 131 ) 132 133 var _ParsingErrors = []string{ 134 0: "ok", 135 ERR_EOF: "eof", 136 ERR_INVALID_CHAR: "invalid char", 137 ERR_INVALID_ESCAPE: "invalid escape char", 138 ERR_INVALID_UNICODE: "invalid unicode escape", 139 ERR_INTEGER_OVERFLOW: "integer overflow", 140 ERR_INVALID_NUMBER_FMT: "invalid number format", 141 ERR_RECURSE_EXCEED_MAX: "recursion exceeded max depth", 142 ERR_FLOAT_INFINITY: "float number is infinity", 143 ERR_DISMATCH_TYPE: "dismatched type", 144 ERR_NULL_REQUIRED: "required field is not set", 145 ERR_UNSUPPORT_THRIFT_TYPE: "unsupported type", 146 ERR_UNKNOWN_FIELD: "unknown field", 147 ERR_DISMATCH_TYPE2: "dismatched types", 148 ERR_DECODE_BASE64: "decode base64 error", 149 ERR_OOM_BM: "requireness cache is not enough", 150 ERR_OOM_BUF: "output buffer is not enough", 151 ERR_OOM_KEY: "key cache is not enough", 152 ERR_HTTP_MAPPING: "http mapping error", 153 ERR_UNSUPPORT_VM_TYPE: "unsupported value mapping type", 154 } 155 156 func (self ParsingError) Error() string { 157 return "json: error when parsing input: " + self.Message() 158 } 159 160 func (self ParsingError) Message() string { 161 if int(self) < len(_ParsingErrors) { 162 return _ParsingErrors[self] 163 } else { 164 return fmt.Sprintf("unknown error %d", self) 165 } 166 } 167 168 type JsonState struct { 169 Vt ValueType 170 Dv float64 171 Iv int64 172 Ep int64 173 Dbuf *byte 174 Dcap int 175 } 176 177 type StateMachine struct { 178 Sp int 179 Vt [MAX_RECURSE]int64 180 } 181 182 var stackPool = sync.Pool{ 183 New: func() interface{} { 184 return &StateMachine{} 185 }, 186 } 187 188 func NewStateMachine() *StateMachine { 189 return stackPool.Get().(*StateMachine) 190 } 191 192 func FreeStateMachine(fsm *StateMachine) { 193 stackPool.Put(fsm) 194 } 195 196 const _SIZE_J2TEXTRA = 3 197 198 type J2TExtra [_SIZE_J2TEXTRA]uint64 199 200 type J2TState struct { 201 State int 202 JsonPos int 203 TypeDesc uintptr 204 Extra J2TExtra 205 } 206 207 func (self *J2TState) TdPointer() uintptr { 208 return uintptr(self.TypeDesc) 209 } 210 211 type J2T_STATE uint8 212 213 const ( 214 J2T_VAL J2T_STATE = iota 215 J2T_ARR 216 J2T_OBJ 217 J2T_KEY 218 J2T_ELEM 219 J2T_ARR_0 220 J2T_OBJ_0 221 222 J2T_VM J2T_STATE = 16 223 ) 224 225 func (v J2T_STATE) String() string { 226 return _J2T_STATEs[v] 227 } 228 229 var _J2T_STATEs = []string{ 230 J2T_VAL: "J2T_VAL", 231 J2T_ARR: "J2T_ARR", 232 J2T_OBJ: "J2T_OBJ", 233 J2T_KEY: "J2T_KEY", 234 J2T_ELEM: "J2T_ELEM", 235 J2T_ARR_0: "J2T_ARR_0", 236 J2T_OBJ_0: "J2T_OBJ_0", 237 J2T_VM: "J2T_VM", 238 } 239 240 const ( 241 J2T_KEY_CACHE_SIZE = 1024 242 J2T_FIELD_CACHE_SIZE = 4096 243 J2T_REQS_CACHE_SIZE = 4096 244 J2T_DBUF_SIZE = 800 245 ) 246 247 type J2TStateMachine struct { 248 SP int 249 JT JsonState 250 ReqsCache []byte 251 KeyCache []byte 252 VT [MAX_RECURSE]J2TState 253 SM StateMachine 254 FieldCache []int32 255 FieldValueCache FieldValue 256 } 257 258 type FieldValue struct { 259 FieldID int32 260 ValBegin uint32 261 ValEnd uint32 262 } 263 264 var j2tStackPool = sync.Pool{ 265 New: func() interface{} { 266 ret := &J2TStateMachine{} 267 ret.ReqsCache = make([]byte, 0, J2T_REQS_CACHE_SIZE) 268 ret.KeyCache = make([]byte, 0, J2T_KEY_CACHE_SIZE) 269 ret.FieldCache = make([]int32, 0, J2T_FIELD_CACHE_SIZE) 270 // ret.FieldValueCache = make([]FieldValue, 0, J2T_FIELD_CACHE_SIZE) 271 tmp := make([]byte, 0, J2T_DBUF_SIZE) 272 ret.JT.Dbuf = *(**byte)(unsafe.Pointer(&tmp)) 273 ret.JT.Dcap = J2T_DBUF_SIZE 274 return ret 275 }, 276 } 277 278 func NewJ2TStateMachine() *J2TStateMachine { 279 return j2tStackPool.Get().(*J2TStateMachine) 280 } 281 282 func FreeJ2TStateMachine(ret *J2TStateMachine) { 283 ret.SP = 0 284 ret.ReqsCache = ret.ReqsCache[:0] 285 ret.KeyCache = ret.KeyCache[:0] 286 ret.FieldCache = ret.FieldCache[:0] 287 // ret.FieldValueCache = ret.FieldValueCache[:0] 288 j2tStackPool.Put(ret) 289 } 290 291 func (ret *J2TStateMachine) Init(start int, desc unsafe.Pointer) { 292 ret.SP = 1 293 ret.VT[0] = J2TState{ 294 State: 0, 295 JsonPos: start, 296 TypeDesc: uintptr(desc), 297 } 298 } 299 300 func (self *J2TStateMachine) At(i int) *J2TState { 301 if i < 0 || i >= self.SP { 302 return nil 303 } 304 return &self.VT[i] 305 } 306 307 func (self *J2TStateMachine) Now() *J2TState { 308 if self.SP == 0 || self.SP >= MAX_RECURSE { 309 return nil 310 } 311 return &self.VT[self.SP-1] 312 } 313 314 func (self *J2TStateMachine) Drop() { 315 if self.SP == 0 { 316 return 317 } 318 self.SP-- 319 } 320 321 func (self *J2TStateMachine) Next() *J2TState { 322 if self.SP > MAX_RECURSE { 323 return nil 324 } 325 return &self.VT[self.SP] 326 } 327 328 const ( 329 resizeFactor = 2 330 int64ByteSize = unsafe.Sizeof(int64(0)) 331 ) 332 333 func (ret *J2TStateMachine) GrowReqCache(n int) { 334 c := cap(ret.ReqsCache) + n*resizeFactor 335 tmp := make([]byte, len(ret.ReqsCache), c) 336 copy(tmp, ret.ReqsCache) 337 ret.ReqsCache = tmp 338 } 339 340 func (ret *J2TStateMachine) GrowKeyCache(n int) { 341 c := cap(ret.KeyCache) + n*resizeFactor 342 tmp := make([]byte, len(ret.KeyCache), c) 343 copy(tmp, ret.KeyCache) 344 ret.KeyCache = tmp 345 } 346 347 func (ret *J2TStateMachine) GrowFieldCache(n int) { 348 c := cap(ret.FieldCache) + n 349 tmp := make([]int32, len(ret.FieldCache), c) 350 copy(tmp, ret.FieldCache) 351 ret.FieldCache = tmp 352 } 353 354 // func (ret *J2TStateMachine) GrowFieldValueCache(n int) { 355 // c := cap(ret.FieldValueCache) + n 356 // tmp := make([]FieldValue, len(ret.FieldValueCache), c) 357 // copy(tmp, ret.FieldValueCache) 358 // ret.FieldValueCache = tmp 359 // } 360 361 func (ret *J2TStateMachine) SetPos(pos int) { 362 vt := ret.Now() 363 vt.JsonPos = pos 364 } 365 366 type TState struct { 367 t uint8 368 k uint8 369 v uint8 370 n int32 371 } 372 373 const ( 374 TB_SKIP_STACK_SIZE = 1024 375 ) 376 377 type TStateMachine [TB_SKIP_STACK_SIZE]TState 378 379 var tsmPool = sync.Pool{ 380 New: func() interface{} { 381 return &TStateMachine{} 382 }, 383 } 384 385 func NewTStateMachine() *TStateMachine { 386 ret := tsmPool.Get().(*TStateMachine) 387 return ret 388 } 389 390 func FreeTStateMachine(ret *TStateMachine) { 391 tsmPool.Put(ret) 392 } 393 394 const ( 395 VM_NONE uint16 = 0 396 VM_JSCONV uint16 = 101 397 )