-
Notifications
You must be signed in to change notification settings - Fork 58
BaW file format
The file format consists of Blobs which are binary dumps of C++ structs. These structs are carefully designed to ensure they have the same memory layout on all compilers available. The way to achieve that is to make sure there are no padding bytes. BaW format is able to load various version of BaW files with fixed size known as fixedSizeBlob or with size that may be known only on runtime (like ICPUBuffer
, you can't specify it's size while compiling) called variableSizeBlob
. The writer is able to deal only with the latest version. It can serialize everything deriving from BlobSerializable
, so all Assets available at the moment. BaW format has been also designed to deal with a data not being an Asset nor BlobSerializable
, but data being raw.
The BaW file looks like bellow:
- Header
- Table of Offsets to Blobs
- Blob Headers
- Blob Data
Where Header looks like:
- 256bit header which consists of
HEADER_STRING
("IrrlichtBaW BinaryFile") and the file version - Number of Blobs
- 128bit Initialization Vector used for block based encryption
- A fake-sized array of offsets for indexing Blobs
{FileHeaderVN}
{Table Of Offsets To Blob Contents}
{Blob Headers}
{Blob Contents}
Where FileHeaderVN
is sizeof(FileHeaderVN) - sizeof(uint32_t). The sizeof(uint32_t)
is just a fake array mentioned above - for indexing Blobs. VN
postfix means version. Blob Headers are separated with Blob Contents because Blob Contents may be compressed, or encrypted, so per-blob-header needs to be apart separately from the contents. It allows to read headers without decryption or decompression. Significant thing to remember is read offset in Table Of Offsets is relative to file position.
As mentioned, the Writer will need to handle file with the latest version. In the loader case, you can load any file with X version. Loader will be converting file with version X to the latest version. Because of that, some functions will have to be provided by a user, because there must be known ways to convert a file starting from X version to the latest used. So imagine that one of your Assets has changed itself and a one new member has been added to it. You have to for instance provide a function preparing a final size for such a Blob that will be created basing on the Asset. In case where you load previous version file, where there was no such a member, you will have to provide a constructor that will create an Asset with the newer one version of Asset and fill a member with a default value for example. Due to new version, and so new member, you will have to create a new function mentioned earlier to calculate new size of Blob though. Because everything you do with BaW format usage is versioned, you have to provide new ones functions changing the Version using
/typedef
. If there is something that has been deleted in newer versions, you have to put it to legacy
section that has been created for those Blobs/Functions that are needed to handle older version.
// TODO
// TODO
// More info - TODO