json-projection 0.1.3 → 0.2.0

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: 6b331a3db1a52374a5cdfae9d4357696d5096c91
4
- data.tar.gz: 50a134c347705a60af03fb8ad42f591431c5ea61
3
+ metadata.gz: 5b310ebdff6509d59c9737225a97b66de49a2ced
4
+ data.tar.gz: 705ca5b363df43245d2c8a3180343acb4584707c
5
5
  SHA512:
6
- metadata.gz: 06f10ad2683686a49c487de9b045019a3e42279871815f276bfd0b365ed634cec990082e2725da7d59af207ef8d9a3db450d72f9ba50cbb83edb0731bc81cc21
7
- data.tar.gz: a24b80cb879125ef11a14d050d6e7edf9c2e04855ec56dafe9e748ed99c2ff8dc6ed59b2efafd651a320d8239995238eff3cfbeaaa255e1b6e54c46fb1e34066
6
+ metadata.gz: 818bfe7cd12ea0b9a06316822b875595ee4608fe74114a39963901aa7f584a02e20edbca77fe1e926ffae64155debd31f7185fa983f53d82974f01686c085dfc
7
+ data.tar.gz: 9a911520fc8b962704ac1a3cf87dfef0d2528b52dc3dac4b17b89407328b1278338ec68fa01f0d21cf8b9fd443d5ef669d770f1831a9fdf2d2ae2b2b569fdd38
@@ -34,7 +34,6 @@ module JsonProjection
34
34
  # Use the json gem for small documents. Use this for huge documents that
35
35
  # won't fit in memory.
36
36
  class Parser
37
- BUF_SIZE = 4096
38
37
  CONTROL = /[\x00-\x1F]/
39
38
  WS = /[ \n\t\r]/
40
39
  HEX = /[0-9a-fA-F]/
@@ -67,19 +66,25 @@ module JsonProjection
67
66
  # events are drawn from the parser. The parser maintains a small data cache
68
67
  # of bytes read from the stream.
69
68
  #
70
- # stream :: IO
71
- # IO stream to read data from.
69
+ # stream :: IO
70
+ # IO stream to read data from.
71
+ #
72
+ # chunk_size :: Integer
73
+ # Number of bytes to read from the stream at a time.
72
74
  #
73
75
  # Returns nothing.
74
- def initialize(stream)
76
+ def initialize(stream, chunk_size = 4096)
75
77
  @stream = stream
78
+ @chunk_size = chunk_size
76
79
 
77
80
  @event_buffer = Fifo.new
78
81
 
79
- @bytes_buffer = Buffer.new
80
- @bytes = nil
82
+ @character_buffer = Buffer.new
83
+
84
+ @characters_cursor = -1
85
+ @characters = nil
81
86
 
82
- @pos = -1
87
+ @stream_position = -1
83
88
  @state = :start_document
84
89
  @stack = []
85
90
 
@@ -93,7 +98,7 @@ module JsonProjection
93
98
  # Returns a JsonProject::StreamEvent subclass or raises StandardError.
94
99
  def next_event()
95
100
  # Are there any already read events, return the oldest
96
- @event_buffer, event = @event_buffer.pop
101
+ event = @event_buffer.pop!
97
102
  return event unless event.nil?
98
103
 
99
104
  if @state == :end_document
@@ -101,30 +106,28 @@ module JsonProjection
101
106
  end
102
107
 
103
108
  while true do
104
- if @bytes.nil? || @bytes.empty?
105
- data = stream.read(BUF_SIZE)
109
+ if @characters.nil? || @characters_cursor == @characters.size
110
+ data = stream.read(@chunk_size)
106
111
  if data == nil # hit EOF
107
112
  error("unexpected EOF")
108
113
  end
109
114
 
110
- @bytes = @bytes_buffer.<<(data).each_char.to_a
115
+ @characters = @character_buffer.<<(data).each_char.to_a
116
+ @characters_cursor = 0
111
117
  end
112
118
 
113
- head = @bytes.first
114
- tail = @bytes.slice!(1, @bytes.size - 1)
119
+ character = @characters[@characters_cursor]
120
+ @characters_cursor += 1
115
121
 
116
- @bytes = tail
117
- @pos += 1
122
+ @stream_position += 1
118
123
 
119
- new_state, events = handle_character(@state, head)
124
+ new_state, new_events = handle_character(@state, character)
120
125
 
121
126
  @state = new_state
122
- @event_buffer = events.append(@event_buffer)
127
+ @event_buffer.prepend!(new_events)
123
128
 
124
- unless @event_buffer.empty?
125
- @event_buffer, event = @event_buffer.pop
126
- return event
127
- end
129
+ event = @event_buffer.pop!
130
+ return event unless event.nil?
128
131
  end
129
132
  end
130
133
 
@@ -151,13 +154,13 @@ module JsonProjection
151
154
  when LEFT_BRACE
152
155
  @stack.push(:object)
153
156
 
154
- events = Fifo.pure(StartDocument.empty).push(StartObject.empty)
157
+ events = Fifo.pure(StartObject.empty, StartDocument.empty)
155
158
 
156
159
  return :start_object, events
157
160
  when LEFT_BRACKET
158
161
  @stack.push(:array)
159
162
 
160
- events = Fifo.pure(StartDocument.empty).push(StartArray.empty)
163
+ events = Fifo.pure(StartArray.empty, StartDocument.empty)
161
164
 
162
165
  return :start_array, events
163
166
  end
@@ -296,8 +299,9 @@ module JsonProjection
296
299
  state = :end_value
297
300
 
298
301
  state, new_events = handle_character(state, ch)
302
+ events.prepend!(new_events)
299
303
 
300
- return state, new_events.append(events)
304
+ return state, events
301
305
  end
302
306
 
303
307
  when :start_float
@@ -324,8 +328,9 @@ module JsonProjection
324
328
  state = :end_value
325
329
 
326
330
  state, new_events = handle_character(state, ch)
331
+ events.prepend!(new_events)
327
332
 
328
- return state, new_events.append(events)
333
+ return state, events
329
334
  end
330
335
 
331
336
  when :start_exponent
@@ -351,8 +356,9 @@ module JsonProjection
351
356
  state = :end_value
352
357
 
353
358
  state, new_events = handle_character(state, ch)
359
+ events.prepend!(new_events)
354
360
 
355
- return state, new_events.append(events)
361
+ return state, events
356
362
  end
357
363
 
358
364
  when :start_int
@@ -373,8 +379,9 @@ module JsonProjection
373
379
  state = :end_value
374
380
 
375
381
  state, new_events = handle_character(state, ch)
382
+ events.prepend!(new_events)
376
383
 
377
- return state, new_events.append(events)
384
+ return state, events
378
385
  end
379
386
 
380
387
  when :start_true
@@ -478,14 +485,14 @@ module JsonProjection
478
485
  # a value.
479
486
  def end_container(type)
480
487
  state = :end_value
481
- events = Fifo.empty
488
+ events = Fifo.pure
482
489
 
483
490
  if @stack.pop == type
484
491
  case type
485
492
  when :object then
486
- events = events.push(EndObject.empty)
493
+ events.push!(EndObject.empty)
487
494
  when :array then
488
- events = events.push(EndArray.empty)
495
+ events.push!(EndArray.empty)
489
496
  end
490
497
  else
491
498
  error("Expected end of #{type}")
@@ -493,7 +500,7 @@ module JsonProjection
493
500
 
494
501
  if @stack.empty?
495
502
  state = :end_document
496
- events = events.push(EndDocument.empty)
503
+ events.push!(EndDocument.empty)
497
504
  end
498
505
 
499
506
  return state, events
@@ -587,7 +594,7 @@ module JsonProjection
587
594
  end
588
595
 
589
596
  def error(message)
590
- raise ParseError, "#{message}: char #{@pos}"
597
+ raise ParseError, "#{message}: char #{@stream_position}"
591
598
  end
592
599
  end
593
600
 
@@ -2,28 +2,23 @@ module JsonProjection
2
2
  class Fifo
3
3
 
4
4
  def self.empty
5
- @empty ||= self.new
5
+ @empty ||= self.new([].freeze)
6
6
  end
7
7
 
8
- def self.pure(val)
9
- Fifo.new([val])
8
+ def self.pure(*vals)
9
+ Fifo.new(vals)
10
10
  end
11
11
 
12
12
  def initialize(stack = [])
13
13
  @stack = stack
14
14
  end
15
15
 
16
- def push(val)
17
- Fifo.new(@stack.dup.insert(0, val))
16
+ def push!(val)
17
+ @stack.insert(0, val)
18
18
  end
19
19
 
20
- def pop()
21
- return self, nil if empty?
22
-
23
- init = @stack.slice(0, @stack.size - 1)
24
- last = @stack.last
25
-
26
- return Fifo.new(init), last
20
+ def pop!
21
+ @stack.pop
27
22
  end
28
23
 
29
24
  def empty?
@@ -39,15 +34,20 @@ module JsonProjection
39
34
  stack.hash
40
35
  end
41
36
 
42
- def append(fifo)
43
- return self if fifo.empty?
44
- return fifo if self.empty?
45
- Fifo.new(@stack.concat(fifo.stack))
37
+ def prepend!(fifo)
38
+ return if fifo.empty?
39
+ if empty?
40
+ @stack = fifo.stack.dup
41
+ return
42
+ end
43
+ @stack = fifo.stack.concat(@stack)
46
44
  end
47
45
 
48
46
  protected
49
47
 
50
- attr_reader :stack
48
+ def stack
49
+ @stack
50
+ end
51
51
 
52
52
  end
53
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-projection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Duncan