groonga-command-parser 1.0.6 → 1.0.7

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