|
- # Python implementation of the "rocket" data parsing interface.
- # This interface translates between the binary format on disk
- # and the ASCII format used when communicating with clients.
-
- # This is slow! Use the C version instead.
-
- import struct
- import layout as _layout
-
- class Rocket(object):
- def __init__(self, layout):
- self.layout = layout
-
- # For packing/unpacking into a binary file.
- # This will change in the C version
- try:
- (self.ltype, lcount) = layout.split('_', 2)
- self.lcount = int(lcount)
- except:
- raise ValueError("no such layout: badly formatted string")
- if self.lcount < 1:
- raise ValueError("no such layout: bad count")
- try:
- struct_fmt = '<d' # Little endian, double timestamp
- struct_mapping = {
- "int8": 'b',
- "uint8": 'B',
- "int16": 'h',
- "uint16": 'H',
- "int32": 'i',
- "uint32": 'I',
- "int64": 'q',
- "uint64": 'Q',
- "float32": 'f',
- "float64": 'd',
- }
- struct_fmt += struct_mapping[self.ltype] * self.lcount
- except KeyError:
- raise ValueError("no such layout: bad data type")
- self.packer = struct.Struct(struct_fmt)
-
- # For packing/unpacking from strings.
- self.formatter = _layout.Formatter(self.layout)
-
- @property
- def binary_size(self):
- """Return size of one row of data in the binary file, in bytes"""
- return self.packer.size
-
- def append_list(self, file, data):
- """Append the list data to the file"""
- # We assume the file is opened in append mode,
- # so all writes go to the end.
- for row in data:
- file.write(self.packer.pack(*row))
- file.flush()
-
- def extract_list(self, file, offset, count):
- """Extract count rows of data from the file at offset offset.
- Return a list of lists [[row],[row],...]"""
- ret = []
- file.seek(offset)
- for i in xrange(count):
- data = file.read(self.binary_size)
- ret.append(list(self.packer.unpack(data)))
- return ret
-
- def extract_string(self, file, offset, count):
- """Extract count rows of data from the file at offset offset.
- Return an ascii formatted string according to the layout"""
- return self.formatter.format(self.extract_list(file, offset, count))
|