json-projection 0.1.3 → 0.2.0

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