ruby-jq 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWVjZTVhZmQ4MzYwZTI4OTU0YWNhMmMxMmI3MjIzMjU1MmE0Y2Y4Nw==
4
+ OTUzMDNjM2E5MDlmYzBlZWNkZjYwOTJiN2M3MzcyZmZlYzNhZDQxZA==
5
5
  data.tar.gz: !binary |-
6
- OGMwZjZhODEzYWFjMjhmNmE4NGZiM2YyOTFlZDRkNmM0MDRhZTFhOA==
6
+ MDUyMzQ0MjBiMjcxZjU0MWRiYWExOTA2ODljN2IwZTY1MTUyZTM2ZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZjZiODYyOTRiYTMzNDZjMWE1OTY4ZGIxMzE3MmMwZjA5M2ZiODAyODhiYzY4
10
- YTNlNDMxNWVhYjBlY2ExMjI4MWJlMjhkMDJkMjg1YWQzNjQxNWJjYTY2MmEx
11
- ODExNzJhZmI2OWJhY2NmNDI3MjYyYWQxMjhiYjUwMWY5Njg1ZWU=
9
+ NGVlNTM5MGRkZDg2ODI1ZjljY2JlMTI2OWQwZjE2ODczMmE4NzVhNDViOTA5
10
+ MDBlMDcxMjA4NWI2MzRlYWUwYmUwZDE2OGQ5MTk5MjgyY2M5NjU2NzlhMWU2
11
+ YzZhMzdhNWM2NGU3MTAxZTZlMjEyMzIyZTJjNmQxYTlkOTAzNTM=
12
12
  data.tar.gz: !binary |-
13
- OWRiOTg4OTU5ZmExNzRlYWEwMWQxNTg2YTYxYzNkNDcyYjgwY2M2ZDQ3YzNi
14
- NGRiZjA1ZjAxYzczYTY2M2IwN2VkNjg4YmQzNWUwYzQ5NzE0NDJlM2IyNDg3
15
- MTdmY2MzMjMzYTY3YzQzOWJmN2Y0ZjZiNTgzOTE4YTEyM2Q5ZTk=
13
+ ZTRhMWFjZjQxZGFjNzEzZDBmY2FmMTNiYjAzNzQ1YjQwYjMxY2RiZjU1Y2Yz
14
+ YjI2YTMwMzNlMDcyNjliZmVjYzg2OGQwNDFkZTg2OWRiNWE4NjI2MDAwODcz
15
+ N2QzZGYzZTYwNjNiOTJhNTAxM2Q3MzMxNTg4NWRhMzdlODM0OWI=
data/ext/jq_core.c CHANGED
@@ -10,6 +10,7 @@ static VALUE rb_jq_alloc(VALUE klass) {
10
10
  struct jq_container *p;
11
11
  p = ALLOC(struct jq_container);
12
12
  p->jq = NULL;
13
+ p->parser = NULL;
13
14
  p->closed = 1;
14
15
  return Data_Wrap_Struct(klass, 0, rb_jq_free, p);
15
16
  }
@@ -35,6 +36,7 @@ static VALUE rb_jq_initialize(VALUE self, VALUE program) {
35
36
  }
36
37
 
37
38
  p->jq = jq;
39
+ p->parser = NULL;
38
40
  p->closed = 0;
39
41
 
40
42
  return Qnil;
@@ -46,6 +48,8 @@ static VALUE rb_jq_close(VALUE self) {
46
48
 
47
49
  if (!p->closed) {
48
50
  jq_teardown(&p->jq);
51
+ p->jq = NULL;
52
+ p->parser = NULL;
49
53
  p->closed = 1;
50
54
  }
51
55
 
@@ -65,40 +69,27 @@ static void jq_process(jq_state *jq, jv value, VALUE (*proc)(), int *status) {
65
69
  jv_free(result);
66
70
  }
67
71
 
68
- static void jq_parse(jq_state *jq, char *buf, int is_partial, VALUE (*proc)()) {
69
- struct jv_parser* parser = jv_parser_new();
72
+ static void jq_parse(jq_state *jq, struct jv_parser *parser, VALUE (*proc)(), int *status, VALUE *errmsg) {
70
73
  jv value;
71
- int status = 0, error = 0;
72
- VALUE errmsg;
73
74
 
74
- jv_parser_set_buf(parser, buf, strlen(buf), is_partial);
75
-
76
- while (jv_is_valid((value = jv_parser_next(parser))) && status == 0) {
77
- jq_process(jq, value, proc, &status);
75
+ while (jv_is_valid((value = jv_parser_next(parser))) && *status == 0) {
76
+ jq_process(jq, value, proc, status);
78
77
  }
79
78
 
80
79
  if (jv_invalid_has_msg(jv_copy(value))) {
81
80
  jv msg = jv_invalid_get_msg(value);
82
- error = 1;
83
- errmsg = rb_str_new2(jv_string_value(msg));
81
+ *errmsg = rb_str_new2(jv_string_value(msg));
84
82
  jv_free(msg);
85
83
  } else {
86
84
  jv_free(value);
87
85
  }
88
-
89
- jv_parser_free(parser);
90
-
91
- if (status != 0) {
92
- rb_jump_tag(status);
93
- }
94
-
95
- if (error) {
96
- rb_raise(rb_eJQ_Error, "%s", RSTRING_PTR(errmsg));
97
- }
98
86
  }
99
87
 
100
- static VALUE rb_jq_update(VALUE self, VALUE buf, VALUE is_partial) {
88
+ static VALUE rb_jq_update(VALUE self, VALUE buf, VALUE v_is_partial) {
101
89
  struct jq_container *p;
90
+ int is_partial = v_is_partial ? 1 : 0;
91
+ int status = 0;
92
+ VALUE errmsg = Qnil;
102
93
 
103
94
  if (!rb_block_given_p()) {
104
95
  rb_raise(rb_eArgError, "no block given");
@@ -106,7 +97,26 @@ static VALUE rb_jq_update(VALUE self, VALUE buf, VALUE is_partial) {
106
97
 
107
98
  Data_Get_Struct(self, struct jq_container, p);
108
99
  Check_Type(buf, T_STRING);
109
- jq_parse(p->jq, RSTRING_PTR(buf), is_partial ? 1 : 0, rb_yield);
100
+
101
+ if (!p->parser) {
102
+ p->parser = jv_parser_new();
103
+ }
104
+
105
+ jv_parser_set_buf(p->parser, RSTRING_PTR(buf), RSTRING_LEN(buf), is_partial);
106
+ jq_parse(p->jq, p->parser, rb_yield, &status, &errmsg);
107
+
108
+ if (!is_partial) {
109
+ jv_parser_free(p->parser);
110
+ p->parser = NULL;
111
+ }
112
+
113
+ if (status != 0) {
114
+ rb_jump_tag(status);
115
+ }
116
+
117
+ if (!NIL_P(errmsg)) {
118
+ rb_raise(rb_eJQ_Error, "%s", RSTRING_PTR(errmsg));
119
+ }
110
120
 
111
121
  return Qnil;
112
122
  }
data/ext/jq_core.h CHANGED
@@ -9,6 +9,7 @@
9
9
 
10
10
  struct jq_container {
11
11
  jq_state *jq;
12
+ struct jv_parser *parser;
12
13
  int closed;
13
14
  };
14
15
 
data/lib/jq/parser.rb CHANGED
@@ -1,18 +1,20 @@
1
1
  require 'jq_core'
2
2
  require 'json'
3
+ require 'tempfile'
4
+ require 'stringio'
3
5
 
4
6
  class JQ::Parser
5
7
  BUFSIZ = 4096
6
8
 
7
9
  def initialize(src, options = {})
8
- @src = src.kind_of?(IO) ? src : src.to_s
10
+ @src = kind_of_io?(src) ? src : src.to_s
9
11
  @options = {
10
12
  :parse_json => true,
11
13
  }.merge(options)
12
14
  end
13
15
 
14
16
  def search(program, &block)
15
- @src.rewind if @src.kind_of?(IO)
17
+ @src.rewind if kind_of_io?(@src)
16
18
  retval = nil
17
19
 
18
20
  if block
@@ -30,9 +32,9 @@ class JQ::Parser
30
32
  end
31
33
 
32
34
  jq(program) do |jq_core|
33
- if @src.kind_of?(IO)
35
+ if kind_of_io?(@src)
34
36
  while buf = @src.read(BUFSIZ)
35
- jq_core.update(buf, !src.eof?, &block)
37
+ jq_core.update(buf, !@src.eof?, &block)
36
38
  end
37
39
  else
38
40
  jq_core.update(@src, false, &block)
@@ -61,4 +63,8 @@ class JQ::Parser
61
63
  str
62
64
  end
63
65
  end
66
+
67
+ def kind_of_io?(obj)
68
+ [IO, Tempfile, StringIO].any? {|c| obj.kind_of?(c) }
69
+ end
64
70
  end
data/lib/jq/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module JQ
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/spec/jq_spec.rb CHANGED
@@ -92,6 +92,114 @@ describe JQ do
92
92
  end
93
93
  end
94
94
 
95
+ it 'read from file' do
96
+ Tempfile.open("ruby-jq.spec.#{$$}") do |src|
97
+ src.puts(<<-EOS)
98
+ {
99
+ "glossary": {
100
+ "title": "example glossary",
101
+ "GlossDiv": {
102
+ "title": "S",
103
+ "GlossList": {
104
+ "GlossEntry": {
105
+ "ID": "SGML",
106
+ "SortAs": "SGML",
107
+ "GlossTerm": "Standard Generalized Markup Language",
108
+ "Acronym": "SGML",
109
+ "Abbrev": "ISO 8879:1986",
110
+ "GlossDef": {
111
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
112
+ "GlossSeeAlso": ["GML", "XML"]
113
+ },
114
+ "GlossSee": "markup"
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ EOS
121
+
122
+ expected = {
123
+ "glossary"=>
124
+ {"GlossDiv"=>
125
+ {"GlossList"=>
126
+ {"GlossEntry"=>
127
+ {"GlossSee"=>"markup",
128
+ "GlossDef"=>
129
+ {"GlossSeeAlso"=>["GML", "XML"],
130
+ "para"=>
131
+ "A meta-markup language, used to create markup languages such as DocBook."},
132
+ "Abbrev"=>"ISO 8879:1986",
133
+ "Acronym"=>"SGML",
134
+ "GlossTerm"=>"Standard Generalized Markup Language",
135
+ "SortAs"=>"SGML",
136
+ "ID"=>"SGML"}},
137
+ "title"=>"S"},
138
+ "title"=>"example glossary"}}
139
+
140
+ expect(JQ(src).search('.')).to eq([expected])
141
+
142
+ JQ(src).search('.') do |value|
143
+ expect(value).to eq(expected)
144
+ end
145
+ end
146
+ end
147
+
148
+ it 'read from file (> 4096)' do
149
+ Tempfile.open("ruby-jq.spec.#{$$}") do |src|
150
+ src.puts('[' + (1..10).map { (<<-EOS) }.join(',') + ']')
151
+ {
152
+ "glossary": {
153
+ "title": "example glossary",
154
+ "GlossDiv": {
155
+ "title": "S",
156
+ "GlossList": {
157
+ "GlossEntry": {
158
+ "ID": "SGML",
159
+ "SortAs": "SGML",
160
+ "GlossTerm": "Standard Generalized Markup Language",
161
+ "Acronym": "SGML",
162
+ "Abbrev": "ISO 8879:1986",
163
+ "GlossDef": {
164
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
165
+ "GlossSeeAlso": ["GML", "XML"]
166
+ },
167
+ "GlossSee": "markup"
168
+ }
169
+ }
170
+ }
171
+ }
172
+ }
173
+ EOS
174
+
175
+ expected = (1..10).map do
176
+ {
177
+ "glossary"=>
178
+ {"GlossDiv"=>
179
+ {"GlossList"=>
180
+ {"GlossEntry"=>
181
+ {"GlossSee"=>"markup",
182
+ "GlossDef"=>
183
+ {"GlossSeeAlso"=>["GML", "XML"],
184
+ "para"=>
185
+ "A meta-markup language, used to create markup languages such as DocBook."},
186
+ "Abbrev"=>"ISO 8879:1986",
187
+ "Acronym"=>"SGML",
188
+ "GlossTerm"=>"Standard Generalized Markup Language",
189
+ "SortAs"=>"SGML",
190
+ "ID"=>"SGML"}},
191
+ "title"=>"S"},
192
+ "title"=>"example glossary"}}
193
+ end
194
+
195
+ expect(JQ(src).search('.')).to eq([expected])
196
+
197
+ JQ(src).search('.') do |value|
198
+ expect(value).to eq(expected)
199
+ end
200
+ end
201
+ end
202
+
95
203
  it 'parse_json => false' do
96
204
  src = <<-EOS
97
205
  {
@@ -150,4 +258,12 @@ describe JQ do
150
258
  JQ('{}').search('...')
151
259
  }.to raise_error(JQ::Error)
152
260
  end
261
+
262
+ it 'runtime error' do
263
+ expect {
264
+ JQ('{}').search('.') do |value|
265
+ raise 'runtime error'
266
+ end
267
+ }.to raise_error(RuntimeError)
268
+ end
153
269
  end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,3 @@
1
1
  $: << File.dirname(__FILE__) + '/../lib'
2
+ require 'tempfile'
2
3
  require 'jq'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-jq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - winebarrel