json_extractor 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -2
- data/ext/json_extractor/json_extractor.c +69 -3
- metadata +2 -2
data/README.md
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
Pull out specific objects from a large JSON document by key without having to
|
4
4
|
deserialize the whole object in to Ruby.
|
5
5
|
|
6
|
-
**NOTE:** This gem only supports extracting objects from JSON
|
7
|
-
Strings
|
6
|
+
**NOTE:** This gem only supports extracting objects and arrays from JSON
|
7
|
+
documents. Strings and numbers are not supported. Yet.
|
8
8
|
|
9
9
|
## Example
|
10
10
|
|
@@ -7,6 +7,8 @@
|
|
7
7
|
|
8
8
|
PARSER_FUNC(object);
|
9
9
|
PARSER_FUNC(object_body);
|
10
|
+
PARSER_FUNC(array);
|
11
|
+
PARSER_FUNC(array_body);
|
10
12
|
PARSER_FUNC(start);
|
11
13
|
PARSER_FUNC(whitespace);
|
12
14
|
|
@@ -115,6 +117,52 @@ unsigned int object(char * str, long len, unsigned int pos) {
|
|
115
117
|
return(-1);
|
116
118
|
}
|
117
119
|
|
120
|
+
/**
|
121
|
+
* Finds the end of the current array body that is under pos within str.
|
122
|
+
*
|
123
|
+
* @param [char *] str the string to search.
|
124
|
+
* @param [long] len the overall length of the string.
|
125
|
+
* @param [unsigned int] pos the initial position (i.e. where to start)
|
126
|
+
* @return [unsigned int] the end of the array body.
|
127
|
+
*/
|
128
|
+
unsigned int array_body(char * str, long len, unsigned int pos) {
|
129
|
+
while(pos < len) {
|
130
|
+
if(str[pos+1] == '[') {
|
131
|
+
pos = array(str, len, pos+1);
|
132
|
+
}
|
133
|
+
|
134
|
+
if(str[pos+1] == ']') {
|
135
|
+
return pos;
|
136
|
+
}
|
137
|
+
|
138
|
+
pos++;
|
139
|
+
}
|
140
|
+
|
141
|
+
return -1;
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* Finds the end of the current array that is under pos within str.
|
146
|
+
*
|
147
|
+
* @param [char *] str the string to search.
|
148
|
+
* @param [long] len the overall length of the string.
|
149
|
+
* @param [unsigned int] pos the initial position (i.e. where to start)
|
150
|
+
* @return [unsigned int] the end of the array.
|
151
|
+
*/
|
152
|
+
unsigned int array(char * str, long len, unsigned int pos) {
|
153
|
+
if(str[pos] != '[') {
|
154
|
+
return -1;
|
155
|
+
}
|
156
|
+
|
157
|
+
pos = array_body(str, len, pos);
|
158
|
+
|
159
|
+
if(str[pos+1] == ']') {
|
160
|
+
return pos+1;
|
161
|
+
}
|
162
|
+
|
163
|
+
return -1;
|
164
|
+
}
|
165
|
+
|
118
166
|
/**
|
119
167
|
* Starts parsing.
|
120
168
|
*
|
@@ -128,6 +176,8 @@ unsigned int start(char * str, long len, unsigned int pos) {
|
|
128
176
|
|
129
177
|
if(str[pos] == '{') {
|
130
178
|
return object(str, len, pos);
|
179
|
+
} else if(str[pos] == '[') {
|
180
|
+
return array(str, len, pos);
|
131
181
|
}
|
132
182
|
|
133
183
|
return -1;
|
@@ -178,6 +228,17 @@ char * extract_subdocument(char * data, const char * key) {
|
|
178
228
|
return final;
|
179
229
|
}
|
180
230
|
|
231
|
+
int file_exists(char * filename) {
|
232
|
+
FILE * fp;
|
233
|
+
|
234
|
+
if(fp = fopen(filename, "r")) {
|
235
|
+
fclose(fp);
|
236
|
+
return 1;
|
237
|
+
}
|
238
|
+
|
239
|
+
return 0;
|
240
|
+
}
|
241
|
+
|
181
242
|
static VALUE rb_extract_subdocument(VALUE self, VALUE str, VALUE key) {
|
182
243
|
char *data, *substr;
|
183
244
|
VALUE result;
|
@@ -192,9 +253,14 @@ static VALUE rb_extract_subdocument(VALUE self, VALUE str, VALUE key) {
|
|
192
253
|
return Qnil;
|
193
254
|
}
|
194
255
|
|
195
|
-
|
196
|
-
|
197
|
-
|
256
|
+
// If str points to a file, let's read it and use that. Otherwise...
|
257
|
+
if(file_exists(RSTRING_PTR(str))) {
|
258
|
+
data = read_all(RSTRING_PTR(str));
|
259
|
+
substr = extract_subdocument(data, RSTRING_PTR(key));
|
260
|
+
free(data);
|
261
|
+
} else {
|
262
|
+
substr = extract_subdocument(RSTRING_PTR(str), RSTRING_PTR(key));
|
263
|
+
}
|
198
264
|
|
199
265
|
if(substr == NULL) {
|
200
266
|
return Qnil;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_extractor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -89,7 +89,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
89
|
version: '0'
|
90
90
|
segments:
|
91
91
|
- 0
|
92
|
-
hash:
|
92
|
+
hash: 243038373631746394
|
93
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|