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#ifndef NATIVE_H
18#define NATIVE_H
19
20#include <stdint.h>
21#include <sys/types.h>
22#include <immintrin.h>
23#include <stdbool.h>
24
25#include "types.h"
26
27#define likely(v) (__builtin_expect((v), 1))
28#define unlikely(v) (__builtin_expect((v), 0))
29#define always_inline inline __attribute__((always_inline))
30
31#define as_m128p(v) ((__m128i *)(v))
32#define as_m128c(v) ((const __m128i *)(v))
33#define as_m256c(v) ((const __m256i *)(v))
34#define as_m128v(v) (*(const __m128i *)(v))
35#define as_uint64v(p) (*(uint64_t *)(p))
36#define is_infinity(v) ((as_uint64v(&v) << 1) == 0xFFE0000000000000)
37
38typedef struct {
39 void * buf;
40 size_t len;
41 size_t cap;
42} GoSlice;
43
44static const uint8_t GO_KIND_MASK = (1 << 5) - 1;
45typedef enum {
46 Invalid = 0,
47 Bool,
48 Int,
49 Int8,
50 Int16,
51 Int32,
52 Int64,
53 Uint,
54 Uint8,
55 Uint16,
56 Uint32,
57 Uint64,
58 Uintptr,
59 Float32,
60 Float64,
61 Complex64,
62 Complex128,
63 Array,
64 Chan,
65 Func,
66 Interface,
67 Map,
68 Pointer,
69 Slice,
70 String,
71 Struct,
72 UnsafePointer,
73} GoKind;
74
75typedef struct {
76 uint64_t size;
77 uint64_t ptr_data;
78 uint32_t hash;
79 uint8_t flags;
80 uint8_t align;
81 uint8_t filed_align;
82 uint8_t kind_flags;
83 uint64_t traits;
84 void* gc_data;
85 int32_t str;
86 int32_t ptr_to_self;
87} GoType;
88
89typedef struct {
90 GoType * type;
91 void * value;
92} GoIface;
93
94typedef struct {
95 const char * buf;
96 size_t len;
97} GoString;
98
99typedef struct {
100 long t;
101 double d;
102 int64_t i;
103} JsonNumber;
104
105typedef struct {
106 long vt;
107 double dv;
108 int64_t iv;
109 int64_t ep;
110 char* dbuf;
111 ssize_t dcap;
112} JsonState;
113
114typedef struct {
115 int64_t sp;
116 int64_t vt[MAX_RECURSE];
117} StateMachine;
118
119int f64toa(char *out, double val);
120int i64toa(char *out, int64_t val);
121int u64toa(char *out, uint64_t val);
122
123size_t lspace(const char *sp, size_t nb, size_t p);
124
125ssize_t quote(const char *sp, ssize_t nb, char *dp, ssize_t *dn, uint64_t flags);
126ssize_t unquote(const char *sp, ssize_t nb, char *dp, ssize_t *ep, uint64_t flags);
127ssize_t html_escape(const char *sp, ssize_t nb, char *dp, ssize_t *dn);
128
129long value(const char *s, size_t n, long p, JsonState *ret, uint64_t flags);
130void vstring(const GoString *src, long *p, JsonState *ret, uint64_t flags);
131void vnumber(const GoString *src, long *p, JsonState *ret);
132void vsigned(const GoString *src, long *p, JsonState *ret);
133void vunsigned(const GoString *src, long *p, JsonState *ret);
134
135long skip_one(const GoString *src, long *p, StateMachine *m, uint64_t flags);
136long skip_array(const GoString *src, long *p, StateMachine *m, uint64_t flags);
137long skip_object(const GoString *src, long *p, StateMachine *m, uint64_t flags);
138
139long skip_string(const GoString *src, long *p, uint64_t flags);
140long skip_negative(const GoString *src, long *p);
141long skip_positive(const GoString *src, long *p);
142long skip_number(const GoString *src, long *p);
143
144bool atof_eisel_lemire64(uint64_t mant, int exp10, int sgn, double *val);
145double atof_native(const char *sp, ssize_t nb, char *dbuf, ssize_t cap);
146
147long validate_string(const GoString *src, long *p);
148long validate_one(const GoString *src, long *p, StateMachine *m);
149long validate_utf8(const GoString *src, long *p, StateMachine *m);
150long validate_utf8_fast(const GoString *src);
151
152long skip_one_fast(const GoString *src, long *p);
153long get_by_path(const GoString *src, long *p, const GoSlice *path, StateMachine* sm);
154#endif
View as plain text