yajl-ffi 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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91b3e4f40a342d0b737483a32c14789d13901071
4
- data.tar.gz: acfebb0bf6867ee99cc39f44411b394dd697acbf
3
+ metadata.gz: 6de3c945368d22be36236e10320d4f352eb30d92
4
+ data.tar.gz: fb7fb82310439d20429da612ac5e134bfeb1e733
5
5
  SHA512:
6
- metadata.gz: 4894734f7816e431e19f05e81ddbc30e5e30aa79d1712d421af4f24f2b377b8868b4e1ff5324ff6a0bf49bceafd5cc79675ed495eaa63700502cbd1dcbb45e9e
7
- data.tar.gz: 7dcc45a9609c6f9f99ff3db4fbdaa86e97e6a96ef247b7347dc418c56ba241f33e2a7a2848205b55db743f4bc5a4271da84189418e8d3cbb00200a4564facecf
6
+ metadata.gz: 42d060dadaf9bc2e0eea2e5ce7e218180b7bd6c483ae449ec4e8329d1da61bac9c85fd7c96a9ea374f49eca828fc967663f7caa0f43300bf458c4fe4a9567a4d
7
+ data.tar.gz: e0b43c9e8427a05d72f76e69e468baf69483e69fd0290571173b023a283c8f5ae7791b99fb36c6457ecd35a1be4346e5281063790a99bbe2cd6a17a539c7b8d6
data/README.md CHANGED
@@ -158,10 +158,10 @@ several parsers. Here's a sample run.
158
158
  ```
159
159
  $ rake benchmark
160
160
  user system total real
161
- json 0.130000 0.010000 0.140000 ( 0.136225)
162
- yajl-ruby 0.130000 0.010000 0.140000 ( 0.133872)
163
- yajl-ffi 0.800000 0.010000 0.810000 ( 0.812818)
164
- json-stream 9.500000 0.080000 9.580000 ( 9.580571)
161
+ json 0.120000 0.010000 0.130000 ( 0.130072)
162
+ yajl-ruby 0.130000 0.000000 0.130000 ( 0.129388)
163
+ yajl-ffi 0.790000 0.010000 0.800000 ( 0.805279)
164
+ json-stream 7.500000 0.030000 7.530000 ( 7.524760)
165
165
  ```
166
166
 
167
167
  Yajl::FFI is about 6x slower than the pure native parsers. JSON::Stream is a
@@ -36,13 +36,15 @@ module Yajl
36
36
 
37
37
  def end_object
38
38
  return if @stack.size == 1
39
+
39
40
  node = @stack.pop
41
+ top = @stack[-1]
40
42
 
41
- case @stack.last
43
+ case top
42
44
  when Hash
43
- @stack.last[@keys.pop] = node
45
+ top[@keys.pop] = node
44
46
  when Array
45
- @stack.last << node
47
+ top << node
46
48
  end
47
49
  end
48
50
  alias :end_array :end_object
@@ -56,11 +58,12 @@ module Yajl
56
58
  end
57
59
 
58
60
  def value(value)
59
- case @stack.last
61
+ top = @stack[-1]
62
+ case top
60
63
  when Hash
61
- @stack.last[@keys.pop] = value
64
+ top[@keys.pop] = value
62
65
  when Array
63
- @stack.last << value
66
+ top << value
64
67
  else
65
68
  @stack << value
66
69
  end
@@ -287,7 +287,7 @@ module Yajl
287
287
  #
288
288
  # Returns a String.
289
289
  def extract(pointer, length)
290
- string = pointer.read_string(length)
290
+ string = pointer.get_bytes(0, length)
291
291
  string.force_encoding(Encoding::UTF_8)
292
292
  unless string.valid_encoding?
293
293
  raise ParserError, 'Invalid UTF-8 byte sequence'
@@ -1,5 +1,5 @@
1
1
  module Yajl
2
2
  module FFI
3
- VERSION = '0.1.1'
3
+ VERSION = '0.1.2'
4
4
  end
5
5
  end
@@ -35,7 +35,15 @@ describe Yajl::FFI::Parser do
35
35
  assert_equal expected, events('"test"')
36
36
  end
37
37
 
38
- it 'parses an integer value document' do
38
+ it 'parses a single digit integer value document' do
39
+ expected = [:start_document, [:value, 2], :end_document]
40
+ events = events('2', subject)
41
+ assert events.empty?
42
+ subject.finish
43
+ assert_equal expected, events
44
+ end
45
+
46
+ it 'parses a multiple digit integer value document' do
39
47
  expected = [:start_document, [:value, 12], :end_document]
40
48
  events = events('12', subject)
41
49
  assert events.empty?
@@ -43,6 +51,30 @@ describe Yajl::FFI::Parser do
43
51
  assert_equal expected, events
44
52
  end
45
53
 
54
+ it 'parses a zero literal document' do
55
+ expected = [:start_document, [:value, 0], :end_document]
56
+ events = events('0', subject)
57
+ assert events.empty?
58
+ subject.finish
59
+ assert_equal expected, events
60
+ end
61
+
62
+ it 'parses a negative integer document' do
63
+ expected = [:start_document, [:value, -1], :end_document]
64
+ events = events('-1', subject)
65
+ assert events.empty?
66
+ subject.finish
67
+ assert_equal expected, events
68
+ end
69
+
70
+ it 'parses an exponent literal document' do
71
+ expected = [:start_document, [:value, 200.0], :end_document]
72
+ events = events('2e2', subject)
73
+ assert events.empty?
74
+ subject.finish
75
+ assert_equal expected, events
76
+ end
77
+
46
78
  it 'parses a float value document' do
47
79
  expected = [:start_document, [:value, 12.1], :end_document]
48
80
  events = events('12.1', subject)
@@ -113,6 +145,13 @@ describe Yajl::FFI::Parser do
113
145
  assert_equal expected, events('[fals1]')
114
146
  end
115
147
 
148
+ it 'rejects scrambled keyword tokens' do
149
+ expected = [:start_document, :start_array, :error]
150
+ assert_equal expected, events('[ture]')
151
+ assert_equal expected, events('[fales]')
152
+ assert_equal expected, events('[nlul]')
153
+ end
154
+
116
155
  it 'parses single keyword tokens' do
117
156
  expected = [:start_document, :start_array, [:value, true], :end_array, :end_document]
118
157
  assert_equal expected, events('[true]')
@@ -149,6 +188,36 @@ describe Yajl::FFI::Parser do
149
188
  -> { subject.finish }.must_raise Yajl::FFI::ParserError
150
189
  end
151
190
 
191
+ it 'rejects partial exponent' do
192
+ subject << '42e'
193
+ -> { subject.finish }.must_raise Yajl::FFI::ParserError
194
+ end
195
+
196
+ it 'rejects malformed exponent' do
197
+ subject << '42e+'
198
+ -> { subject.finish }.must_raise Yajl::FFI::ParserError
199
+ end
200
+
201
+ it 'rejects partial negative number' do
202
+ subject << '-'
203
+ -> { subject.finish }.must_raise Yajl::FFI::ParserError
204
+ end
205
+
206
+ it 'rejects partial string literal' do
207
+ subject << '"test'
208
+ -> { subject.finish }.must_raise Yajl::FFI::ParserError
209
+ end
210
+
211
+ it 'rejects partial object ending in literal value' do
212
+ subject << '{"test": 42'
213
+ -> { subject.finish }.must_raise Yajl::FFI::ParserError
214
+ end
215
+
216
+ it 'rejects partial array ending in literal value' do
217
+ subject << '[42'
218
+ -> { subject.finish }.must_raise Yajl::FFI::ParserError
219
+ end
220
+
152
221
  it 'does nothing on subsequent finish' do
153
222
  begin
154
223
  subject << 'false'
@@ -247,9 +316,34 @@ describe Yajl::FFI::Parser do
247
316
  assert_equal expected, events('[12.]')
248
317
  end
249
318
 
250
- it 'parses positive exponent integers' do
251
- expected = [:start_document, :start_array, [:value, 212], :end_array, :end_document]
319
+ it 'parses zero with implicit positive exponent as float' do
320
+ expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
321
+ events = events('[0e2]')
322
+ assert_equal expected, events
323
+ assert_kind_of Float, events[2][1]
324
+ end
325
+
326
+ it 'parses zero with explicit positive exponent as float' do
327
+ expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
328
+ events = events('[0e+2]')
329
+ assert_equal expected, events
330
+ assert_kind_of Float, events[2][1]
331
+ end
332
+
333
+ it 'parses zero with negative exponent as float' do
334
+ expected = [:start_document, :start_array, [:value, 0.0], :end_array, :end_document]
335
+ events = events('[0e-2]')
336
+ assert_equal expected, events
337
+ assert_kind_of Float, events[2][1]
338
+ end
339
+
340
+ it 'parses positive exponent integers as floats' do
341
+ expected = [:start_document, :start_array, [:value, 212.0], :end_array, :end_document]
342
+
343
+ events = events('[2.12e2]')
252
344
  assert_equal expected, events('[2.12e2]')
345
+ assert_kind_of Float, events[2][1]
346
+
253
347
  assert_equal expected, events('[2.12e02]')
254
348
  assert_equal expected, events('[2.12e+2]')
255
349
  assert_equal expected, events('[2.12e+02]')
@@ -452,11 +546,22 @@ describe Yajl::FFI::Parser do
452
546
  end
453
547
 
454
548
  describe 'parsing unicode escapes with surrogate pairs' do
549
+ it 'converts missing second pair to question mark' do
550
+ expected = [:start_document, :start_array, [:value, '?'], :end_array, :end_document]
551
+ assert_equal expected, events('["\uD834"]')
552
+ end
553
+
455
554
  it 'rejects missing first pair' do
456
555
  expected = [:start_document, :start_array, :error]
457
556
  assert_equal expected, events('["\uDD1E"]')
458
557
  end
459
558
 
559
+ it 'rejects double first pair' do
560
+ skip 'yajl incorrectly allows this'
561
+ expected = [:start_document, :start_array, :error]
562
+ assert_equal expected, events('["\uD834\uD834"]')
563
+ end
564
+
460
565
  it 'rejects double second pair' do
461
566
  expected = [:start_document, :start_array, :error]
462
567
  assert_equal expected, events('["\uDD1E\uDD1E"]')
@@ -610,7 +715,7 @@ describe Yajl::FFI::Parser do
610
715
  # is available. The \xC3 byte is the first byte of the é character.
611
716
  it 'rejects a partial two byte utf-8 string' do
612
717
  expected = [:start_document, :start_array, :error]
613
- assert_equal expected, events('["\xC3"]')
718
+ assert_equal expected, events("[\"\xC3\"]")
614
719
  end
615
720
 
616
721
  it 'parses valid two byte utf-8 string' do
@@ -632,12 +737,12 @@ describe Yajl::FFI::Parser do
632
737
 
633
738
  it 'rejects one byte of three byte utf-8 string' do
634
739
  expected = [:start_document, :start_array, :error]
635
- assert_equal expected, events('["\xE2"]')
740
+ assert_equal expected, events("[\"\xE2\"]")
636
741
  end
637
742
 
638
743
  it 'rejects two bytes of three byte utf-8 string' do
639
744
  expected = [:start_document, :start_array, :error]
640
- assert_equal expected, events('["\xE2\x98"]')
745
+ assert_equal expected, events("[\"\xE2\x98\"]")
641
746
  end
642
747
 
643
748
  it 'parses full three byte utf-8 string' do
@@ -658,17 +763,17 @@ describe Yajl::FFI::Parser do
658
763
 
659
764
  it 'rejects one byte of four byte utf-8 string' do
660
765
  expected = [:start_document, :start_array, :error]
661
- assert_equal expected, events('["\xF0"]')
766
+ assert_equal expected, events("[\"\xF0\"]")
662
767
  end
663
768
 
664
769
  it 'rejects two bytes of four byte utf-8 string' do
665
770
  expected = [:start_document, :start_array, :error]
666
- assert_equal expected, events('["\xF0\x90"]')
771
+ assert_equal expected, events("[\"\xF0\x90\"]")
667
772
  end
668
773
 
669
774
  it 'rejects three bytes of four byte utf-8 string' do
670
775
  expected = [:start_document, :start_array, :error]
671
- assert_equal expected, events('["\xF0\x90\x84"]')
776
+ assert_equal expected, events("[\"\xF0\x90\x84\"]")
672
777
  end
673
778
 
674
779
  it 'parses full four byte utf-8 string' do
@@ -749,9 +854,9 @@ describe Yajl::FFI::Parser do
749
854
 
750
855
  private
751
856
 
752
- # Run a worst case, one character at a time, parse against the
753
- # JSON string and return a list of events generated by the parser.
754
- # A special :error event is included if the parser threw an exception.
857
+ # Run a worst case, one byte at a time, parse against the JSON string and
858
+ # return a list of events generated by the parser. A special :error event is
859
+ # included if the parser threw an exception.
755
860
  #
756
861
  # json - The String to parse.
757
862
  # parser - The optional Parser instance to use.
@@ -761,7 +866,7 @@ describe Yajl::FFI::Parser do
761
866
  parser ||= Yajl::FFI::Parser.new
762
867
  collector = Events.new(parser)
763
868
  begin
764
- json.each_char {|ch| parser << ch }
869
+ json.each_byte {|byte| parser << [byte].pack('C') }
765
870
  rescue Yajl::FFI::ParserError
766
871
  collector.error
767
872
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yajl-ffi
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
  - David Graham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-30 00:00:00.000000000 Z
11
+ date: 2014-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi