Пример #1
0
def extend_data(data, length, offset):
    """Extend data using a length and an offset."""
    if length >= offset:
        new_data = data[-offset:] * (alignValue(length, offset) // offset)
        return data + new_data[:length]
    else:
        return data + data[-offset:-offset + length]
Пример #2
0
 def __init__(self, *args):
     FieldSet.__init__(self, *args)
     self._size = (8 + alignValue(self["size"].value, 2)) * 8
     tag = self["type"].value
     if tag in self.TAG_INFO:
         self._name, self._description, self._parser = self.TAG_INFO[tag]
     else:
         self._parser = None
Пример #3
0
 def __init__(self, *args, **kw):
     FieldSet.__init__(self, *args, **kw)
     try:
         self._name, self.handler, self._description = self.TAG_INFO[self["tag"].value]
     except KeyError:
         self.handler = None
     size = self["size"]
     self._size = size.address + size.size + alignValue(size.value, 2) * 8
Пример #4
0
 def createFields(self):
     if self.has_all_byte:
         yield Enum(UInt8(self, "all_defined"), {0: 'False', 1: 'True'})
         if self['all_defined'].value:
             return
     nbytes = alignValue(self.num, 8) // 8
     ctr = 0
     for i in xrange(nbytes):
         for j in reversed(xrange(8)):
             yield Bit(self, "bit[%d]" % (ctr + j))
         ctr += 8
Пример #5
0
    def setCheckedSizes(self, size):
        # First set size so that end is aligned, if needed
        self.real_size = size
        size *= 8
        if self.ALIGN:
            size = alignValue(self.absolute_address + size, 8 * self.ALIGN) \
                   - self.absolute_address

        if self._parent._size:
            if self._parent.current_size + size > self._parent._size:
                size = self._parent._size - self._parent.current_size

        self._size = size
Пример #6
0
def hexadecimal(field):
    """
    Convert an integer to hexadecimal in lower case. Returns unicode string.

    >>> hexadecimal(type("", (), dict(value=412, size=16)))
    u'0x019c'
    >>> hexadecimal(type("", (), dict(value=0, size=32)))
    u'0x00000000'
    """
    assert hasattr(field, "value") and hasattr(field, "size")
    size = field.size
    padding = alignValue(size, 4) // 4
    pattern = u"0x%%0%ux" % padding
    return pattern % field.value
Пример #7
0
 def __init__(self, *args, **kw):
     FieldSet.__init__(self, *args, **kw)
     self._size = (8 + alignValue(self["size"].value, 2)) * 8
     tag = self["tag"].value
     if tag in self.TAG_INFO:
         self.tag_info = self.TAG_INFO[tag]
         if tag == "LIST":
             subtag = self["subtag"].value
             if subtag in self.subtag_info:
                 info = self.subtag_info[subtag]
                 self.tag_info = (info[0], None, info[1])
         self._name = self.tag_info[0]
         self._description = self.tag_info[2]
     else:
         self.tag_info = ("field[]", None, None)
Пример #8
0
    def readBits(self, address, nbits, endian):
        assert endian in (BIG_ENDIAN, LITTLE_ENDIAN, MIDDLE_ENDIAN)

        if endian is MIDDLE_ENDIAN:
            # read an aligned chunk of words
            wordaddr, remainder = divmod(address, 16)
            wordnbits = alignValue(remainder + nbits, 16)
            _, data, missing = self.read(wordaddr * 16, wordnbits)
            shift = remainder
        else:
            shift, data, missing = self.read(address, nbits)
        if missing:
            raise ReadStreamError(nbits, address)
        value = str2long(data, endian)
        if endian in (BIG_ENDIAN, MIDDLE_ENDIAN):
            value >>= len(data) * 8 - shift - nbits
        else:
            value >>= shift
        return value & (1 << nbits) - 1
Пример #9
0
 def createFields(self):
     yield String(self, "signature", 4, "8BIM signature", charset="ASCII")
     if self["signature"].value != "8BIM":
         raise ParserError("Stream doesn't look like 8BIM item (wrong signature)!")
     yield textHandler(UInt16(self, "tag"), hexadecimal)
     if self.stream.readBytes(self.absolute_address + self.current_size, 4) != "\0\0\0\0":
         yield PascalString8(self, "name")
         size = 2 + (self["name"].size // 8) % 2
         yield NullBytes(self, "name_padding", size)
     else:
         yield String(self, "name", 4, strip="\0")
     yield UInt16(self, "size")
     size = alignValue(self["size"].value, 2)
     if not size:
         return
     if self.handler:
         if issubclass(self.handler, FieldSet):
             yield self.handler(self, "content", size=size * 8)
         else:
             yield self.handler(self, "content")
     else:
         yield RawBytes(self, "content", size)
Пример #10
0
 def __init__(self, parent, name):
     FieldSet.__init__(self, parent, name)
     self._size = alignValue(self["size"].value, 4) * 8
Пример #11
0
 def __init__(self, parent, name, is_32bit=True):
     FieldSet.__init__(self, parent, name)
     self._size = alignValue(self["size"].value, 4) * 8
     self.is_32bit = is_32bit
Пример #12
0
 def __init__(self, parent, name, width, pixel_class):
     FieldSet.__init__(self, parent, name)
     self._pixel = pixel_class
     self._width = width
     self._size = alignValue(self._width * self._pixel.static_size, 32)
Пример #13
0
    def __init__(self,
                 parent,
                 name,
                 format,
                 description=None,
                 strip=None,
                 charset=None,
                 nbytes=None,
                 truncate=None):
        Bytes.__init__(self, parent, name, 1, description)

        # Is format valid?
        assert format in self.VALID_FORMATS

        # Store options
        self._format = format
        self._strip = strip
        self._truncate = truncate

        # Check charset and compute character size in bytes
        # (or None when it's not possible to guess character size)
        if not charset or charset in self.CHARSET_8BIT:
            self._character_size = 1  # one byte per character
        elif charset in self.UTF_CHARSET:
            self._character_size = None
        else:
            raise FieldError("Invalid charset for %s: \"%s\"" %
                             (self.path, charset))
        self._charset = charset

        # It is a fixed string?
        if nbytes is not None:
            assert self._format == "fixed"
            # Arbitrary limits, just to catch some bugs...
            if not (1 <= nbytes <= 0xffff):
                raise FieldError("Invalid string size for %s: %s" %
                                 (self.path, nbytes))
            self._content_size = nbytes  # content length in bytes
            self._size = nbytes * 8
            self._content_offset = 0
        else:
            # Format with a suffix: Find the end of the string
            if self._format in self.SUFFIX_FORMAT:
                self._content_offset = 0

                # Choose the suffix
                suffix = self.suffix_str

                # Find the suffix
                length = self._parent.stream.searchBytesLength(
                    suffix, False, self.absolute_address)
                if length is None:
                    raise FieldError(
                        "Unable to find end of string %s (format %s)!" %
                        (self.path, self._format))
                if 1 < len(suffix):
                    # Fix length for little endian bug with UTF-xx charset:
                    #   u"abc" -> "a\0b\0c\0\0\0" (UTF-16-LE)
                    #   search returns length=5, whereas real lenght is 6
                    length = alignValue(length, len(suffix))

                # Compute sizes
                self._content_size = length  # in bytes
                self._size = (length + len(suffix)) * 8

            # Format with a prefix: Read prefixed length in bytes
            else:
                assert self._format in self.PASCAL_FORMATS

                # Get the prefix size
                prefix_size = self.PASCAL_FORMATS[self._format]
                self._content_offset = prefix_size

                # Read the prefix and compute sizes
                value = self._parent.stream.readBits(self.absolute_address,
                                                     prefix_size * 8,
                                                     self._parent.endian)
                self._content_size = value  # in bytes
                self._size = (prefix_size + value) * 8

        # For UTF-16 and UTF-32, choose the right charset using BOM
        if self._charset in self.UTF_CHARSET:
            # Charset requires a BOM?
            bomsize, endian = self.UTF_CHARSET[self._charset]
            if endian == "BOM":
                # Read the BOM value
                nbytes = bomsize // 8
                bom = self._parent.stream.readBytes(self.absolute_address,
                                                    nbytes)

                # Choose right charset using the BOM
                bom_endian = self.UTF_BOM[bomsize]
                if bom not in bom_endian:
                    raise FieldError("String %s has invalid BOM (%s)!" %
                                     (self.path, repr(bom)))
                self._charset = bom_endian[bom]
                self._content_size -= nbytes
                self._content_offset += nbytes

        # Compute length in character if possible
        if self._character_size:
            self._length = self._content_size // self._character_size
        else:
            self._length = None