mirror of
https://github.com/derrod/legendary.git
synced 2025-01-03 04:45:28 +00:00
[models] Add Chunk serialisation
This commit is contained in:
parent
5d91b2b59f
commit
bdd2a14350
|
@ -4,22 +4,25 @@
|
|||
import struct
|
||||
import zlib
|
||||
|
||||
from hashlib import sha1
|
||||
from io import BytesIO
|
||||
|
||||
from legendary.utils.rolling_hash import get_hash
|
||||
|
||||
|
||||
# ToDo do some reworking to make this more memory efficient
|
||||
|
||||
class Chunk:
|
||||
header_magic = 0xB1FE3AA2
|
||||
|
||||
def __init__(self):
|
||||
self.header_version = 0
|
||||
self.header_version = 3
|
||||
self.header_size = 0
|
||||
self.compressed_size = 0
|
||||
self.hash = 0
|
||||
self.stored_as = 0
|
||||
self.guid = []
|
||||
|
||||
# 0x1 = rolling hash, 0x2 = sha hash, 0x3 = both
|
||||
self.hash_type = 0
|
||||
self.sha_hash = None
|
||||
self.uncompressed_size = 1024 * 1024
|
||||
|
@ -45,6 +48,20 @@ class Chunk:
|
|||
|
||||
return self._data
|
||||
|
||||
@data.setter
|
||||
def data(self, value: bytes):
|
||||
# data is now uncompressed
|
||||
if self.compressed:
|
||||
self.stored_as ^= 0x1
|
||||
# pad data to 1 MiB
|
||||
if len(value) < 1024 * 1024:
|
||||
value += b'\x00' * (1024 * 1024 - len(value))
|
||||
# recalculate hashes
|
||||
self.hash = get_hash(value)
|
||||
self.sha_hash = sha1(value).digest()
|
||||
self.hash_type = 0x3
|
||||
self._data = value
|
||||
|
||||
@property
|
||||
def guid_str(self):
|
||||
if not self._guid_str:
|
||||
|
@ -93,3 +110,33 @@ class Chunk:
|
|||
raise ValueError('Did not read entire chunk header!')
|
||||
|
||||
return _chunk
|
||||
|
||||
def write(self, compress=True):
|
||||
bio = BytesIO()
|
||||
|
||||
self.uncompressed_size = self.compressed_size = len(self.data)
|
||||
if compress or self.compressed:
|
||||
self._data = zlib.compress(self.data)
|
||||
self.stored_as |= 0x1
|
||||
self.compressed_size = len(self._data)
|
||||
|
||||
bio.write(struct.pack('<I', self.header_magic))
|
||||
# we only serialize the latest version so version/size are hardcoded to 3/66
|
||||
bio.write(struct.pack('<I', 3))
|
||||
bio.write(struct.pack('<I', 66))
|
||||
bio.write(struct.pack('<I', self.compressed_size))
|
||||
bio.write(struct.pack('<IIII', *self.guid))
|
||||
bio.write(struct.pack('<Q', self.hash))
|
||||
bio.write(struct.pack('<B', self.stored_as))
|
||||
|
||||
# header version 2 stuff
|
||||
bio.write(self.sha_hash)
|
||||
bio.write(struct.pack('B', self.hash_type))
|
||||
|
||||
# header version 3 stuff
|
||||
bio.write(struct.pack('<I', self.uncompressed_size))
|
||||
|
||||
# finally, add the data
|
||||
bio.write(self._data)
|
||||
|
||||
return bio.getvalue()
|
||||
|
|
Loading…
Reference in a new issue