groonga-command-parser 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a75084a7badb6eaff6d7904c21749782c1565eab
4
- data.tar.gz: 8e5f32b9c0ac5cbfe347e356fb8fc3843e0f52d4
3
+ metadata.gz: 4a650d05617980af6af0e11548cf0938e8ed631a
4
+ data.tar.gz: 7aceca455972e4734e8029e966d501a8ba3e14db
5
5
  SHA512:
6
- metadata.gz: cc7cb7b7c40a7459bc15ac2be6aa69e8c695a330ba86c8e6df3b69516d9801533ed39ac411cb1746756ecdd9d3a1eb220f90d7e2735d04d6ee17cbbee6f76f4c
7
- data.tar.gz: da59b07ea452dc7dc7be75eea93b8dfb960c85ac9ac019ccde3f9162b4d49497b7fec01056656a64920afe1735c93b58b6a9483b6cba0b8333112a782aac91ff
6
+ metadata.gz: a78f94997caa0239aca88c73b71fb22b9da213c40a48f60d8500e136299cf7e667af0b124d1ab5ea74a9f7ca2767a783ccb58152c6024836e4aa6b478ba7235b
7
+ data.tar.gz: e9a0427a34376d5e91f7f33a4aa0945457c5ac74bb1a4cc94e8abc5475a10e9ac940c3ab548e0bd9411c559411a22034479c54557bcdd76560b07b0d637fb43b
@@ -1,5 +1,12 @@
1
1
  # News
2
2
 
3
+ ## 1.0.7: 2016-12-20
4
+
5
+ ### Improvements
6
+
7
+ * Switched to json-stream from ffi-yajl. Because ffi-yajl doesn't
8
+ work on Windows.
9
+
3
10
  ## 1.0.6: 2016-09-12
4
11
 
5
12
  ### Improvements
@@ -53,8 +53,7 @@ Gem::Specification.new do |spec|
53
53
  spec.require_paths = ["lib"]
54
54
 
55
55
  spec.add_runtime_dependency("groonga-command", ">= 1.0.9")
56
- spec.add_runtime_dependency("ffi")
57
- spec.add_runtime_dependency("ffi-yajl")
56
+ spec.add_runtime_dependency("json-stream")
58
57
 
59
58
  spec.add_development_dependency("test-unit")
60
59
  spec.add_development_dependency("test-unit-notify")
@@ -122,7 +122,6 @@ module Groonga
122
122
  def initialize
123
123
  reset
124
124
  initialize_hooks
125
- initialize_load_values_parser
126
125
  end
127
126
 
128
127
  # Streaming parsing command.
@@ -262,6 +261,7 @@ module Groonga
262
261
  on_load_columns(@command, @command.columns)
263
262
  end
264
263
  if @command[:values]
264
+ initialize_load_values_parser
265
265
  @load_values_parser << @command[:values]
266
266
  reset
267
267
  else
@@ -271,6 +271,7 @@ module Groonga
271
271
  else
272
272
  @command.original_source << "\n"
273
273
  @loading = true
274
+ initialize_load_values_parser
274
275
  end
275
276
  end
276
277
  else
@@ -339,6 +340,7 @@ module Groonga
339
340
  @command = nil
340
341
  @loading = false
341
342
  @buffer = "".force_encoding("ASCII-8BIT")
343
+ @load_values_parser = nil
342
344
  end
343
345
 
344
346
  def initialize_hooks
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2015 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -16,12 +14,7 @@
16
14
  # License along with this library; if not, write to the Free Software
17
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
16
 
19
- ENV["FORCE_FFI_YAJL"] = "ffi"
20
- require "ffi_yajl"
21
-
22
- module FFI_Yajl
23
- attach_function :yajl_get_bytes_consumed, [:yajl_handle], :size_t
24
- end
17
+ require "json/stream"
25
18
 
26
19
  module Groonga
27
20
  module Command
@@ -30,9 +23,7 @@ module Groonga
30
23
  attr_writer :on_value
31
24
  attr_writer :on_end
32
25
  def initialize
33
- initialize_callbacks
34
- @handle = nil
35
- @callbacks_memory = nil
26
+ initialize_parser
36
27
  @on_value = nil
37
28
  @on_end = nil
38
29
  @containers = []
@@ -43,39 +34,28 @@ module Groonga
43
34
  data_size = data.bytesize
44
35
  return self if data_size.zero?
45
36
 
46
- ensure_handle
47
-
48
- status = FFI_Yajl.yajl_parse(@handle, data, data_size)
49
-
50
- if status != :yajl_status_ok
51
- consumed = FFI_Yajl.yajl_get_bytes_consumed(@handle)
52
- if consumed > 0
53
- consumed -= 1
54
- end
55
- if @containers.empty?
56
- message = "there are garbages before JSON"
57
- else
58
- message = FFI_Yajl.yajl_get_error(@handle, 0, nil, 0).chomp
59
- end
37
+ before_pos = @parser.pos
38
+ status = catch do |tag|
39
+ @tag = tag
60
40
  begin
61
- raise Error.new(message,
41
+ @parser << data
42
+ rescue JSON::Stream::ParserError => error
43
+ pos = @parser.pos
44
+ consumed = pos - before_pos - 1
45
+ raise Error.new(error.message,
62
46
  data[0, consumed],
63
47
  data[consumed..-1])
64
- ensure
65
- finalize_handle
66
48
  end
49
+ :continue
67
50
  end
68
51
 
69
- if @containers.empty?
70
- consumed = FFI_Yajl.yajl_get_bytes_consumed(@handle)
71
- begin
72
- if consumed < data_size
73
- @on_end.call(data[consumed..-1])
74
- else
75
- @on_end.call(nil)
76
- end
77
- ensure
78
- finalize_handle
52
+ if status == :done
53
+ pos = @parser.pos
54
+ consumed = pos - before_pos
55
+ if consumed < data_size
56
+ @on_end.call(data[consumed..-1])
57
+ else
58
+ @on_end.call(nil)
79
59
  end
80
60
  end
81
61
 
@@ -83,51 +63,30 @@ module Groonga
83
63
  end
84
64
 
85
65
  private
86
- def callback(*arguments)
87
- FFI::Function.new(:int, [:pointer, *arguments]) do |_, *values|
88
- yield(*values)
89
- 1
90
- end
91
- end
92
-
93
- def initialize_callbacks
94
- @null_callback = callback do
95
- push_value(nil)
96
- end
97
- @boolean_callback = callback(:int) do |c_boolean|
98
- push_value(c_boolean != 0)
99
- end
100
- @number_callback = callback(:string, :size_t) do |data, size|
101
- number_data = data.slice(0, size)
102
- if /[\.eE]/ =~ number_data
103
- number = number_data.to_f
104
- else
105
- number = number_data.to_i
106
- end
107
- push_value(number)
108
- end
109
- @string_callback = callback(:string, :size_t) do |data, size|
110
- string = data.slice(0, size)
111
- string.force_encoding(Encoding::UTF_8)
112
- push_value(string)
66
+ def initialize_parser
67
+ @parser = JSON::Stream::Parser.new
68
+ @parser.singleton_class.__send__(:attr_reader, :pos)
69
+ @parser.end_document do
70
+ throw(@tag, :done)
113
71
  end
114
- @start_map_callback = callback do
72
+ @parser.start_object do
115
73
  push_container({})
116
74
  end
117
- @map_key_callback = callback(:string, :size_t) do |data, size|
118
- key = data.slice(0, size)
119
- key.force_encoding(Encoding::UTF_8)
120
- @keys.push(key)
121
- end
122
- @end_map_callback = callback do
75
+ @parser.end_object do
123
76
  pop_container
124
77
  end
125
- @start_array_callback = callback do
78
+ @parser.start_array do
126
79
  push_container([])
127
80
  end
128
- @end_array_callback = callback do
81
+ @parser.end_array do
129
82
  pop_container
130
83
  end
84
+ @parser.key do |key|
85
+ push_key(key)
86
+ end
87
+ @parser.value do |value|
88
+ push_value(value)
89
+ end
131
90
  end
132
91
 
133
92
  def push_container(container)
@@ -143,64 +102,19 @@ module Groonga
143
102
  end
144
103
  end
145
104
 
105
+ def push_key(key)
106
+ @keys.push(key)
107
+ end
108
+
146
109
  def push_value(value)
147
110
  container = @containers.last
148
111
  case container
149
- when Hash
112
+ when ::Hash
150
113
  container[@keys.pop] = value
151
- when Array
114
+ when ::Array
152
115
  container.push(value)
153
116
  end
154
117
  end
155
-
156
- def ensure_handle
157
- return if @handle
158
- initialize_handle
159
- end
160
-
161
- def initialize_handle
162
- @callbacks_memory = FFI::MemoryPointer.new(FFI_Yajl::YajlCallbacks)
163
- callbacks = FFI_Yajl::YajlCallbacks.new(@callbacks_memory)
164
- callbacks[:yajl_null] = @null_callback
165
- callbacks[:yajl_boolean] = @boolean_callback
166
- callbacks[:yajl_integer] = nil
167
- callbacks[:yajl_double] = nil
168
- callbacks[:yajl_number] = @number_callback
169
- callbacks[:yajl_string] = @string_callback
170
- callbacks[:yajl_start_map] = @start_map_callback
171
- callbacks[:yajl_map_key] = @map_key_callback
172
- callbacks[:yajl_end_map] = @end_map_callback
173
- callbacks[:yajl_start_array] = @start_array_callback
174
- callbacks[:yajl_end_array] = @end_array_callback
175
-
176
- @handle = FFI_Yajl.yajl_alloc(@callbacks_memory, nil, nil)
177
- FFI_Yajl.yajl_config(@handle,
178
- :yajl_allow_trailing_garbage,
179
- :int,
180
- 1)
181
- @finalizer = Finalizer.new(@handle)
182
- ObjectSpace.define_finalizer(self, @finalizer)
183
- end
184
-
185
- def finalize_handle
186
- @callbacks_memory = nil
187
- @finalizer.call(object_id)
188
- ObjectSpace.undefine_finalizer(self)
189
- @finalizer = nil
190
- @handle = nil
191
- end
192
-
193
- class Finalizer
194
- def initialize(handle)
195
- @handle = handle
196
- end
197
-
198
- def call(object_id)
199
- return if @handle.nil?
200
- FFI_Yajl.yajl_free(@handle)
201
- @handle = nil
202
- end
203
- end
204
118
  end
205
119
  end
206
120
  end
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013-2015 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -19,7 +17,7 @@
19
17
  module Groonga
20
18
  module Command
21
19
  class Parser
22
- VERSION = "1.0.6"
20
+ VERSION = "1.0.7"
23
21
  end
24
22
  end
25
23
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #
3
- # Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2012-2016 Kouhei Sutou <kou@clear-code.com>
4
4
  #
5
5
  # This library is free software; you can redistribute it and/or
6
6
  # modify it under the terms of the GNU Lesser General Public
@@ -36,13 +36,6 @@ end
36
36
  $LOAD_PATH.unshift(lib_dir)
37
37
  $LOAD_PATH.unshift(test_dir)
38
38
 
39
- # TODO: Remove me when suppress warnings patches are merged int
40
- # ffi_yajl.
41
- require "stringio"
42
- $VERBOSE = false
43
- require "ffi_yajl/ffi"
44
- $VERBOSE = true
45
-
46
39
  require "groonga-command-parser-test-utils"
47
40
 
48
41
  ENV["TEST_UNIT_MAX_DIFF_TARGET_STRING_SIZE"] ||= "5000"
@@ -21,13 +21,17 @@ class LoadValuesParserTest < Test::Unit::TestCase
21
21
  @parser.on_value = lambda do |value|
22
22
  @values << value
23
23
  end
24
+ @parse_done = false
24
25
  @parser.on_end = lambda do |rest|
26
+ @parse_done = true
27
+ @parse_rest = rest
25
28
  end
26
29
  end
27
30
 
28
31
  def parse(data)
29
32
  data.each_line do |line|
30
- @parser << line
33
+ @parser << line
34
+ break if @parse_done
31
35
  end
32
36
  @values
33
37
  end
@@ -140,10 +144,50 @@ class LoadValuesParserTest < Test::Unit::TestCase
140
144
  }
141
145
  }
142
146
  ]
147
+ JSON
148
+ end
149
+ end
150
+
151
+ sub_test_case "error" do
152
+ test "unfinished" do
153
+ assert_equal([
154
+ {
155
+ "object" => {
156
+ "string" => "abc",
157
+ },
158
+ },
159
+ ],
160
+ parse(<<-JSON))
143
161
  [
144
- 1
145
- ]
162
+ {
163
+ "object": {
164
+ "string": "abc"
165
+ }
166
+ },
167
+ {
168
+ JSON
169
+ assert_false(@parse_done)
170
+ end
171
+
172
+ test "too much" do
173
+ assert_equal([
174
+ {
175
+ "object" => {
176
+ "string" => "abc",
177
+ },
178
+ },
179
+ ],
180
+ parse(<<-JSON))
181
+ [
182
+ {
183
+ "object": {
184
+ "string": "abc"
185
+ }
186
+ }
187
+ ]garbage
146
188
  JSON
189
+ assert_equal([true, "garbage\n"],
190
+ [@parse_done, @parse_rest])
147
191
  end
148
192
  end
149
193
  end
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2011-2014 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -374,7 +372,7 @@ EOS
374
372
  end
375
373
 
376
374
  def test_no_record_separate_comma
377
- message = "parse error: after array element, I expect ',' or ']'"
375
+ message = "Expected comma or object or array close: char 37"
378
376
  before = <<-BEFORE
379
377
  [
380
378
  {"_key": "alice", "name": "Alice"}
@@ -394,7 +392,7 @@ EOC
394
392
  end
395
393
 
396
394
  def test_garbage_before_json
397
- message = "there are garbages before JSON"
395
+ message = "Expected value: char 0"
398
396
  before = ""
399
397
  after = <<-AFTER
400
398
  XXX
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: groonga-command-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-12 00:00:00.000000000 Z
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: groonga-command
@@ -25,21 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.9
27
27
  - !ruby/object:Gem::Dependency
28
- name: ffi
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: ffi-yajl
28
+ name: json-stream
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
31
  - - ">="
@@ -200,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
186
  version: '0'
201
187
  requirements: []
202
188
  rubyforge_project:
203
- rubygems_version: 2.5.1
189
+ rubygems_version: 2.5.2
204
190
  signing_key:
205
191
  specification_version: 4
206
192
  summary: Groonga-command-parser is a Ruby library to parses [groonga](http://groonga.org/)'s
@@ -211,4 +197,3 @@ test_files:
211
197
  - test/test-load-value-parser.rb
212
198
  - test/test-command-line-splitter.rb
213
199
  - test/groonga-command-parser-test-utils.rb
214
- has_rdoc: