Beispiel #1
0
    def parse(self, reader: ByteIO, parent=None, in_array=False):
        name = None
        parent = parent

        if not in_array:
            string_id = reader.read_uint32()
            name = "ERROR" if string_id == -1 else self.strings[string_id]
        add = lambda v: parent.update({name: v}
                                      ) if not in_array else parent.append(v)
        data_type = reader.read_int8()
        flag_info = KVFlag.Nothing
        if data_type & 0x80:
            data_type &= 0x7F
            flag_info = KVFlag(reader.read_int8())

        if data_type == KVType.NULL:
            add(None)
            return
        if data_type == KVType.BOOLEAN:
            add(reader.read_int8() > 0)
            return
        if data_type == KVType.INTEGER:
            add(reader.read_int64())
            return
        if data_type == KVType.DOUBLE:
            add(reader.read_double())
            return
        if data_type == KVType.STRING:
            string_id = reader.read_int32()
            if string_id == -1:
                add(None)
                return
            add(self.strings[string_id])
            return
        if data_type == KVType.ARRAY:
            size = reader.read_uint32()
            arr = []
            for _ in range(size):
                self.parse(reader, arr, True)
            add(arr)
            return
        if data_type == KVType.OBJECT:
            size = reader.read_uint32()
            tmp = {}
            for _ in range(size):
                self.parse(reader, tmp, False)
            add(tmp)
            if not parent:
                parent = tmp
        return parent
Beispiel #2
0
 def read(self, reader: ByteIO):
     fourcc = reader.read_bytes(4)
     assert tuple(fourcc) == self.SIG, 'Invalid KV Signature'
     encoding = reader.read_bytes(16)
     assert tuple(encoding) == self.ENCODING, 'Unrecognized KV3 Encoding'
     format = reader.read_bytes(16)
     assert tuple(format) == self.FORMAT, 'Unrecognised KV3 Format'
     self.flags = reader.read_bytes(4)
     if self.flags[3] & 0x80:
         self.buffer.write_bytes(
             reader.read_bytes(self.info_block.block_size -
                               (reader.tell() -
                                self.info_block.absolute_offset)))
     working = True
     while reader.tell() != reader.size() and working:
         block_mask = reader.read_uint16()
         for i in range(16):
             if block_mask & (1 << i) > 0:
                 offset_and_size = reader.read_uint16()
                 offset = ((offset_and_size & 0xFFF0) >> 4) + 1
                 size = (offset_and_size & 0x000F) + 3
                 lookup_size = offset if offset < size else size
                 entry = self.buffer.tell()
                 self.buffer.seek(entry - offset)
                 data = self.buffer.read_bytes(lookup_size)
                 self.buffer.seek(entry)
                 while size > 0:
                     self.buffer.write_bytes(
                         data[:lookup_size if lookup_size < size else size])
                     size -= lookup_size
             else:
                 data = reader.read_int8()
                 self.buffer.write_int8(data)
             if self.buffer.size() == (self.flags[2] << 16) + (
                     self.flags[1] << 8) + self.flags[0]:
                 working = False
                 break
     self.buffer.seek(0)
     string_count = self.buffer.read_uint32()
     for i in range(string_count):
         self.strings.append(self.buffer.read_ascii_string())
     self.parse(self.buffer, self.kv, True)
     self.buffer.close()
     del self.buffer
Beispiel #3
0
 def read(self, reader: ByteIO, block_info: InfoBlock = None):
     self.info_block = block_info
     entry = reader.tell()
     self.name_offset = reader.read_int32()
     self.name = reader.read_from_offset(entry + self.name_offset,
                                         reader.read_ascii_string)
     self.count = reader.read_int16()
     self.on_disc_size = reader.read_int16()
     entry = reader.tell()
     self.indirection_bytes_offset = reader.read_int32()
     self.indirection_level = reader.read_int32()
     with reader.save_current_pos():
         reader.seek(entry + self.indirection_bytes_offset)
         indir_level = self.indirection_level if self.indirection_level < 10 else 10
         for _ in range(indir_level):
             self.indirection_bytes.append(reader.read_int8())
     self.data_type = reader.read_int32()
     self.type = KeyValueDataType(reader.read_int16())
     reader.skip(2)
Beispiel #4
0
 def read_from_buffer(self, reader: ByteIO):
     if self.format == DXGI_FORMAT.R32G32B32_FLOAT:
         return [
             reader.read_float()
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R32G32B32_UINT:
         return [
             reader.read_uint32()
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R32G32B32_SINT:
         return [
             reader.read_int32()
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R32G32B32A32_FLOAT:
         return [
             reader.read_float()
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R32G32B32A32_UINT:
         return [
             reader.read_uint32()
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R32G32B32A32_SINT:
         return [
             reader.read_int32()
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R16G16_FLOAT:
         return [
             short_to_float(reader.read_int16())
             for _ in range(self.format.name.count('16'))
         ]
     elif self.format == DXGI_FORMAT.R32G32_FLOAT:
         return [
             short_to_float(reader.read_float())
             for _ in range(self.format.name.count('32'))
         ]
     elif self.format == DXGI_FORMAT.R16G16_SINT:
         return [
             reader.read_int16()
             for _ in range(self.format.name.count('16'))
         ]
     elif self.format == DXGI_FORMAT.R16G16_UINT:
         return [
             reader.read_uint16()
             for _ in range(self.format.name.count('16'))
         ]
     elif self.format == DXGI_FORMAT.R8G8B8A8_SNORM:
         return [
             reader.read_int8() for _ in range(self.format.name.count('8'))
         ]
     elif self.format == DXGI_FORMAT.R8G8B8A8_UNORM:
         return [
             reader.read_uint8() for _ in range(self.format.name.count('8'))
         ]
     elif self.format == DXGI_FORMAT.R8G8B8A8_UINT:
         return [
             reader.read_uint8() for _ in range(self.format.name.count('8'))
         ]
     else:
         raise NotImplementedError('Unknown buffer format {}'.format(
             self.format.name))