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 +4 -4
- data/lib/json-projection/parser.rb +39 -32
- data/lib/json-projection/parser/fifo.rb +17 -17
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b310ebdff6509d59c9737225a97b66de49a2ced
|
4
|
+
data.tar.gz: 705ca5b363df43245d2c8a3180343acb4584707c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
71
|
-
#
|
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
|
-
@
|
80
|
-
|
82
|
+
@character_buffer = Buffer.new
|
83
|
+
|
84
|
+
@characters_cursor = -1
|
85
|
+
@characters = nil
|
81
86
|
|
82
|
-
@
|
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
|
-
|
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 @
|
105
|
-
data = stream.read(
|
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
|
-
@
|
115
|
+
@characters = @character_buffer.<<(data).each_char.to_a
|
116
|
+
@characters_cursor = 0
|
111
117
|
end
|
112
118
|
|
113
|
-
|
114
|
-
|
119
|
+
character = @characters[@characters_cursor]
|
120
|
+
@characters_cursor += 1
|
115
121
|
|
116
|
-
@
|
117
|
-
@pos += 1
|
122
|
+
@stream_position += 1
|
118
123
|
|
119
|
-
new_state,
|
124
|
+
new_state, new_events = handle_character(@state, character)
|
120
125
|
|
121
126
|
@state = new_state
|
122
|
-
@event_buffer
|
127
|
+
@event_buffer.prepend!(new_events)
|
123
128
|
|
124
|
-
|
125
|
-
|
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(
|
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(
|
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,
|
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,
|
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,
|
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,
|
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.
|
488
|
+
events = Fifo.pure
|
482
489
|
|
483
490
|
if @stack.pop == type
|
484
491
|
case type
|
485
492
|
when :object then
|
486
|
-
events
|
493
|
+
events.push!(EndObject.empty)
|
487
494
|
when :array then
|
488
|
-
events
|
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
|
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 #{@
|
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(
|
9
|
-
Fifo.new(
|
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
|
-
|
16
|
+
def push!(val)
|
17
|
+
@stack.insert(0, val)
|
18
18
|
end
|
19
19
|
|
20
|
-
def pop
|
21
|
-
|
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
|
43
|
-
return
|
44
|
-
|
45
|
-
|
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
|
-
|
48
|
+
def stack
|
49
|
+
@stack
|
50
|
+
end
|
51
51
|
|
52
52
|
end
|
53
53
|
end
|