oj-introspect 0.3.0 → 0.5.0
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 +4 -4
- data/Gemfile.lock +1 -1
- data/bin/benchmark +7 -2
- data/ext/oj-introspect/extconf.rb +1 -1
- data/ext/oj-introspect/introspect.c +79 -1
- data/lib/oj/introspect/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a72b92485dbfef2a4b2fe110e3209d277c1cb98a356648d5c37d65015906b1b
|
4
|
+
data.tar.gz: 9d8047afdd2b9434fd257f05eb3bafef180c57a3b7c8e5a873bdf954dfd2dfab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42c8c6afb2256ae41a156892379fa8535f3944f457105db6d6f6b1581008dccc2ba76e413eef725428ea70d384b69ae3d6a8657d745a3eedda7997d1da13910a
|
7
|
+
data.tar.gz: 12446b7a5f18442a2dd7695823b08ebe331a71d707583342f8b9d7034a0acef529df8368cf490b2928da6ae4d31f673783075b3a24d3f302b6dbe8aab34a8db9
|
data/Gemfile.lock
CHANGED
data/bin/benchmark
CHANGED
@@ -5,16 +5,21 @@ require "oj/introspect"
|
|
5
5
|
require "json"
|
6
6
|
require "benchmark/ips"
|
7
7
|
|
8
|
-
TEST_JSON =
|
8
|
+
TEST_JSON = File.read("./spec/fixtures/vulnerabilities.json")
|
9
9
|
|
10
10
|
INTROSPECT_PARSER = Oj::Parser.introspect
|
11
|
+
FILTERED_INTROSPECT_PARSER = Oj::Introspect.new(filter: "remediations")
|
11
12
|
USUAL_PARSER = Oj::Parser.usual
|
12
13
|
|
13
14
|
Benchmark.ips do |b|
|
14
|
-
b.report("
|
15
|
+
b.report("Introspect") do
|
15
16
|
INTROSPECT_PARSER.parse(TEST_JSON)
|
16
17
|
end
|
17
18
|
|
19
|
+
b.report("Filtered introspect") do
|
20
|
+
FILTERED_INTROSPECT_PARSER.parse(TEST_JSON)
|
21
|
+
end
|
22
|
+
|
18
23
|
b.report("Oj usual") do
|
19
24
|
USUAL_PARSER.parse(TEST_JSON)
|
20
25
|
end
|
@@ -16,16 +16,22 @@ typedef struct _introspect_S {
|
|
16
16
|
struct _usual usual; // inherit all the attributes from `_usual` struct
|
17
17
|
struct _byte_offsets byte_offsets; // I think it's better to encapsulate common fields under a namespace
|
18
18
|
|
19
|
+
char *filter;
|
20
|
+
bool introspect;
|
21
|
+
|
19
22
|
void (*delegated_start_func)(struct _ojParser *p);
|
20
23
|
void (*delegated_free_func)(struct _ojParser *p);
|
24
|
+
VALUE (*delegated_option_func)(struct _ojParser *p, const char *key, VALUE value);
|
21
25
|
void (*delegated_open_object_func)(struct _ojParser *p);
|
22
26
|
void (*delegated_open_object_key_func)(struct _ojParser *p);
|
27
|
+
void (*delegated_open_array_key_func)(struct _ojParser *p);
|
23
28
|
void (*delegated_close_object_func)(struct _ojParser *p);
|
24
|
-
} *IntrospectDelegate;
|
29
|
+
} * IntrospectDelegate;
|
25
30
|
|
26
31
|
static void dfree(ojParser p) {
|
27
32
|
IntrospectDelegate d = (IntrospectDelegate)p->ctx;
|
28
33
|
|
34
|
+
if(d->filter != NULL) xfree(d->filter);
|
29
35
|
xfree(d->byte_offsets.stack);
|
30
36
|
d->delegated_free_func(p);
|
31
37
|
}
|
@@ -36,6 +42,31 @@ static void start(ojParser p) {
|
|
36
42
|
d->delegated_start_func(p);
|
37
43
|
// Reset to zero so the parser and delegate can be reused.
|
38
44
|
d->byte_offsets.current = 0;
|
45
|
+
|
46
|
+
/*
|
47
|
+
* If the `filter` is provided we will start introspecting later
|
48
|
+
* once we encounter with the key provided.
|
49
|
+
*/
|
50
|
+
d->introspect = (d->filter == NULL);
|
51
|
+
}
|
52
|
+
|
53
|
+
static void copy_ruby_str(char **target, VALUE source) {
|
54
|
+
size_t len = RSTRING_LEN(source);
|
55
|
+
*target = ALLOC_N(char, len + 1);
|
56
|
+
memcpy(*target, RSTRING_PTR(source), len);
|
57
|
+
(*target)[len] = '\0'; // Parantheses are important as it means => (*target + sizeof(char) * len)
|
58
|
+
}
|
59
|
+
|
60
|
+
static VALUE option(ojParser p, const char *key, VALUE value) {
|
61
|
+
IntrospectDelegate d = (IntrospectDelegate)p->ctx;
|
62
|
+
|
63
|
+
if(strcmp(key, "filter=") == 0) {
|
64
|
+
copy_ruby_str(&d->filter, value); // We need to copy the value as GC can free it later.
|
65
|
+
|
66
|
+
return Qtrue;
|
67
|
+
}
|
68
|
+
|
69
|
+
return d->delegated_option_func(p, key, value);
|
39
70
|
}
|
40
71
|
|
41
72
|
static void ensure_byte_offsets_stack(IntrospectDelegate d) {
|
@@ -65,16 +96,56 @@ static void open_object_introspected(ojParser p) {
|
|
65
96
|
d->delegated_open_object_func(p);
|
66
97
|
}
|
67
98
|
|
99
|
+
static char * previously_inserted_key(IntrospectDelegate d) {
|
100
|
+
Key key = (d->usual.ktail - 1);
|
101
|
+
|
102
|
+
return ((size_t)key->len < sizeof(key->buf)) ? key->buf : key->key;
|
103
|
+
}
|
104
|
+
|
105
|
+
static bool should_switch_introspection(IntrospectDelegate d) {
|
106
|
+
return strcmp(d->filter, previously_inserted_key(d)) == 0;
|
107
|
+
}
|
108
|
+
|
109
|
+
/*
|
110
|
+
* WHEN there is a filter
|
111
|
+
* AND
|
112
|
+
* WHEN the introspection is disabled
|
113
|
+
* AND the last inserted key matches the filter
|
114
|
+
* THEN enable introspection
|
115
|
+
* OR
|
116
|
+
* WHEN the introspection is enabled
|
117
|
+
* AND the last inserted key matches the filter
|
118
|
+
* THEN disable introspection
|
119
|
+
*/
|
120
|
+
static void switch_introspection(IntrospectDelegate d) {
|
121
|
+
if(d->filter == NULL) return;
|
122
|
+
|
123
|
+
d->introspect = should_switch_introspection(d) != d->introspect; // a XOR b
|
124
|
+
}
|
125
|
+
|
68
126
|
static void open_object_key_introspected(ojParser p) {
|
69
127
|
push(p);
|
70
128
|
|
71
129
|
IntrospectDelegate d = (IntrospectDelegate)p->ctx;
|
72
130
|
d->delegated_open_object_key_func(p);
|
131
|
+
|
132
|
+
if(!d->introspect) switch_introspection(d);
|
133
|
+
}
|
134
|
+
|
135
|
+
static void open_array_key_introspected(ojParser p) {
|
136
|
+
IntrospectDelegate d = (IntrospectDelegate)p->ctx;
|
137
|
+
d->delegated_open_array_key_func(p);
|
138
|
+
|
139
|
+
if(!d->introspect) switch_introspection(d);
|
73
140
|
}
|
74
141
|
|
75
142
|
static void set_introspection_values(ojParser p) {
|
76
143
|
IntrospectDelegate d = (IntrospectDelegate)p->ctx;
|
77
144
|
|
145
|
+
if(!d->introspect) return;
|
146
|
+
|
147
|
+
switch_introspection(d);
|
148
|
+
|
78
149
|
volatile VALUE obj = rb_hash_new();
|
79
150
|
rb_hash_aset(obj, ID2SYM(rb_intern("start_byte")), INT2FIX(pop(p)));
|
80
151
|
rb_hash_aset(obj, ID2SYM(rb_intern("end_byte")), INT2FIX(p->cur));
|
@@ -100,6 +171,9 @@ static void init_introspect_parser(ojParser p, VALUE ropts) {
|
|
100
171
|
d->delegated_start_func = p->start;
|
101
172
|
p->start = start;
|
102
173
|
|
174
|
+
d->delegated_option_func = p->option;
|
175
|
+
p->option = option;
|
176
|
+
|
103
177
|
// We are cheating with the mark, free, and options functions. Since struct
|
104
178
|
// _usual is the first member of struct _introspect the cast to Usual in the
|
105
179
|
// usual.c mark() function should still work just fine.
|
@@ -117,7 +191,9 @@ static void init_introspect_parser(ojParser p, VALUE ropts) {
|
|
117
191
|
f->close_object = close_object_introspected;
|
118
192
|
|
119
193
|
f = &p->funcs[OBJECT_FUN];
|
194
|
+
d->delegated_open_array_key_func = f->open_array;
|
120
195
|
d->delegated_open_object_key_func = f->open_object;
|
196
|
+
f->open_array = open_array_key_introspected;
|
121
197
|
f->open_object = open_object_key_introspected;
|
122
198
|
f->close_object = close_object_introspected;
|
123
199
|
|
@@ -126,6 +202,8 @@ static void init_introspect_parser(ojParser p, VALUE ropts) {
|
|
126
202
|
d->byte_offsets.stack = ALLOC_N(long, BYTE_OFFSETS_STACK_INC_SIZE);
|
127
203
|
d->byte_offsets.length = BYTE_OFFSETS_STACK_INC_SIZE;
|
128
204
|
|
205
|
+
d->filter = NULL;
|
206
|
+
|
129
207
|
// Process options.
|
130
208
|
oj_parser_set_option(p, ropts);
|
131
209
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oj-introspect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mehmet Emin INAC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|