class Tros::DataFile::Reader

Read files written by DataFileWriter

Attributes

block_count[RW]
block_decoder[R]

The binary decoder for the contents of a block (after codec decompression)

codec[R]
datum_reader[R]
decoder[R]

The reader and binary decoder for the raw file stream

file_length[R]
meta[R]
reader[R]

The reader and binary decoder for the raw file stream

sync_marker[R]

Public Class Methods

new(reader, datum_reader) click to toggle source
    # File lib/tros/data_file.rb
213 def initialize(reader, datum_reader)
214   @reader = reader
215   @decoder = IO::BinaryDecoder.new(reader)
216   @datum_reader = datum_reader
217 
218   # read the header: magic, meta, sync
219   read_header
220 
221   @codec = DataFile.get_codec(meta['tros.codec'])
222 
223   # get ready to read
224   @block_count = 0
225   datum_reader.writers_schema = Schema.parse meta['tros.schema']
226 end

Public Instance Methods

close() click to toggle source
    # File lib/tros/data_file.rb
251 def close
252   reader.close
253 end
each() { |datum| ... } click to toggle source

Iterates through each datum in this file TODO(jmhodges): handle block of length zero

    # File lib/tros/data_file.rb
230 def each
231   loop do
232     if block_count == 0
233       case
234       when eof?; break
235       when skip_sync
236         break if eof?
237         read_block_header
238       else
239         read_block_header
240       end
241     end
242 
243     datum = datum_reader.read(block_decoder)
244     self.block_count -= 1
245     yield(datum)
246   end
247 end
eof?() click to toggle source
    # File lib/tros/data_file.rb
249 def eof?; reader.eof?; end

Private Instance Methods

read_block_header() click to toggle source
    # File lib/tros/data_file.rb
278 def read_block_header
279   self.block_count = decoder.read_long
280   block_bytes = decoder.read_long
281   data = codec.decompress(reader.read(block_bytes))
282   @block_decoder = IO::BinaryDecoder.new(StringIO.new(data))
283 end
read_header() click to toggle source
    # File lib/tros/data_file.rb
256 def read_header
257   # seek to the beginning of the file to get magic block
258   reader.seek(0, 0)
259 
260   # check magic number
261   magic_in_file = reader.read(MAGIC_SIZE)
262   if magic_in_file.size < MAGIC_SIZE
263     msg = 'Not an Tros data file: shorter than the Tros magic block'
264     raise DataFileError, msg
265   elsif magic_in_file != MAGIC
266     msg = "Not an Tros data file: #{magic_in_file.inspect} doesn't match #{MAGIC.inspect}"
267     raise DataFileError, msg
268   end
269 
270   # read metadata
271   @meta = datum_reader.read_data(META_SCHEMA,
272                                  META_SCHEMA,
273                                  decoder)
274   # read sync marker
275   @sync_marker = reader.read(SYNC_SIZE)
276 end
skip_sync() click to toggle source

read the length of the sync marker; if it matches the sync marker, return true. Otherwise, seek back to where we started and return false

    # File lib/tros/data_file.rb
288 def skip_sync
289   proposed_sync_marker = reader.read(SYNC_SIZE)
290   if proposed_sync_marker != sync_marker
291     reader.seek(-SYNC_SIZE, 1)
292     false
293   else
294     true
295   end
296 end