Module: BinData::Skip::SkipUntilValidPlugin
- Defined in:
- lib/bindata/skip.rb
Overview
Logic for the :until_valid parameter
Defined Under Namespace
Classes: FastSearch, ReadaheadIO
Constant Summary
collapse
- SEARCH_SIZE =
100_000
Instance Method Summary
collapse
Instance Method Details
#fast_search_for(obj) ⇒ Object
145
146
147
148
149
150
151
|
# File 'lib/bindata/skip.rb', line 145
def fast_search_for(obj)
if obj.respond_to?(:asserted_binary_s)
FastSearch.new(obj.asserted_binary_s, obj.rel_offset)
else
nil
end
end
|
#fast_search_for_obj(obj) ⇒ Object
If a search object has an asserted_value
field then we perform a faster search for a valid object.
155
156
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/bindata/skip.rb', line 155
def fast_search_for_obj(obj)
if BinData::Struct === obj
obj.each_pair(true) do |_, field|
fs = fast_search_for(field)
return fs if fs
end
elsif BinData::BasePrimitive === obj
return fast_search_for(obj)
end
nil
end
|
#next_search_index(io, fs) ⇒ Object
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
# File 'lib/bindata/skip.rb', line 170
def next_search_index(io, fs)
buffer = binary_string("")
pos = fs.offset
io.skip(fs.offset)
loop do
data = io.read(SEARCH_SIZE)
raise EOFError, "no match" if data.nil?
buffer << data
index = buffer.index(fs.pattern)
if index
return pos + index - fs.offset
end
searched = buffer.slice!(0..-fs.pattern.size)
pos += searched.size
end
end
|
#read_and_return_value(io) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/bindata/skip.rb', line 111
def read_and_return_value(io)
prototype = get_parameter(:until_valid)
validator = prototype.instantiate(nil, self)
fs = fast_search_for_obj(validator)
io.transform(ReadaheadIO.new) do |transformed_io, raw_io|
pos = 0
loop do
seek_to_pos(pos, raw_io)
validator.clear
validator.do_read(transformed_io)
break
rescue ValidityError
pos += 1
if fs
seek_to_pos(pos, raw_io)
pos += next_search_index(raw_io, fs)
end
end
seek_to_pos(pos, raw_io)
@skip_length = pos
end
end
|
#seek_to_pos(pos, io) ⇒ Object
137
138
139
140
|
# File 'lib/bindata/skip.rb', line 137
def seek_to_pos(pos, io)
io.rollback
io.skip(pos)
end
|
#skip_length ⇒ Object
107
108
109
|
# File 'lib/bindata/skip.rb', line 107
def skip_length
@skip_length ||= 0
end
|