oj_windows 3.16.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +44 -0
- data/LICENSE +21 -0
- data/README.md +164 -0
- data/ext/oj_windows/buf.h +85 -0
- data/ext/oj_windows/cache.c +339 -0
- data/ext/oj_windows/cache.h +22 -0
- data/ext/oj_windows/cache8.c +105 -0
- data/ext/oj_windows/cache8.h +21 -0
- data/ext/oj_windows/circarray.c +64 -0
- data/ext/oj_windows/circarray.h +22 -0
- data/ext/oj_windows/code.c +214 -0
- data/ext/oj_windows/code.h +40 -0
- data/ext/oj_windows/compat.c +239 -0
- data/ext/oj_windows/custom.c +1074 -0
- data/ext/oj_windows/debug.c +126 -0
- data/ext/oj_windows/dump.c +1556 -0
- data/ext/oj_windows/dump.h +110 -0
- data/ext/oj_windows/dump_compat.c +901 -0
- data/ext/oj_windows/dump_leaf.c +162 -0
- data/ext/oj_windows/dump_object.c +710 -0
- data/ext/oj_windows/dump_strict.c +405 -0
- data/ext/oj_windows/encode.h +16 -0
- data/ext/oj_windows/err.c +57 -0
- data/ext/oj_windows/err.h +67 -0
- data/ext/oj_windows/extconf.rb +77 -0
- data/ext/oj_windows/fast.c +1710 -0
- data/ext/oj_windows/intern.c +325 -0
- data/ext/oj_windows/intern.h +22 -0
- data/ext/oj_windows/mem.c +320 -0
- data/ext/oj_windows/mem.h +53 -0
- data/ext/oj_windows/mimic_json.c +919 -0
- data/ext/oj_windows/object.c +726 -0
- data/ext/oj_windows/odd.c +245 -0
- data/ext/oj_windows/odd.h +43 -0
- data/ext/oj_windows/oj.c +2097 -0
- data/ext/oj_windows/oj.h +420 -0
- data/ext/oj_windows/parse.c +1317 -0
- data/ext/oj_windows/parse.h +113 -0
- data/ext/oj_windows/parser.c +1600 -0
- data/ext/oj_windows/parser.h +103 -0
- data/ext/oj_windows/rails.c +1484 -0
- data/ext/oj_windows/rails.h +18 -0
- data/ext/oj_windows/reader.c +222 -0
- data/ext/oj_windows/reader.h +137 -0
- data/ext/oj_windows/resolve.c +80 -0
- data/ext/oj_windows/resolve.h +12 -0
- data/ext/oj_windows/rxclass.c +144 -0
- data/ext/oj_windows/rxclass.h +26 -0
- data/ext/oj_windows/saj.c +675 -0
- data/ext/oj_windows/saj2.c +584 -0
- data/ext/oj_windows/saj2.h +23 -0
- data/ext/oj_windows/scp.c +187 -0
- data/ext/oj_windows/simd.h +47 -0
- data/ext/oj_windows/sparse.c +946 -0
- data/ext/oj_windows/stream_writer.c +329 -0
- data/ext/oj_windows/strict.c +189 -0
- data/ext/oj_windows/string_writer.c +517 -0
- data/ext/oj_windows/trace.c +72 -0
- data/ext/oj_windows/trace.h +55 -0
- data/ext/oj_windows/usual.c +1218 -0
- data/ext/oj_windows/usual.h +69 -0
- data/ext/oj_windows/util.c +136 -0
- data/ext/oj_windows/util.h +20 -0
- data/ext/oj_windows/val_stack.c +101 -0
- data/ext/oj_windows/val_stack.h +151 -0
- data/ext/oj_windows/validate.c +46 -0
- data/ext/oj_windows/wab.c +584 -0
- data/lib/oj/active_support_helper.rb +39 -0
- data/lib/oj/bag.rb +95 -0
- data/lib/oj/easy_hash.rb +52 -0
- data/lib/oj/error.rb +21 -0
- data/lib/oj/json.rb +188 -0
- data/lib/oj/mimic.rb +301 -0
- data/lib/oj/saj.rb +80 -0
- data/lib/oj/schandler.rb +143 -0
- data/lib/oj/state.rb +135 -0
- data/lib/oj/version.rb +4 -0
- data/lib/oj_windows/active_support_helper.rb +39 -0
- data/lib/oj_windows/bag.rb +95 -0
- data/lib/oj_windows/easy_hash.rb +52 -0
- data/lib/oj_windows/error.rb +21 -0
- data/lib/oj_windows/json.rb +188 -0
- data/lib/oj_windows/mimic.rb +301 -0
- data/lib/oj_windows/saj.rb +80 -0
- data/lib/oj_windows/schandler.rb +143 -0
- data/lib/oj_windows/state.rb +135 -0
- data/lib/oj_windows/version.rb +4 -0
- data/lib/oj_windows.rb +15 -0
- data/pages/Advanced.md +38 -0
- data/pages/Compatibility.md +49 -0
- data/pages/Custom.md +37 -0
- data/pages/Encoding.md +61 -0
- data/pages/InstallOptions.md +20 -0
- data/pages/JsonGem.md +60 -0
- data/pages/Modes.md +94 -0
- data/pages/Options.md +339 -0
- data/pages/Parser.md +134 -0
- data/pages/Rails.md +85 -0
- data/pages/Security.md +43 -0
- data/pages/WAB.md +12 -0
- metadata +242 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) 2022, Peter Ohler, All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <stdbool.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
struct _cache;
|
|
8
|
+
struct _ojParser;
|
|
9
|
+
|
|
10
|
+
// Used to mark the start of each Hash, Array, or Object. The members point at
|
|
11
|
+
// positions of the start in the value stack and if not an Array into the key
|
|
12
|
+
// stack.
|
|
13
|
+
typedef struct _col {
|
|
14
|
+
long vi; // value stack index
|
|
15
|
+
long ki; // key stack index if an hash else -1 for an array
|
|
16
|
+
} *Col;
|
|
17
|
+
|
|
18
|
+
typedef union _key {
|
|
19
|
+
struct {
|
|
20
|
+
int16_t len;
|
|
21
|
+
char buf[30];
|
|
22
|
+
};
|
|
23
|
+
struct {
|
|
24
|
+
int16_t xlen; // should be the same as len
|
|
25
|
+
char *key;
|
|
26
|
+
};
|
|
27
|
+
} *Key;
|
|
28
|
+
|
|
29
|
+
#define MISS_AUTO 'A'
|
|
30
|
+
#define MISS_RAISE 'R'
|
|
31
|
+
#define MISS_IGNORE 'I'
|
|
32
|
+
|
|
33
|
+
typedef struct _usual {
|
|
34
|
+
VALUE *vhead;
|
|
35
|
+
VALUE *vtail;
|
|
36
|
+
VALUE *vend;
|
|
37
|
+
|
|
38
|
+
Col chead;
|
|
39
|
+
Col ctail;
|
|
40
|
+
Col cend;
|
|
41
|
+
|
|
42
|
+
Key khead;
|
|
43
|
+
Key ktail;
|
|
44
|
+
Key kend;
|
|
45
|
+
|
|
46
|
+
VALUE (*get_key)(struct _ojParser *p, Key kp);
|
|
47
|
+
struct _cache *key_cache; // same as str_cache or sym_cache
|
|
48
|
+
struct _cache *str_cache;
|
|
49
|
+
struct _cache *sym_cache;
|
|
50
|
+
struct _cache *class_cache;
|
|
51
|
+
struct _cache *attr_cache;
|
|
52
|
+
|
|
53
|
+
VALUE array_class;
|
|
54
|
+
VALUE hash_class;
|
|
55
|
+
|
|
56
|
+
char *create_id;
|
|
57
|
+
uint8_t create_id_len;
|
|
58
|
+
uint8_t cache_str;
|
|
59
|
+
uint8_t cache_xrate;
|
|
60
|
+
uint8_t miss_class;
|
|
61
|
+
bool cache_keys;
|
|
62
|
+
bool ignore_json_create;
|
|
63
|
+
bool raise_on_empty;
|
|
64
|
+
} *Usual;
|
|
65
|
+
|
|
66
|
+
// Initialize the parser with the usual delegate. If the usual delegate is
|
|
67
|
+
// wrapped then this function is called first and then the parser functions
|
|
68
|
+
// can be replaced.
|
|
69
|
+
extern void oj_init_usual(struct _ojParser *p, Usual d);
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Copyright (c) 2019 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
3
|
+
|
|
4
|
+
#include "util.h"
|
|
5
|
+
|
|
6
|
+
#include <stdbool.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include <time.h>
|
|
11
|
+
|
|
12
|
+
#define SECS_PER_DAY 86400LL
|
|
13
|
+
#define SECS_PER_YEAR 31536000LL
|
|
14
|
+
#define SECS_PER_LEAP 31622400LL
|
|
15
|
+
#define SECS_PER_QUAD_YEAR (SECS_PER_YEAR * 3 + SECS_PER_LEAP)
|
|
16
|
+
#define SECS_PER_CENT (SECS_PER_QUAD_YEAR * 24 + SECS_PER_YEAR * 4)
|
|
17
|
+
#define SECS_PER_LEAP_CENT (SECS_PER_CENT + SECS_PER_DAY)
|
|
18
|
+
#define SECS_PER_QUAD_CENT (SECS_PER_CENT * 4 + SECS_PER_DAY)
|
|
19
|
+
|
|
20
|
+
static int64_t eom_secs[] = {
|
|
21
|
+
2678400, // January (31)
|
|
22
|
+
5097600, // February (28) 2419200 2505600
|
|
23
|
+
7776000, // March (31)
|
|
24
|
+
10368000, // April (30 2592000
|
|
25
|
+
13046400, // May (31)
|
|
26
|
+
15638400, // June (30)
|
|
27
|
+
18316800, // July (31)
|
|
28
|
+
20995200, // August (31)
|
|
29
|
+
23587200, // September (30)
|
|
30
|
+
26265600, // October (31)
|
|
31
|
+
28857600, // November (30)
|
|
32
|
+
31536000, // December (31)
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
static int64_t eom_leap_secs[] = {
|
|
36
|
+
2678400, // January (31)
|
|
37
|
+
5184000, // February (28) 2419200 2505600
|
|
38
|
+
7862400, // March (31)
|
|
39
|
+
10454400, // April (30 2592000
|
|
40
|
+
13132800, // May (31)
|
|
41
|
+
15724800, // June (30)
|
|
42
|
+
18403200, // July (31)
|
|
43
|
+
21081600, // August (31)
|
|
44
|
+
23673600, // September (30)
|
|
45
|
+
26352000, // October (31)
|
|
46
|
+
28944000, // November (30)
|
|
47
|
+
31622400, // December (31)
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
void sec_as_time(int64_t secs, TimeInfo ti) {
|
|
51
|
+
int64_t qc = 0;
|
|
52
|
+
int64_t c = 0;
|
|
53
|
+
int64_t qy = 0;
|
|
54
|
+
int64_t y = 0;
|
|
55
|
+
bool leap = false;
|
|
56
|
+
int64_t *ms;
|
|
57
|
+
int m;
|
|
58
|
+
int shift = 0;
|
|
59
|
+
|
|
60
|
+
secs += 62167219200LL; // normalize to first day of the year 0
|
|
61
|
+
if (secs < 0) {
|
|
62
|
+
shift = -secs / SECS_PER_QUAD_CENT;
|
|
63
|
+
shift++;
|
|
64
|
+
secs += shift * SECS_PER_QUAD_CENT;
|
|
65
|
+
}
|
|
66
|
+
qc = secs / SECS_PER_QUAD_CENT;
|
|
67
|
+
secs = secs - qc * SECS_PER_QUAD_CENT;
|
|
68
|
+
if (secs < SECS_PER_LEAP) {
|
|
69
|
+
leap = true;
|
|
70
|
+
} else if (secs < SECS_PER_QUAD_YEAR) {
|
|
71
|
+
if (SECS_PER_LEAP <= secs) {
|
|
72
|
+
secs -= SECS_PER_LEAP;
|
|
73
|
+
y = secs / SECS_PER_YEAR;
|
|
74
|
+
secs = secs - y * SECS_PER_YEAR;
|
|
75
|
+
y++;
|
|
76
|
+
leap = false;
|
|
77
|
+
}
|
|
78
|
+
} else if (secs < SECS_PER_LEAP_CENT) { // first century in 400 years is a leap century (one
|
|
79
|
+
// extra day)
|
|
80
|
+
qy = secs / SECS_PER_QUAD_YEAR;
|
|
81
|
+
secs = secs - qy * SECS_PER_QUAD_YEAR;
|
|
82
|
+
if (secs < SECS_PER_LEAP) {
|
|
83
|
+
leap = true;
|
|
84
|
+
} else {
|
|
85
|
+
secs -= SECS_PER_LEAP;
|
|
86
|
+
y = secs / SECS_PER_YEAR;
|
|
87
|
+
secs = secs - y * SECS_PER_YEAR;
|
|
88
|
+
y++;
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
secs -= SECS_PER_LEAP_CENT;
|
|
92
|
+
c = secs / SECS_PER_CENT;
|
|
93
|
+
secs = secs - c * SECS_PER_CENT;
|
|
94
|
+
c++;
|
|
95
|
+
if (secs < SECS_PER_YEAR * 4) {
|
|
96
|
+
y = secs / SECS_PER_YEAR;
|
|
97
|
+
secs = secs - y * SECS_PER_YEAR;
|
|
98
|
+
} else {
|
|
99
|
+
secs -= SECS_PER_YEAR * 4;
|
|
100
|
+
qy = secs / SECS_PER_QUAD_YEAR;
|
|
101
|
+
secs = secs - qy * SECS_PER_QUAD_YEAR;
|
|
102
|
+
qy++;
|
|
103
|
+
if (secs < SECS_PER_LEAP) {
|
|
104
|
+
leap = true;
|
|
105
|
+
} else {
|
|
106
|
+
secs -= SECS_PER_LEAP;
|
|
107
|
+
y = secs / SECS_PER_YEAR;
|
|
108
|
+
secs = secs - y * SECS_PER_YEAR;
|
|
109
|
+
y++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
ti->year = (int)((qc - (int64_t)shift) * 400 + c * 100 + qy * 4 + y);
|
|
114
|
+
if (leap) {
|
|
115
|
+
ms = eom_leap_secs;
|
|
116
|
+
} else {
|
|
117
|
+
ms = eom_secs;
|
|
118
|
+
}
|
|
119
|
+
for (m = 1; m <= 12; m++, ms++) {
|
|
120
|
+
if (secs < *ms) {
|
|
121
|
+
if (1 < m) {
|
|
122
|
+
secs -= *(ms - 1);
|
|
123
|
+
}
|
|
124
|
+
ti->mon = m;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
ti->day = (int)(secs / 86400LL);
|
|
129
|
+
secs = secs - (int64_t)ti->day * 86400LL;
|
|
130
|
+
ti->day++;
|
|
131
|
+
ti->hour = (int)(secs / 3600LL);
|
|
132
|
+
secs = secs - (int64_t)ti->hour * 3600LL;
|
|
133
|
+
ti->min = (int)(secs / 60LL);
|
|
134
|
+
secs = secs - (int64_t)ti->min * 60LL;
|
|
135
|
+
ti->sec = (int)secs;
|
|
136
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright (c) 2019 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
3
|
+
|
|
4
|
+
#ifndef OJ_UTIL_H
|
|
5
|
+
#define OJ_UTIL_H
|
|
6
|
+
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
typedef struct _timeInfo {
|
|
10
|
+
int sec;
|
|
11
|
+
int min;
|
|
12
|
+
int hour;
|
|
13
|
+
int day;
|
|
14
|
+
int mon;
|
|
15
|
+
int year;
|
|
16
|
+
}* TimeInfo;
|
|
17
|
+
|
|
18
|
+
extern void sec_as_time(int64_t secs, TimeInfo ti);
|
|
19
|
+
|
|
20
|
+
#endif /* OJ_UTIL_H */
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
3
|
+
|
|
4
|
+
#include "val_stack.h"
|
|
5
|
+
|
|
6
|
+
#include <string.h>
|
|
7
|
+
|
|
8
|
+
#include "odd.h"
|
|
9
|
+
#include "oj.h"
|
|
10
|
+
|
|
11
|
+
static void stack_mark(void *ptr) {
|
|
12
|
+
ValStack stack = (ValStack)ptr;
|
|
13
|
+
Val v;
|
|
14
|
+
|
|
15
|
+
if (NULL == ptr) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
19
|
+
pthread_mutex_lock(&stack->mutex);
|
|
20
|
+
#else
|
|
21
|
+
rb_mutex_lock(stack->mutex);
|
|
22
|
+
rb_gc_mark(stack->mutex);
|
|
23
|
+
#endif
|
|
24
|
+
for (v = stack->head; v < stack->tail; v++) {
|
|
25
|
+
if (Qnil != v->val && Qundef != v->val) {
|
|
26
|
+
rb_gc_mark(v->val);
|
|
27
|
+
}
|
|
28
|
+
if (Qnil != v->key_val && Qundef != v->key_val) {
|
|
29
|
+
rb_gc_mark(v->key_val);
|
|
30
|
+
}
|
|
31
|
+
if (NULL != v->odd_args) {
|
|
32
|
+
VALUE *a;
|
|
33
|
+
int i;
|
|
34
|
+
|
|
35
|
+
for (i = v->odd_args->odd->attr_cnt, a = v->odd_args->args; 0 < i; i--, a++) {
|
|
36
|
+
if (Qnil != *a) {
|
|
37
|
+
rb_gc_mark(*a);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
43
|
+
pthread_mutex_unlock(&stack->mutex);
|
|
44
|
+
#else
|
|
45
|
+
rb_mutex_unlock(stack->mutex);
|
|
46
|
+
#endif
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static const rb_data_type_t oj_stack_type = {
|
|
50
|
+
"oj_windows/stack",
|
|
51
|
+
{
|
|
52
|
+
stack_mark,
|
|
53
|
+
NULL,
|
|
54
|
+
NULL,
|
|
55
|
+
},
|
|
56
|
+
0,
|
|
57
|
+
0,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
VALUE
|
|
61
|
+
oj_stack_init(ValStack stack) {
|
|
62
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
63
|
+
int err;
|
|
64
|
+
|
|
65
|
+
if (0 != (err = pthread_mutex_init(&stack->mutex, 0))) {
|
|
66
|
+
rb_raise(rb_eException, "failed to initialize a mutex. %s", strerror(err));
|
|
67
|
+
}
|
|
68
|
+
#else
|
|
69
|
+
stack->mutex = rb_mutex_new();
|
|
70
|
+
#endif
|
|
71
|
+
stack->head = stack->base;
|
|
72
|
+
stack->end = stack->base + sizeof(stack->base) / sizeof(struct _val);
|
|
73
|
+
stack->tail = stack->head;
|
|
74
|
+
stack->head->val = Qundef;
|
|
75
|
+
stack->head->key = NULL;
|
|
76
|
+
stack->head->key_val = Qundef;
|
|
77
|
+
stack->head->classname = NULL;
|
|
78
|
+
stack->head->odd_args = NULL;
|
|
79
|
+
stack->head->clas = Qundef;
|
|
80
|
+
stack->head->klen = 0;
|
|
81
|
+
stack->head->clen = 0;
|
|
82
|
+
stack->head->next = NEXT_NONE;
|
|
83
|
+
|
|
84
|
+
return TypedData_Wrap_Struct(oj_cstack_class, &oj_stack_type, stack);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const char *oj_stack_next_string(ValNext n) {
|
|
88
|
+
switch (n) {
|
|
89
|
+
case NEXT_ARRAY_NEW: return "array element or close";
|
|
90
|
+
case NEXT_ARRAY_ELEMENT: return "array element";
|
|
91
|
+
case NEXT_ARRAY_COMMA: return "comma";
|
|
92
|
+
case NEXT_HASH_NEW: return "hash pair or close";
|
|
93
|
+
case NEXT_HASH_KEY: return "hash key";
|
|
94
|
+
case NEXT_HASH_COLON: return "colon";
|
|
95
|
+
case NEXT_HASH_VALUE: return "hash value";
|
|
96
|
+
case NEXT_HASH_COMMA: return "comma";
|
|
97
|
+
case NEXT_NONE: break;
|
|
98
|
+
default: break;
|
|
99
|
+
}
|
|
100
|
+
return "nothing";
|
|
101
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// Copyright (c) 2011 Peter Ohler. All rights reserved.
|
|
2
|
+
// Licensed under the MIT License. See LICENSE file in the project root for license details.
|
|
3
|
+
|
|
4
|
+
#ifndef OJ_VAL_STACK_H
|
|
5
|
+
#define OJ_VAL_STACK_H
|
|
6
|
+
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
#include "mem.h"
|
|
10
|
+
#include "odd.h"
|
|
11
|
+
#include "ruby.h"
|
|
12
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
13
|
+
#include <pthread.h>
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
#define STACK_INC 64
|
|
17
|
+
|
|
18
|
+
typedef enum {
|
|
19
|
+
NEXT_NONE = 0,
|
|
20
|
+
NEXT_ARRAY_NEW = 'a',
|
|
21
|
+
NEXT_ARRAY_ELEMENT = 'e',
|
|
22
|
+
NEXT_ARRAY_COMMA = ',',
|
|
23
|
+
NEXT_HASH_NEW = 'h',
|
|
24
|
+
NEXT_HASH_KEY = 'k',
|
|
25
|
+
NEXT_HASH_COLON = ':',
|
|
26
|
+
NEXT_HASH_VALUE = 'v',
|
|
27
|
+
NEXT_HASH_COMMA = 'n',
|
|
28
|
+
} ValNext;
|
|
29
|
+
|
|
30
|
+
typedef struct _val {
|
|
31
|
+
volatile VALUE val;
|
|
32
|
+
const char *key;
|
|
33
|
+
char karray[32];
|
|
34
|
+
volatile VALUE key_val;
|
|
35
|
+
const char *classname;
|
|
36
|
+
VALUE clas;
|
|
37
|
+
OddArgs odd_args;
|
|
38
|
+
uint16_t klen;
|
|
39
|
+
uint16_t clen;
|
|
40
|
+
char next; // ValNext
|
|
41
|
+
char k1; // first original character in the key
|
|
42
|
+
char kalloc;
|
|
43
|
+
} *Val;
|
|
44
|
+
|
|
45
|
+
typedef struct _valStack {
|
|
46
|
+
struct _val base[STACK_INC];
|
|
47
|
+
Val head; // current stack
|
|
48
|
+
Val end; // stack end
|
|
49
|
+
Val tail; // pointer to one past last element name on stack
|
|
50
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
51
|
+
pthread_mutex_t mutex;
|
|
52
|
+
#else
|
|
53
|
+
VALUE mutex;
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
} *ValStack;
|
|
57
|
+
|
|
58
|
+
extern VALUE oj_stack_init(ValStack stack);
|
|
59
|
+
|
|
60
|
+
inline static int stack_empty(ValStack stack) {
|
|
61
|
+
return (stack->head == stack->tail);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
inline static void stack_cleanup(ValStack stack) {
|
|
65
|
+
if (stack->base != stack->head) {
|
|
66
|
+
OJ_R_FREE(stack->head);
|
|
67
|
+
stack->head = NULL;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
inline static void stack_push(ValStack stack, VALUE val, ValNext next) {
|
|
72
|
+
if (stack->end <= stack->tail) {
|
|
73
|
+
size_t len = stack->end - stack->head;
|
|
74
|
+
size_t toff = stack->tail - stack->head;
|
|
75
|
+
Val head = stack->head;
|
|
76
|
+
|
|
77
|
+
// A realloc can trigger a GC so make sure it happens outside the lock
|
|
78
|
+
// but lock before changing pointers.
|
|
79
|
+
if (stack->base == stack->head) {
|
|
80
|
+
head = OJ_R_ALLOC_N(struct _val, len + STACK_INC);
|
|
81
|
+
memcpy(head, stack->base, sizeof(struct _val) * len);
|
|
82
|
+
} else {
|
|
83
|
+
OJ_R_REALLOC_N(head, struct _val, len + STACK_INC);
|
|
84
|
+
}
|
|
85
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
86
|
+
pthread_mutex_lock(&stack->mutex);
|
|
87
|
+
#else
|
|
88
|
+
rb_mutex_lock(stack->mutex);
|
|
89
|
+
#endif
|
|
90
|
+
stack->head = head;
|
|
91
|
+
stack->tail = stack->head + toff;
|
|
92
|
+
stack->end = stack->head + len + STACK_INC;
|
|
93
|
+
#ifdef HAVE_PTHREAD_MUTEX_INIT
|
|
94
|
+
pthread_mutex_unlock(&stack->mutex);
|
|
95
|
+
#else
|
|
96
|
+
rb_mutex_unlock(stack->mutex);
|
|
97
|
+
#endif
|
|
98
|
+
}
|
|
99
|
+
stack->tail->val = val;
|
|
100
|
+
stack->tail->next = next;
|
|
101
|
+
stack->tail->classname = NULL;
|
|
102
|
+
stack->tail->clas = Qundef;
|
|
103
|
+
stack->tail->odd_args = NULL;
|
|
104
|
+
stack->tail->key = 0;
|
|
105
|
+
stack->tail->key_val = Qundef;
|
|
106
|
+
stack->tail->clen = 0;
|
|
107
|
+
stack->tail->klen = 0;
|
|
108
|
+
stack->tail->kalloc = 0;
|
|
109
|
+
stack->tail++;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
inline static size_t stack_size(ValStack stack) {
|
|
113
|
+
return stack->tail - stack->head;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
inline static Val stack_peek(ValStack stack) {
|
|
117
|
+
if (stack->head < stack->tail) {
|
|
118
|
+
return stack->tail - 1;
|
|
119
|
+
}
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
inline static Val stack_peek_up(ValStack stack) {
|
|
124
|
+
if (stack->head < stack->tail - 1) {
|
|
125
|
+
return stack->tail - 2;
|
|
126
|
+
}
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
inline static Val stack_prev(ValStack stack) {
|
|
131
|
+
return stack->tail;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
inline static VALUE stack_head_val(ValStack stack) {
|
|
135
|
+
if (Qundef != stack->head->val) {
|
|
136
|
+
return stack->head->val;
|
|
137
|
+
}
|
|
138
|
+
return Qnil;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
inline static Val stack_pop(ValStack stack) {
|
|
142
|
+
if (stack->head < stack->tail) {
|
|
143
|
+
stack->tail--;
|
|
144
|
+
return stack->tail;
|
|
145
|
+
}
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
extern const char *oj_stack_next_string(ValNext n);
|
|
150
|
+
|
|
151
|
+
#endif /* OJ_VAL_STACK_H */
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright (c) 2021, Peter Ohler, All rights reserved.
|
|
2
|
+
|
|
3
|
+
#include "parser.h"
|
|
4
|
+
|
|
5
|
+
static void noop(ojParser p) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
static VALUE option(ojParser p, const char *key, VALUE value) {
|
|
9
|
+
rb_raise(rb_eArgError, "%s is not an option for the validate delegate", key);
|
|
10
|
+
return Qnil;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static VALUE result(ojParser p) {
|
|
14
|
+
return Qnil;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static void dfree(ojParser p) {
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static void mark(ojParser p) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
void oj_set_parser_validator(ojParser p) {
|
|
24
|
+
Funcs end = p->funcs + 3;
|
|
25
|
+
Funcs f;
|
|
26
|
+
p->ctx = NULL;
|
|
27
|
+
|
|
28
|
+
for (f = p->funcs; f < end; f++) {
|
|
29
|
+
f->add_null = noop;
|
|
30
|
+
f->add_true = noop;
|
|
31
|
+
f->add_false = noop;
|
|
32
|
+
f->add_int = noop;
|
|
33
|
+
f->add_float = noop;
|
|
34
|
+
f->add_big = noop;
|
|
35
|
+
f->add_str = noop;
|
|
36
|
+
f->open_array = noop;
|
|
37
|
+
f->close_array = noop;
|
|
38
|
+
f->open_object = noop;
|
|
39
|
+
f->close_object = noop;
|
|
40
|
+
}
|
|
41
|
+
p->option = option;
|
|
42
|
+
p->result = result;
|
|
43
|
+
p->free = dfree;
|
|
44
|
+
p->mark = mark;
|
|
45
|
+
p->start = noop;
|
|
46
|
+
}
|