You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

72 lines
2.5 KiB

  1. # Python implementation of the "rocket" data parsing interface.
  2. # This interface translates between the binary format on disk
  3. # and the ASCII format used when communicating with clients.
  4. # This is slow! Use the C version instead.
  5. import struct
  6. import layout as _layout
  7. class Rocket(object):
  8. def __init__(self, layout):
  9. self.layout = layout
  10. # For packing/unpacking into a binary file.
  11. # This will change in the C version
  12. try:
  13. (self.ltype, lcount) = layout.split('_', 2)
  14. self.lcount = int(lcount)
  15. except:
  16. raise ValueError("no such layout: badly formatted string")
  17. if self.lcount < 1:
  18. raise ValueError("no such layout: bad count")
  19. try:
  20. struct_fmt = '<d' # Little endian, double timestamp
  21. struct_mapping = {
  22. "int8": 'b',
  23. "uint8": 'B',
  24. "int16": 'h',
  25. "uint16": 'H',
  26. "int32": 'i',
  27. "uint32": 'I',
  28. "int64": 'q',
  29. "uint64": 'Q',
  30. "float32": 'f',
  31. "float64": 'd',
  32. }
  33. struct_fmt += struct_mapping[self.ltype] * self.lcount
  34. except KeyError:
  35. raise ValueError("no such layout: bad data type")
  36. self.packer = struct.Struct(struct_fmt)
  37. # For packing/unpacking from strings.
  38. self.formatter = _layout.Formatter(self.layout)
  39. @property
  40. def binary_size(self):
  41. """Return size of one row of data in the binary file, in bytes"""
  42. return self.packer.size
  43. def append_list(self, file, data):
  44. """Append the list data to the file"""
  45. # We assume the file is opened in append mode,
  46. # so all writes go to the end.
  47. for row in data:
  48. file.write(self.packer.pack(*row))
  49. file.flush()
  50. def extract_list(self, file, offset, count):
  51. """Extract count rows of data from the file at offset offset.
  52. Return a list of lists [[row],[row],...]"""
  53. ret = []
  54. file.seek(offset)
  55. for i in xrange(count):
  56. data = file.read(self.binary_size)
  57. ret.append(list(self.packer.unpack(data)))
  58. return ret
  59. def extract_string(self, file, offset, count):
  60. """Extract count rows of data from the file at offset offset.
  61. Return an ascii formatted string according to the layout"""
  62. return self.formatter.format(self.extract_list(file, offset, count))