jsonsl 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +68 -0
- data/.travis.yml +5 -0
- data/Gemfile +19 -0
- data/LICENSE +202 -0
- data/README.md +39 -0
- data/Rakefile +54 -0
- data/bin/console +23 -0
- data/bin/setup +23 -0
- data/ext/jsonsl_ext/extconf.rb +47 -0
- data/ext/jsonsl_ext/jsonsl.LICENSE +20 -0
- data/ext/jsonsl_ext/jsonsl.c +1666 -0
- data/ext/jsonsl_ext/jsonsl.h +1009 -0
- data/ext/jsonsl_ext/jsonsl.h.patch +14 -0
- data/ext/jsonsl_ext/jsonsl.rev +1 -0
- data/ext/jsonsl_ext/jsonsl_ext.c +164 -0
- data/ext/jsonsl_ext/jsonsl_ext.h +36 -0
- data/ext/jsonsl_ext/jsonsl_row_parser.c +271 -0
- data/jsonsl.gemspec +42 -0
- data/lib/jsonsl.rb +22 -0
- data/lib/jsonsl/error.rb +21 -0
- data/lib/jsonsl/version.rb +19 -0
- metadata +107 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
--- jsonsl.h.orig 2018-08-08 22:32:20.688856662 +0300
|
2
|
+
+++ jsonsl.h 2018-08-08 22:34:01.616759720 +0300
|
3
|
+
@@ -12,6 +12,11 @@
|
4
|
+
#ifndef JSONSL_H_
|
5
|
+
#define JSONSL_H_
|
6
|
+
|
7
|
+
+#include <ruby.h>
|
8
|
+
+#define JSONSL_STATE_USER_FIELDS \
|
9
|
+
+ VALUE val; \
|
10
|
+
+ VALUE pkey;
|
11
|
+
+
|
12
|
+
#include <stdio.h>
|
13
|
+
#include <stdlib.h>
|
14
|
+
#include <stddef.h>
|
@@ -0,0 +1 @@
|
|
1
|
+
684b60f9af68b8c397422e74d0c2dd206de16a2c
|
@@ -0,0 +1,164 @@
|
|
1
|
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Author:: Couchbase <info@couchbase.com>
|
4
|
+
* Copyright:: 2018 Couchbase, Inc.
|
5
|
+
* License:: Apache License, Version 2.0
|
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
|
+
#include "jsonsl_ext.h"
|
21
|
+
|
22
|
+
VALUE jsl_mJSONSL;
|
23
|
+
VALUE jsl_eError;
|
24
|
+
|
25
|
+
void jsl_raise_at(jsonsl_error_t code, const char *message, const char *file, int line)
|
26
|
+
{
|
27
|
+
VALUE exc, str;
|
28
|
+
|
29
|
+
str = rb_str_new_cstr(message);
|
30
|
+
if (code > 0) {
|
31
|
+
rb_str_catf(str, ": (0x%02x) \"%s\"", (int)code, jsonsl_strerror(code));
|
32
|
+
}
|
33
|
+
rb_str_buf_cat_ascii(str, " [");
|
34
|
+
while (*file == '.' || *file == '/') {
|
35
|
+
file++;
|
36
|
+
}
|
37
|
+
rb_str_buf_cat_ascii(str, file);
|
38
|
+
rb_str_catf(str, ":%d]", line);
|
39
|
+
exc = rb_exc_new3(jsl_eError, str);
|
40
|
+
rb_ivar_set(exc, rb_intern("@code"), INT2FIX(code));
|
41
|
+
rb_exc_raise(exc);
|
42
|
+
}
|
43
|
+
|
44
|
+
static int jsl_jsonsl_error_callback(jsonsl_t jsn, jsonsl_error_t err, struct jsonsl_state_st *state, char *at)
|
45
|
+
{
|
46
|
+
char buf[30] = {0};
|
47
|
+
sprintf(buf, "error at %d position", (int)jsn->pos);
|
48
|
+
jsl_raise(err, buf);
|
49
|
+
(void)at;
|
50
|
+
(void)state;
|
51
|
+
return 0;
|
52
|
+
}
|
53
|
+
|
54
|
+
static void jsl_jsonsl_push_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
55
|
+
const jsonsl_char_t *at)
|
56
|
+
{
|
57
|
+
switch (state->type) {
|
58
|
+
case JSONSL_T_SPECIAL:
|
59
|
+
case JSONSL_T_STRING:
|
60
|
+
break;
|
61
|
+
case JSONSL_T_HKEY:
|
62
|
+
break;
|
63
|
+
case JSONSL_T_LIST:
|
64
|
+
state->val = rb_ary_new();
|
65
|
+
break;
|
66
|
+
case JSONSL_T_OBJECT:
|
67
|
+
state->val = rb_hash_new();
|
68
|
+
break;
|
69
|
+
default:
|
70
|
+
jsl_raise_msg("unexpected state type in POP callback");
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
(void)at;
|
74
|
+
(void)jsn;
|
75
|
+
(void)action;
|
76
|
+
}
|
77
|
+
|
78
|
+
static void jsl_jsonsl_pop_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
79
|
+
const jsonsl_char_t *at)
|
80
|
+
{
|
81
|
+
struct jsonsl_state_st *last_state = jsonsl_last_state(jsn, state);
|
82
|
+
VALUE val = Qnil;
|
83
|
+
|
84
|
+
switch (state->type) {
|
85
|
+
case JSONSL_T_SPECIAL:
|
86
|
+
if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) {
|
87
|
+
val = rb_float_new(strtod((char *)jsn->base + state->pos_begin, NULL));
|
88
|
+
} else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
|
89
|
+
val = rb_cstr2inum((char *)jsn->base + state->pos_begin, 10);
|
90
|
+
} else if (state->special_flags & JSONSL_SPECIALf_TRUE) {
|
91
|
+
val = Qtrue;
|
92
|
+
} else if (state->special_flags & JSONSL_SPECIALf_FALSE) {
|
93
|
+
val = Qfalse;
|
94
|
+
} else if (state->special_flags & JSONSL_SPECIALf_NULL) {
|
95
|
+
val = Qnil;
|
96
|
+
} else {
|
97
|
+
jsl_raise_msg("invalid special value");
|
98
|
+
}
|
99
|
+
break;
|
100
|
+
case JSONSL_T_STRING:
|
101
|
+
val = rb_str_new((char *)jsn->base + state->pos_begin + 1, at - ((char *)jsn->base + state->pos_begin + 1));
|
102
|
+
break;
|
103
|
+
case JSONSL_T_HKEY:
|
104
|
+
val = rb_str_new((char *)jsn->base + state->pos_begin + 1, at - ((char *)jsn->base + state->pos_begin + 1));
|
105
|
+
break;
|
106
|
+
case JSONSL_T_LIST:
|
107
|
+
case JSONSL_T_OBJECT:
|
108
|
+
val = (VALUE)state->val;
|
109
|
+
break;
|
110
|
+
default:
|
111
|
+
jsl_raise_msg("unexpected state type in PUSH callback");
|
112
|
+
}
|
113
|
+
if (!last_state) {
|
114
|
+
jsn->data = (void *)val;
|
115
|
+
} else if (last_state->type == JSONSL_T_LIST) {
|
116
|
+
rb_ary_push(last_state->val, val);
|
117
|
+
} else if (last_state->type == JSONSL_T_OBJECT) {
|
118
|
+
Check_Type(last_state->val, T_HASH);
|
119
|
+
if (state->type == JSONSL_T_HKEY) {
|
120
|
+
last_state->pkey = val;
|
121
|
+
} else {
|
122
|
+
rb_hash_aset(last_state->val, last_state->pkey, val);
|
123
|
+
}
|
124
|
+
} else {
|
125
|
+
jsl_raise_msg("unable to add value to non container type");
|
126
|
+
}
|
127
|
+
(void)action;
|
128
|
+
}
|
129
|
+
|
130
|
+
static VALUE jsl_jsonsl_parse(int argc, VALUE *argv, VALUE self)
|
131
|
+
{
|
132
|
+
jsonsl_t jsn;
|
133
|
+
VALUE nlevels = Qnil, str = Qnil;
|
134
|
+
|
135
|
+
rb_scan_args(argc, argv, "11", &str, &nlevels);
|
136
|
+
Check_Type(str, T_STRING);
|
137
|
+
if (nlevels != Qnil) {
|
138
|
+
Check_Type(nlevels, T_FIXNUM);
|
139
|
+
jsn = jsonsl_new(FIX2INT(nlevels));
|
140
|
+
} else {
|
141
|
+
jsn = jsonsl_new(JSONSL_MAX_LEVELS);
|
142
|
+
}
|
143
|
+
jsonsl_reset(jsn);
|
144
|
+
jsn->data = (void *)Qnil;
|
145
|
+
jsonsl_enable_all_callbacks(jsn);
|
146
|
+
jsn->action_callback_PUSH = jsl_jsonsl_push_callback;
|
147
|
+
jsn->action_callback_POP = jsl_jsonsl_pop_callback;
|
148
|
+
jsn->error_callback = jsl_jsonsl_error_callback;
|
149
|
+
jsonsl_feed(jsn, RSTRING_PTR(str), RSTRING_LEN(str));
|
150
|
+
if (jsn->level != 0) {
|
151
|
+
jsl_raise_msg("unexpected end of data");
|
152
|
+
}
|
153
|
+
(void)self;
|
154
|
+
return (VALUE)jsn->data;
|
155
|
+
}
|
156
|
+
|
157
|
+
void Init_jsonsl_ext()
|
158
|
+
{
|
159
|
+
jsl_mJSONSL = rb_define_module("JSONSL");
|
160
|
+
rb_define_const(jsl_mJSONSL, "REVISION", rb_str_freeze(rb_str_new_cstr(JSONSL_REVISION)));
|
161
|
+
jsl_eError = rb_const_get(jsl_mJSONSL, rb_intern("Error"));
|
162
|
+
rb_define_singleton_method(jsl_mJSONSL, "parse", jsl_jsonsl_parse, -1);
|
163
|
+
jsl_row_parser_init();
|
164
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Author:: Couchbase <info@couchbase.com>
|
4
|
+
* Copyright:: 2018 Couchbase, Inc.
|
5
|
+
* License:: Apache License, Version 2.0
|
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
|
+
#include <ruby.h>
|
21
|
+
|
22
|
+
#include "jsonsl.h"
|
23
|
+
|
24
|
+
#ifndef JSONSL_EXT_H
|
25
|
+
#define JSONSL_EXT_H
|
26
|
+
|
27
|
+
extern VALUE jsl_mJSONSL;
|
28
|
+
extern VALUE jsl_eError;
|
29
|
+
|
30
|
+
void jsl_raise_at(jsonsl_error_t code, const char *message, const char *file, int line);
|
31
|
+
#define jsl_raise(code, message) jsl_raise_at(code, message, __FILE__, __LINE__)
|
32
|
+
#define jsl_raise_msg(message) jsl_raise_at(0, message, __FILE__, __LINE__)
|
33
|
+
|
34
|
+
void jsl_row_parser_init();
|
35
|
+
|
36
|
+
#endif
|
@@ -0,0 +1,271 @@
|
|
1
|
+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Author:: Couchbase <info@couchbase.com>
|
4
|
+
* Copyright:: 2018 Couchbase, Inc.
|
5
|
+
* License:: Apache License, Version 2.0
|
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
|
+
#include "jsonsl_ext.h"
|
21
|
+
|
22
|
+
VALUE jsl_cRowParser;
|
23
|
+
|
24
|
+
ID jsl_id_call;
|
25
|
+
ID jsl_sym_root;
|
26
|
+
ID jsl_sym_rows;
|
27
|
+
|
28
|
+
typedef struct jsl_PARSER {
|
29
|
+
jsonsl_t jsn;
|
30
|
+
jsonsl_jpr_t ptr;
|
31
|
+
VALUE buffer;
|
32
|
+
VALUE proc;
|
33
|
+
VALUE last_key;
|
34
|
+
int initialized;
|
35
|
+
size_t last_row_endpos;
|
36
|
+
size_t header_len;
|
37
|
+
int rowcount;
|
38
|
+
} jsl_PARSER;
|
39
|
+
|
40
|
+
static void jsl_parser_mark(void *ptr)
|
41
|
+
{
|
42
|
+
jsl_PARSER *parser = ptr;
|
43
|
+
if (parser) {
|
44
|
+
rb_gc_mark_maybe(parser->buffer);
|
45
|
+
rb_gc_mark_maybe(parser->proc);
|
46
|
+
rb_gc_mark_maybe(parser->last_key);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
static void jsl_parser_free(void *ptr)
|
51
|
+
{
|
52
|
+
jsl_PARSER *parser = ptr;
|
53
|
+
if (parser) {
|
54
|
+
if (parser->jsn) {
|
55
|
+
jsonsl_destroy(parser->jsn);
|
56
|
+
}
|
57
|
+
parser->jsn = NULL;
|
58
|
+
if (parser->ptr) {
|
59
|
+
jsonsl_jpr_destroy(parser->ptr);
|
60
|
+
}
|
61
|
+
parser->ptr = NULL;
|
62
|
+
ruby_xfree(parser);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
static VALUE jsl_parser_alloc(VALUE klass)
|
67
|
+
{
|
68
|
+
VALUE obj;
|
69
|
+
jsl_PARSER *parser;
|
70
|
+
|
71
|
+
obj = Data_Make_Struct(klass, jsl_PARSER, jsl_parser_mark, jsl_parser_free, parser);
|
72
|
+
return obj;
|
73
|
+
}
|
74
|
+
|
75
|
+
static int jsl_parser_error_callback(jsonsl_t jsn, jsonsl_error_t err, struct jsonsl_state_st *state, char *at)
|
76
|
+
{
|
77
|
+
char buf[30] = {0};
|
78
|
+
sprintf(buf, "error at %d position", (int)jsn->pos);
|
79
|
+
jsl_raise(err, buf);
|
80
|
+
(void)at;
|
81
|
+
(void)state;
|
82
|
+
return 0;
|
83
|
+
}
|
84
|
+
|
85
|
+
static void jsl_parser_cover_push_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
86
|
+
const jsonsl_char_t *at)
|
87
|
+
{
|
88
|
+
jsl_PARSER *parser = (jsl_PARSER *)jsn->data;
|
89
|
+
parser->header_len = state->pos_begin;
|
90
|
+
jsn->action_callback_PUSH = NULL;
|
91
|
+
(void)action;
|
92
|
+
(void)at;
|
93
|
+
}
|
94
|
+
|
95
|
+
static void jsl_parser_reset(jsl_PARSER *parser)
|
96
|
+
{
|
97
|
+
if (parser) {
|
98
|
+
parser->buffer = Qnil;
|
99
|
+
parser->last_key = Qnil;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
static void jsl_parser_cover_pop_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
104
|
+
const jsonsl_char_t *at)
|
105
|
+
{
|
106
|
+
jsl_PARSER *parser = (jsl_PARSER *)jsn->data;
|
107
|
+
VALUE cover;
|
108
|
+
|
109
|
+
if (state->val != jsl_sym_root) {
|
110
|
+
return;
|
111
|
+
}
|
112
|
+
cover = rb_str_new(RSTRING_PTR(parser->buffer), parser->header_len);
|
113
|
+
rb_str_cat(cover, RSTRING_PTR(parser->buffer) + parser->last_row_endpos,
|
114
|
+
RSTRING_LEN(parser->buffer) - parser->last_row_endpos);
|
115
|
+
rb_funcall(parser->proc, jsl_id_call, 1, cover);
|
116
|
+
jsl_parser_reset(parser);
|
117
|
+
(void)action;
|
118
|
+
(void)at;
|
119
|
+
}
|
120
|
+
|
121
|
+
static void jsl_parser_row_pop_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
122
|
+
const jsonsl_char_t *at)
|
123
|
+
{
|
124
|
+
jsl_PARSER *parser = (jsl_PARSER *)jsn->data;
|
125
|
+
parser->last_row_endpos = jsn->pos;
|
126
|
+
|
127
|
+
if (state->val == jsl_sym_rows) {
|
128
|
+
jsn->action_callback_POP = jsl_parser_cover_pop_callback;
|
129
|
+
jsn->action_callback_PUSH = NULL;
|
130
|
+
return;
|
131
|
+
}
|
132
|
+
|
133
|
+
const char *ptr = RSTRING_PTR(parser->buffer) + state->pos_begin;
|
134
|
+
size_t len = jsn->pos - state->pos_begin + 1;
|
135
|
+
if (state->type == JSONSL_T_SPECIAL) {
|
136
|
+
len--;
|
137
|
+
}
|
138
|
+
rb_funcall(parser->proc, jsl_id_call, 2, INT2FIX(parser->rowcount), rb_str_new(ptr, len));
|
139
|
+
parser->rowcount++;
|
140
|
+
|
141
|
+
(void)action;
|
142
|
+
(void)at;
|
143
|
+
}
|
144
|
+
|
145
|
+
static void jsl_parser_initial_push_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
146
|
+
const jsonsl_char_t *at)
|
147
|
+
{
|
148
|
+
jsl_PARSER *parser = (jsl_PARSER *)jsn->data;
|
149
|
+
jsonsl_jpr_match_t match = JSONSL_MATCH_UNKNOWN;
|
150
|
+
if (JSONSL_STATE_IS_CONTAINER(state)) {
|
151
|
+
jsonsl_jpr_match_state(jsn, state, RSTRING_PTR(parser->last_key), RSTRING_LEN(parser->last_key), &match);
|
152
|
+
}
|
153
|
+
if (parser->initialized == 0) {
|
154
|
+
if (state->type != JSONSL_T_OBJECT) {
|
155
|
+
jsl_raise_msg("expected root to be an object");
|
156
|
+
}
|
157
|
+
if (match != JSONSL_MATCH_POSSIBLE) {
|
158
|
+
jsl_raise_msg("root does not match JSON pointer");
|
159
|
+
}
|
160
|
+
state->val = jsl_sym_root;
|
161
|
+
parser->initialized = 1;
|
162
|
+
}
|
163
|
+
|
164
|
+
if (state->type == JSONSL_T_LIST && match == JSONSL_MATCH_POSSIBLE) {
|
165
|
+
state->val = jsl_sym_rows;
|
166
|
+
jsn->action_callback_POP = jsl_parser_row_pop_callback;
|
167
|
+
jsn->action_callback_PUSH = jsl_parser_cover_push_callback;
|
168
|
+
}
|
169
|
+
(void)action;
|
170
|
+
(void)at;
|
171
|
+
}
|
172
|
+
|
173
|
+
static void jsl_parser_initial_pop_callback(jsonsl_t jsn, jsonsl_action_t action, struct jsonsl_state_st *state,
|
174
|
+
const jsonsl_char_t *at)
|
175
|
+
{
|
176
|
+
jsl_PARSER *parser = (jsl_PARSER *)jsn->data;
|
177
|
+
if (state->type == JSONSL_T_HKEY) {
|
178
|
+
const char *key_str = RSTRING_PTR(parser->buffer) + state->pos_begin + 1;
|
179
|
+
size_t len = jsn->pos - state->pos_begin - 1;
|
180
|
+
parser->last_key = rb_str_new(key_str, len);
|
181
|
+
}
|
182
|
+
(void)action;
|
183
|
+
(void)at;
|
184
|
+
}
|
185
|
+
|
186
|
+
static VALUE jsl_parser_init(int argc, VALUE *argv, VALUE self)
|
187
|
+
{
|
188
|
+
jsl_PARSER *parser = DATA_PTR(self);
|
189
|
+
VALUE nlevels = Qnil;
|
190
|
+
VALUE jptr = Qnil;
|
191
|
+
VALUE proc = Qnil;
|
192
|
+
jsonsl_error_t rc = JSONSL_ERROR_SUCCESS;
|
193
|
+
|
194
|
+
rb_scan_args(argc, argv, "11&", &jptr, &nlevels, &proc);
|
195
|
+
if (proc == Qnil) {
|
196
|
+
rb_raise(rb_eArgError, "tried to create Parser object without a block");
|
197
|
+
}
|
198
|
+
|
199
|
+
Check_Type(jptr, T_STRING);
|
200
|
+
parser->ptr = jsonsl_jpr_new(RSTRING_PTR(jptr), &rc);
|
201
|
+
if (rc != JSONSL_ERROR_SUCCESS) {
|
202
|
+
jsl_raise(rc, "invalid JSON pointer");
|
203
|
+
}
|
204
|
+
if (nlevels != Qnil) {
|
205
|
+
Check_Type(nlevels, T_FIXNUM);
|
206
|
+
parser->jsn = jsonsl_new(FIX2INT(nlevels));
|
207
|
+
} else {
|
208
|
+
parser->jsn = jsonsl_new(JSONSL_MAX_LEVELS);
|
209
|
+
}
|
210
|
+
parser->initialized = 0;
|
211
|
+
parser->buffer = rb_str_buf_new(100);
|
212
|
+
parser->last_key = rb_str_new_cstr("");
|
213
|
+
parser->proc = proc;
|
214
|
+
parser->jsn->data = parser;
|
215
|
+
parser->jsn->max_callback_level = 4;
|
216
|
+
jsonsl_jpr_match_state_init(parser->jsn, &parser->ptr, 1);
|
217
|
+
jsonsl_reset(parser->jsn);
|
218
|
+
parser->jsn->error_callback = jsl_parser_error_callback;
|
219
|
+
parser->jsn->action_callback_PUSH = jsl_parser_initial_push_callback;
|
220
|
+
parser->jsn->action_callback_POP = jsl_parser_initial_pop_callback;
|
221
|
+
jsonsl_enable_all_callbacks(parser->jsn);
|
222
|
+
return self;
|
223
|
+
}
|
224
|
+
|
225
|
+
static VALUE jsl_parser_inspect(VALUE self)
|
226
|
+
{
|
227
|
+
jsl_PARSER *parser = DATA_PTR(self);
|
228
|
+
VALUE str;
|
229
|
+
|
230
|
+
str = rb_str_buf_new2("#<");
|
231
|
+
rb_str_buf_cat2(str, rb_obj_classname(self));
|
232
|
+
rb_str_catf(str, ":%p", (void *)self);
|
233
|
+
if (parser->buffer != Qnil) {
|
234
|
+
rb_str_catf(str, " buflen=%lu", (long int)RSTRING_LEN(parser->buffer));
|
235
|
+
}
|
236
|
+
if (parser->ptr && parser->ptr->orig) {
|
237
|
+
VALUE tmp = rb_inspect(rb_str_new_cstr(parser->ptr->orig));
|
238
|
+
rb_str_catf(str, " ptr=%s", RSTRING_PTR(tmp));
|
239
|
+
}
|
240
|
+
rb_str_buf_cat_ascii(str, ">");
|
241
|
+
|
242
|
+
return str;
|
243
|
+
}
|
244
|
+
|
245
|
+
static VALUE jsl_parser_feed(VALUE self, VALUE data)
|
246
|
+
{
|
247
|
+
jsl_PARSER *parser = DATA_PTR(self);
|
248
|
+
size_t old_len = RSTRING_LEN(parser->buffer);
|
249
|
+
|
250
|
+
if (NIL_P(parser->buffer)) {
|
251
|
+
jsl_raise_msg("unable to feed completed parser");
|
252
|
+
}
|
253
|
+
Check_Type(data, T_STRING);
|
254
|
+
rb_str_buf_append(parser->buffer, data);
|
255
|
+
jsonsl_feed(parser->jsn, RSTRING_PTR(parser->buffer) + old_len, RSTRING_LEN(data));
|
256
|
+
|
257
|
+
return self;
|
258
|
+
}
|
259
|
+
|
260
|
+
void jsl_row_parser_init()
|
261
|
+
{
|
262
|
+
jsl_id_call = rb_intern("call");
|
263
|
+
jsl_sym_root = ID2SYM(rb_intern("root"));
|
264
|
+
jsl_sym_rows = ID2SYM(rb_intern("row"));
|
265
|
+
|
266
|
+
jsl_cRowParser = rb_define_class_under(jsl_mJSONSL, "RowParser", rb_cObject);
|
267
|
+
rb_define_alloc_func(jsl_cRowParser, jsl_parser_alloc);
|
268
|
+
rb_define_method(jsl_cRowParser, "initialize", jsl_parser_init, -1);
|
269
|
+
rb_define_method(jsl_cRowParser, "inspect", jsl_parser_inspect, 0);
|
270
|
+
rb_define_method(jsl_cRowParser, "feed", jsl_parser_feed, 1);
|
271
|
+
}
|