ruby-jq 0.1.1 → 0.1.2

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 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