Files
Hippolyzer/hippolyzer/lib/base/vfs.py
Salad Dais 237a409ee0 Move serialization templates and VFS code to lib.base
Not being able to use common enums in code in lib.base was
getting to be really annoying. It always should have been in
base anyways.
2021-05-23 10:44:18 +00:00

68 lines
2.0 KiB
Python

import dataclasses
from typing import *
import hippolyzer.lib.base.serialization as se
from hippolyzer.lib.base.datatypes import UUID
from hippolyzer.lib.base.helpers import get_resource_filename
from hippolyzer.lib.base.templates import AssetType
@dataclasses.dataclass
class VFSBlock:
location: int = se.dataclass_field(se.U32)
length: int = se.dataclass_field(se.U32)
access_time: int = se.dataclass_field(se.U32)
file_id: UUID = se.dataclass_field(se.UUID)
asset_type: AssetType = se.dataclass_field(se.IntEnum(AssetType, se.U16))
size: int = se.dataclass_field(se.U32)
class VFS:
def __init__(self, index_path):
self._data_fh = None
self.blocks = []
self._uuid_lookup: Dict[UUID, VFSBlock] = {}
assert "index.db2" in index_path
self._index_path = index_path
self.reload()
def reload(self):
self.blocks.clear()
self._uuid_lookup.clear()
if self._data_fh:
self._data_fh.close()
self._data_fh = None
self._data_fh = open(self._index_path.replace("index.db2", "data.db2"), "rb")
with open(self._index_path, "rb") as index_fh:
reader = se.FHReader("<", index_fh)
while reader:
block: VFSBlock = reader.read(se.Dataclass(VFSBlock))
if not block.size:
continue
self.blocks.append(block)
self._uuid_lookup[block.file_id] = block
def __iter__(self):
return iter(self.blocks)
def __getitem__(self, item: UUID):
return self._uuid_lookup[item]
def __contains__(self, item: UUID):
return item in self._uuid_lookup
def __del__(self):
if self._data_fh:
self._data_fh.close()
self._data_fh = None
def read_block(self, block: VFSBlock):
self._data_fh.seek(block.location)
return self._data_fh.read(block.size)
_static_path = get_resource_filename("lib/base/data/static_index.db2")
STATIC_VFS = VFS(_static_path)