ruby-jq 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []