Как лучше построить архитектуру парсер файла?
Есть файлы, которые по сути являются Compound File (в файле есть, скажем так, файловая система, есть папки (storages) и файлы (streams)). Нужно извлечь оттуда данные.
Какие данные? Есть конечные storages, в которых есть определённые streams (Property, Data, Indexes...)
Как их извлечь? С помощью olefile получаем данные в сыром виде.
ole.openstream(endpoint_storage + ["Data"])
Далее поток байт нужно превратить в какие-то структуры. Делается всё с помощью модуля struct. Может есть какие-то модули, которые позволяют это дело упростить (как bincode в Rust? (Извлекать данные, а потом создавать экземляр датакласса - не очень)
Как это выглядит?
@dataclass
class PropertyUnit:
...
@dataclass
class Indexes:
...
class BaseParser:
def __init__(self, filename):
self.ole = olefile.OleFileIO(filename)
self.opened = {}
def get_endpoint_data(self, storage) -> EndpointStorage:
raw_data = self.ole.openstream(stream + ["Data"])
raw_prop = self.ole.openstream(stream + ["Property"])
props = self.parse_property(raw_prop)
data = self.parse_data(raw_data, props)
return EndpointStorage(props=props, data=data)
@staticmethod
def parse_property(raw_prop) -> List[PropertyUnit]:
result = []
(prop_length,) = struct.unpack("<i", raw_prop.read(4))
for _ in range(prop_length):
n_id, name, m_type = struct.unpack("<i64si", raw_prop.read(4 + 64 + 4))
name = name[:name.find(b'\x00') if name.find(b'\x00') != -1 else len(name)].decode('cp1251')
result.append(PropertyUnit(id=n_id, name=name, type=m_type))
return result
@staticmethod
def parse_data(raw_data, props: List[PropertyUnit]) -> Data:
result = []
(data_length,) = struct.unpack("<i", raw_prop.read(4))
for _ in range(data_length):
for prop in props:
...
return result
Код плохой, поэтому укажите на ошибки. И главное - как лучше спроектировать программу? Как в общих чертах должна выглядеть программа? Чувствую, на BaseParser ложится слишком много отвественности.