ruby-jq 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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTVjYjg1MGJiNGUzNmQ0NmFmMzYzYWVjZWZjNjUxYjAyZGMwYTgxMg==
5
+ data.tar.gz: !binary |-
6
+ NDRjMDM4ZGFmNDRkNjQ0ZTMyMGFiMTNhZDk2YmJjZmExNWYwODc0MQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTlkMDFlOGYxYWZkZTc0MzA0MTAzMDAzNmMzYjgwNGRlMjkzYmFmY2E5Mjgy
10
+ MTAzNWUxYjhjOTQ3NTM0NTg1ZDAzMjllZmIzZDVkMzU2NDNmNzRjMzdjODli
11
+ MTQ5ZTc1YjdmY2YyZGM2ZDRkNzkyOGIxMTJmZDE2YzM0NjljMzk=
12
+ data.tar.gz: !binary |-
13
+ OTg2M2JkNmUzY2E3MDg1YjBmYTI2MjdlMDcyOWE0ZDk3YzdjOWY4ZGM1YTVh
14
+ NmI5MjY1ZjhhYzQ3NmU5MjEwZjBiNjBlMDYxODQzYmYxNGQ1OTM5ZjhjMGFm
15
+ MjdmOGJmY2RlZmQxOTgyMzA4ZjY0NmFhYWZlYWY2ZDkxYjcwYjA=
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ Makefile
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ mkmf.log
23
+ test.rb
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ruby-jq.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Genki Sugawara
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # ruby-jq
2
+
3
+ Ruby binding for jq.
4
+
5
+ see [http://stedolan.github.io/jq/](http://stedolan.github.io/jq/).
6
+
7
+ ## Installation
8
+
9
+ First, please install libjq from HEAD of [git repository](https://github.com/stedolan/jq).
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'ruby-jq'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ruby-jq
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require 'jq'
27
+
28
+ src = <<EOS
29
+ [
30
+ "FOO",
31
+ {
32
+ "BAR": [100, 200]
33
+ },
34
+ 1.23,
35
+ [1, "2", 3]
36
+ ]
37
+ EOS
38
+
39
+ jq = JQ(src)
40
+
41
+ jq.search('.[]') do |value|
42
+ p value
43
+ # => "FOO"
44
+ # => {"BAR"=>[100, 200]}
45
+ # => 1.23
46
+ # => [1, "2", 3]
47
+ end
48
+
49
+ jq = JQ(src, :parse_json => false)
50
+
51
+ jq.search('.[1].BAR') do |value|
52
+ p value
53
+ # => "[100,200]"
54
+ end
55
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/ext/extconf.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ if have_library('jq')
4
+ create_makefile('jq_core')
5
+ end
data/ext/jq_core.c ADDED
@@ -0,0 +1,125 @@
1
+ #include "jq_core.h"
2
+
3
+ static VALUE rb_eJQ_Error;
4
+
5
+ void rb_jq_free(struct jq_container *p) {
6
+ xfree(p);
7
+ }
8
+
9
+ static void rb_jq_mark(struct jq_container *p) {
10
+ }
11
+
12
+ static VALUE rb_jq_alloc(VALUE klass) {
13
+ struct jq_container *p;
14
+ p = ALLOC(struct jq_container);
15
+ p->jq = NULL;
16
+ p->closed = 1;
17
+ return Data_Wrap_Struct(klass, rb_jq_mark, rb_jq_free, p);
18
+ }
19
+
20
+ static VALUE rb_jq_initialize(VALUE self, VALUE program) {
21
+ struct jq_container *p;
22
+ jq_state *jq;
23
+ int compiled;
24
+
25
+ Data_Get_Struct(self, struct jq_container, p);
26
+ Check_Type(program, T_STRING);
27
+ jq = jq_init();
28
+
29
+ if (jq == NULL) {
30
+ rb_raise(rb_eJQ_Error, "%s", strerror(errno));
31
+ }
32
+
33
+ compiled = jq_compile(jq, RSTRING_PTR(program));
34
+
35
+ if (!compiled) {
36
+ jq_teardown(&jq);
37
+ rb_raise(rb_eJQ_Error, "compile error");
38
+ }
39
+
40
+ p->jq = jq;
41
+ p->closed = 0;
42
+
43
+ return Qnil;
44
+ }
45
+
46
+ static VALUE rb_jq_close(VALUE self) {
47
+ struct jq_container *p;
48
+ Data_Get_Struct(self, struct jq_container, p);
49
+
50
+ if (!p->closed) {
51
+ jq_teardown(&p->jq);
52
+ p->closed = 1;
53
+ }
54
+
55
+ return Qnil;
56
+ }
57
+
58
+ static void jq_process(jq_state *jq, jv value, VALUE (*proc)(), int *status) {
59
+ jq_start(jq, value, 0);
60
+ jv result;
61
+
62
+ while (jv_is_valid(result = jq_next(jq)) && *status == 0) {
63
+ jv dumped = jv_dump_string(result, 0);
64
+ const char *str = jv_string_value(dumped);
65
+ rb_protect(proc, rb_str_new2(str), status);
66
+ }
67
+
68
+ jv_free(result);
69
+ }
70
+
71
+ static void jq_parse(jq_state *jq, char *buf, int is_partial, VALUE (*proc)()) {
72
+ struct jv_parser* parser = jv_parser_new();
73
+ jv value;
74
+ int status = 0, error = 0;
75
+ VALUE errmsg;
76
+
77
+ jv_parser_set_buf(parser, buf, strlen(buf), is_partial);
78
+
79
+ while (jv_is_valid((value = jv_parser_next(parser))) && status == 0) {
80
+ jq_process(jq, value, proc, &status);
81
+ }
82
+
83
+ if (jv_invalid_has_msg(jv_copy(value))) {
84
+ jv msg = jv_invalid_get_msg(value);
85
+ error = 1;
86
+ errmsg = rb_str_new2(jv_string_value(msg));
87
+ jv_free(msg);
88
+ } else {
89
+ jv_free(value);
90
+ }
91
+
92
+ jv_parser_free(parser);
93
+
94
+ if (status != 0) {
95
+ rb_jump_tag(status);
96
+ }
97
+
98
+ if (error) {
99
+ rb_raise(rb_eJQ_Error, "%s", RSTRING_PTR(errmsg));
100
+ }
101
+ }
102
+
103
+ static VALUE rb_jq_update(VALUE self, VALUE buf, VALUE is_partial) {
104
+ struct jq_container *p;
105
+
106
+ if (!rb_block_given_p()) {
107
+ rb_raise(rb_eArgError, "no block given");
108
+ }
109
+
110
+ Data_Get_Struct(self, struct jq_container, p);
111
+ Check_Type(buf, T_STRING);
112
+ jq_parse(p->jq, RSTRING_PTR(buf), is_partial ? 1 : 0, rb_yield);
113
+
114
+ return Qnil;
115
+ }
116
+
117
+ void Init_jq_core() {
118
+ VALUE rb_mJQ = rb_define_module("JQ");
119
+ VALUE rb_cJQ_Core = rb_define_class_under(rb_mJQ, "Core", rb_cObject);
120
+ rb_eJQ_Error = rb_define_class_under(rb_mJQ, "Error", rb_eStandardError);
121
+ rb_define_alloc_func(rb_cJQ_Core, rb_jq_alloc);
122
+ rb_define_private_method(rb_cJQ_Core, "initialize", rb_jq_initialize, 1);
123
+ rb_define_method(rb_cJQ_Core, "close", rb_jq_close, 0);
124
+ rb_define_method(rb_cJQ_Core, "update", rb_jq_update, 2);
125
+ }
data/ext/jq_core.h ADDED
@@ -0,0 +1,15 @@
1
+ #ifndef __JQ_CORE_H__
2
+ #define __JQ_CORE_H__
3
+
4
+ #include <string.h>
5
+ #include <errno.h>
6
+
7
+ #include <jq.h>
8
+ #include <ruby.h>
9
+
10
+ struct jq_container {
11
+ jq_state *jq;
12
+ int closed;
13
+ };
14
+
15
+ #endif //__JQ_CORE_H__
data/lib/jq.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'jq/version'
2
+ require 'jq/parser'
3
+
4
+ def JQ(src, options = {})
5
+ JQ::Parser.new(src, options)
6
+ end
data/lib/jq/parser.rb ADDED
@@ -0,0 +1,64 @@
1
+ require 'jq_core'
2
+ require 'json'
3
+
4
+ class JQ::Parser
5
+ BUFSIZ = 4096
6
+
7
+ def initialize(src, options = {})
8
+ @src = src.kind_of?(IO) ? src : src.to_s
9
+ @options = {
10
+ :parse_json => true,
11
+ }.merge(options)
12
+ end
13
+
14
+ def search(program, &block)
15
+ @src.rewind if @src.kind_of?(IO)
16
+ retval = nil
17
+
18
+ if block
19
+ block_orig = block
20
+
21
+ block = proc do |str|
22
+ block_orig.call(parse_json(str))
23
+ end
24
+ else
25
+ retval = []
26
+
27
+ block = proc do |str|
28
+ retval << parse_json(str)
29
+ end
30
+ end
31
+
32
+ jq(program) do |jq_core|
33
+ if @src.kind_of?(IO)
34
+ while buf = @src.read(BUFSIZ)
35
+ jq_core.update(buf, !src.eof?, &block)
36
+ end
37
+ else
38
+ jq_core.update(@src, false, &block)
39
+ end
40
+ end
41
+
42
+ return retval
43
+ end
44
+
45
+ private
46
+ def jq(program)
47
+ jq_core = nil
48
+
49
+ begin
50
+ jq_core = JQ::Core.new(program)
51
+ retval = yield(jq_core)
52
+ ensure
53
+ jq_core.close if jq_core
54
+ end
55
+ end
56
+
57
+ def parse_json(str)
58
+ if @options[:parse_json]
59
+ JSON.parse("[#{str}]").first
60
+ else
61
+ str
62
+ end
63
+ end
64
+ end
data/lib/jq/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module JQ
2
+ VERSION = "0.1.0"
3
+ end
data/ruby-jq.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jq/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ruby-jq"
8
+ spec.version = JQ::VERSION
9
+ spec.author = "winebarrel"
10
+ spec.email = "sgwr_dts@yahoo.co.jp"
11
+ spec.description = "Ruby binding for jq"
12
+ spec.summary = "Ruby binding for jq"
13
+ spec.homepage = "https://bitbucket.org/winebarrel/ruby-jq"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.extensions = "ext/extconf.rb"
18
+ #spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ #spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "json"
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-jq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - winebarrel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Ruby binding for jq
56
+ email: sgwr_dts@yahoo.co.jp
57
+ executables: []
58
+ extensions:
59
+ - ext/extconf.rb
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - ext/extconf.rb
68
+ - ext/jq_core.c
69
+ - ext/jq_core.h
70
+ - lib/jq.rb
71
+ - lib/jq/parser.rb
72
+ - lib/jq/version.rb
73
+ - ruby-jq.gemspec
74
+ homepage: https://bitbucket.org/winebarrel/ruby-jq
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.1.5
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Ruby binding for jq
98
+ test_files: []