Example #1
0
def Float(parent):
    size = parent['size'].value
    if size == 4:
        return Float32(parent, 'float')
    elif size == 8:
        return Float64(parent, 'double')
    else:
        return RawBytes(parent, 'INVALID_FLOAT', size)
Example #2
0
def parseBinaryComplex(parent):
    yield Float64(parent, "real")
    yield Float64(parent, "complex")
Example #3
0
def parseBinaryFloat(parent):
    yield Float64(parent, "value")
Example #4
0
def parseDate(parent):
    yield Float64(parent, "timestamp_microsec")
    yield UInt16(parent, "timestamp_sec")
Example #5
0
def parseDouble(parent):
    yield Float64(parent, "value")
Example #6
0
    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(
                        '&', '&amp;').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('&', '&amp;').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: ''