Формат DBPF2 и его декодирование: Часть практическая, типы данных
Реализация декодирования формата DBPF2 содержится в файле siS3DBPF2Decoder.pas
Статьи по теме
- библиотека компонентов для работы с файлами TS3 – DBPF2: описание формата, на русском языке
- библиотека компонентов для работы с файлами TS3 – DBPF2: декодер и кодер, на русском языке;
Заголовок файла
Размер записи 96 байт, полей как видно много, но назначение большинства из них неизвестно, а если и известно, то неизвестно применение.
Для декодирования файла важны два поля:
Sig: packed array[0..3] of BYTE – сигнатура файла, содержит текст "DBPF" (или "DBPP" если заголовок шифрованый), при сравнении удобно сравнивать сигнатуру не побайтно, а сразу как 32-разрядное целое: (PInt(@FHeader.Sig[0])^<>$46504244) для "DBPF" (или с $50504244 для "DBPP");
IndexEntryCount: DWORD – число записей в индексной таблице;
MajorVersion, MinorVersion: DWORD – версия формата, 2.0;
IndexSize: DWORD – размер индексной таблицы в байтах, вычисляется довольно сложно потому, что размер индексной записи не фиксированный, а зависит от типа индекса (IndexType), точнее IndexType выступает как битовая маска – каждому полю записи соответствует свой бит и при установке его поле выносится перед всеми записями, а затем пропускается во всех записях. В общем случае
IndexSize = 4 * (1 + число_установленных_бит_в_IndexType + (8 - число_установленных_бит_в_IndexType) *IndexEntryCount;
IndexOffset: DWORD – абсолютное смещение индексной таблицы от начала файла в байтах;
Индексная запись
Свойства
- ResourceType: DWORD – тип ресурса, чтение/запись;
- ResourceGroup: DWORD – группа, чтение/запись;
- InstanceHi: DWORD – старшие 32 бит экземпляра, чтение/запись;
- InstanceLo: DWORD – младшие 32 бит экземпляра, чтение/запись;
- Instance: UInt64 – экземпляр (64 бит), чтение/запись;
- Offset: DWORD – абсолютное смещение данных с начала файла, только чтение;
- PackedSize: DWORD – упакованный размер, старший бит сброшен (в файле DBPF2 он установлен, но так с ним было бы неудобно работать, по этому при записи файла он должен быть приведен в соответствие), только чтение;
- MemSize: DWORD – распакованный размер), только чтение;
- Compressed: WORD – признак того, что блок сжат $0000 - нет, $FFFF – да, чтение/запись;
- Stream: TStream – ссылка на вторичный поток, чтение/запись;
Методы
constructor Create(AOwner: TDBPF2File) – конструктор класса, как аргумент получает декодер, индексной таблице которого принадлежит запись;
destructor Destroy; – виртуальный деструктор, освобождает вторичный поток и запись, вместо него нужно использовать Free;
procedure FreeStream – освобождает вторичный поток (вызывает его Free), то же что и Stream:= nil, но работает быстрее, при попытке освободить поток для записи которой нет в исходном файле – помечает запись как удаленную;
procedure UnlinkStream – удаляет ссылку на вторичный поток, но не удаляет его, необходимо вызывать ее, а не FreeStream, если поток использовался в добавлялся в другой TDBPF2Decoder;
procedure Decode(AStream: TStream) – декодирует запись, то же что и Stream:= AStream, но работает быстрее, если запись уже декодирована, то вначале освобождает старый вторичный поток;
function Decoded: boolean – возвращает true, если запись уже декодирована;
function Exists: boolean – проверяет запись на наличие, возвращает false если запись удалена.