def __init__(self, parent, name, description=None): GenericInteger.__init__(self, parent, name, False, 8, description) i = GenericInteger.createValue(self) if i == 0: raise ParserError('Invalid integer length!') while i < 0x80: self._size += 8 i <<= 1
def createFields(self): yield Unsigned(self, 'track') yield Int16(self, 'timecode') if self.parent._name == 'Block': yield NullBits(self, 'reserved[]', 4) yield Bit(self, 'invisible') yield self.lacing() yield NullBits(self, 'reserved[]', 1) elif self.parent._name.startswith('SimpleBlock'): yield Bit(self, 'keyframe') yield NullBits(self, 'reserved', 3) yield Bit(self, 'invisible') yield self.lacing() yield Bit(self, 'discardable') else: yield NullBits(self, 'reserved', 8) return size = (self._size - self.current_size) // 8 lacing = self['lacing'].value if lacing: yield textHandler(GenericInteger(self, 'n_frames', False, 8), lambda chunk: str(chunk.value + 1)) yield Lace(self, lacing - 1, size - 1) else: yield RawBytes(self, 'frame', size)
def SInt(parent): return GenericInteger(parent, 'signed', True, parent['size'].value * 8)
def UInt(parent): return GenericInteger(parent, 'unsigned', False, parent['size'].value * 8)
def Bool(parent): return textHandler(GenericInteger(parent, 'bool', False, parent['size'].value * 8), lambda chunk: str(chunk.value != 0))
def Enum(parent, enum): return _Enum(GenericInteger(parent, 'enum', False, parent['size'].value * 8), enum)
def SeekID(parent): return textHandler(GenericInteger(parent, 'binary', False, parent['size'].value * 8), lambda chunk: segment.get(chunk.value, (hexadecimal(chunk),))[0])
def Date(parent): return textHandler(GenericInteger(parent, 'date', True, parent['size'].value * 8), dateToString)
def __init__(self, parent, name, description=None): size = parent['/trailer/objectRefSize'].value * 8 GenericInteger.__init__(self, parent, name, False, size, description)
def createFields(self): yield Enum(Bits(self, "marker_type", 4), {0: "Simple", 1: "Int", 2: "Real", 3: "Date", 4: "Data", 5: "ASCII String", 6: "UTF-16-BE String", 8: "UID", 10: "Array", 13: "Dict", }) markertype = self['marker_type'].value if markertype == 0: # Simple (Null) yield Enum(Bits(self, "value", 4), {0: "Null", 8: "False", 9: "True", 15: "Fill Byte", }) if self['value'].display == "False": self.xml = lambda prefix: prefix + "<false/>" elif self['value'].display == "True": self.xml = lambda prefix: prefix + "<true/>" else: self.xml = lambda prefix: prefix + "" elif markertype == 1: # Int yield Bits(self, "size", 4, "log2 of number of bytes") size = self['size'].value # 8-bit (size=0), 16-bit (size=1) and 32-bit (size=2) numbers are unsigned # 64-bit (size=3) numbers are signed yield GenericInteger(self, "value", (size >= 3), (2**size) * 8) self.xml = lambda prefix: prefix + \ "<integer>%s</integer>" % self['value'].value elif markertype == 2: # Real yield Bits(self, "size", 4, "log2 of number of bytes") if self['size'].value == 2: # 2**2 = 4 byte float yield Float32(self, "value") elif self['size'].value == 3: # 2**3 = 8 byte float yield Float64(self, "value") else: # FIXME: What is the format of the real? yield Bits(self, "value", (2**self['size'].value) * 8) self.xml = lambda prefix: prefix + \ "<real>%s</real>" % self['value'].value elif markertype == 3: # Date yield Bits(self, "extra", 4, "Extra value, should be 3") # Use a heuristic to determine which epoch to use def cvt_time(v): v = timedelta(seconds=v) epoch2001 = datetime(2001, 1, 1) epoch1970 = datetime(1970, 1, 1) if (epoch2001 + v - datetime.today()).days > 5 * 365: return epoch1970 + v return epoch2001 + v yield displayHandler(Float64(self, "value"), lambda x: humanDatetime(cvt_time(x))) self.xml = lambda prefix: prefix + \ "<date>%sZ</date>" % ( cvt_time(self['value'].value).isoformat()) elif markertype == 4: # Data yield BPListSize(self, "size") if self['size'].value: yield Bytes(self, "value", self['size'].value) self.xml = lambda prefix: prefix + \ "<data>\n%s\n%s</data>" % ( self['value'].value.encode('base64').strip(), prefix) else: self.xml = lambda prefix: prefix + '<data></data>' elif markertype == 5: # ASCII String yield BPListSize(self, "size") if self['size'].value: yield String(self, "value", self['size'].value, charset="ASCII") self.xml = lambda prefix: prefix + \ "<string>%s</string>" % (self['value'].value.replace( '&', '&').encode('iso-8859-1')) else: self.xml = lambda prefix: prefix + '<string></string>' elif markertype == 6: # UTF-16-BE String yield BPListSize(self, "size") if self['size'].value: yield String(self, "value", self['size'].value * 2, charset="UTF-16-BE") self.xml = lambda prefix: prefix + \ "<string>%s</string>" % ( self['value'].value.replace('&', '&').encode('utf-8')) else: self.xml = lambda prefix: prefix + '<string></string>' elif markertype == 8: # UID yield Bits(self, "size", 4, "Number of bytes minus 1") yield GenericInteger(self, "value", False, (self['size'].value + 1) * 8) self.xml = lambda prefix: prefix + "" # no equivalent? elif markertype == 10: # Array yield BPListSize(self, "size") size = self['size'].value if size: yield BPListArray(self, "value", size) self.xml = lambda prefix: self['value'].createXML(prefix) elif markertype == 13: # Dict yield BPListSize(self, "size") yield BPListDict(self, "value", self['size'].value) self.xml = lambda prefix: self['value'].createXML(prefix) else: yield Bits(self, "value", 4) self.xml = lambda prefix: ''
def readInteger(self, content_size): # Always signed? yield GenericInteger(self, "value", True, content_size * 8)