https://github.com/ate47/dbflib
Library to load and create dynamically linked binary files
https://github.com/ate47/dbflib
dynamic-file-structure header-only library
Last synced: 10 months ago
JSON representation
Library to load and create dynamically linked binary files
- Host: GitHub
- URL: https://github.com/ate47/dbflib
- Owner: ate47
- License: mit
- Created: 2024-04-21T13:39:15.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-21T16:59:01.000Z (about 2 years ago)
- Last Synced: 2024-04-22T16:31:40.907Z (about 2 years ago)
- Topics: dynamic-file-structure, header-only, library
- Language: C++
- Homepage:
- Size: 9.77 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Dynamic binary file
Library to load and create 64 bits dynamically linked binary files.
**Table of contents**
- [Dynamic binary file](#dynamic-binary-file)
- [Import library](#import-library)
- [File structure](#file-structure)
- [Header](#header)
- [Links](#links)
- [Usage](#usage)
- [Read file](#read-file)
- [Create file](#create-file)
## Import library
Only the header file in `src/lib` is required for this library.
## File structure
All the numbers are described in little endian.
### Header
The file starts with the header, it is describing the different components of the file.
```cpp
struct DB_FILE {
uint64_t magic = 0x0d0a46424424;
uint8_t version;
uint8_t flags;
uint16_t links_count;
uint32_t links_table_offset;
uint32_t start_offset;
uint32_t data_size;
uint32_t file_size;
uint32_t __pad;
void* last_link;
};
```
| Name | Min version | Description |
| -------------------- | ----------- | --------------------------------- |
| `magic` | 0 | File magic |
| `version` | 0 | The compiled version of this file |
| `flags` | 0 | Compiler dependent flags |
| `links_count` | 0 | Count of links in the links table |
| `links_table_offset` | 0 | Offset of the links table |
| `start_offset` | 0 | Offset of the start |
| `data_size` | 0 | data section size |
| `file_size` | 0 | File size |
| `last_link` | 0 | Internal runtime object |
### Links
The links location is described in the header by the field `links_table_offset`, the count is described in the header by the field `links_count` and each links is defined by this structure:
```cpp
struct DB_FILE_LINK {
uint32_t origin;
uint32_t destination;
};
```
`origin` is describing the origin offset inside the file and `destination` the destination offset. It can be read as
```cpp
*(void**)&file[origin] = &file[destination];
```
## Usage
First include the library in your application
```cpp
#include
```
### Read file
The file reading can be done by reading a buffer containing the data or by reading a file using the type `dbflib::DBFileReader`.
```cpp
// create by reading a file
dbflib::DBFileReader reader{ "path/to/your/file" };
// create by reading a buffer, a size can be given to avoid overflows
dbflib::DBFileReader reader{ buffer, bufferSize };
```
The file will be linked and a pointer to the data can be obtained using
```cpp
MyType* data = (MyType*)reader.GetStart();
```
The pointer requires is bound to the reader for file reading, otherwise it is bound to the buffer for buffer reading.
If the might be moved, the method `Link` can be used on the file to link (if required) the file again.
```cpp
dbflib::DB_FILE* buffer;
// ...
buffer->Link();
MyType* data = buffer->Start();
```
### Create file
The file creation can be done using the type `dbflib::DBFileReader`.
```cpp
dbflib::DBFileBuilder builder{};
```
You can create data blocks using the `CreateBlock` method, it can be used using a buffer or to directly create a memory block. It returns a block id.
A link can be create between 2 blocks to link them, it is done using the `CreateLink` method.
For example, let's take this small structure
```cpp
struct DemoLinkSub {
int valsub;
};
struct DemoLinkRoot {
int valroot;
DemoLinkSub* link;
};
```
We want to link `DemoLinkSub` to `DemoLinkRoot` using the link field.
For that we first create the 2 blocks.
```cpp
auto [rootId, root] = builder.CreateBlock();
// we can init the block data
root->valroot = 42;
auto [subId, sub] = builder.CreateBlock();
sub->valsub = 32;
```
Note that the `CreateBlock` method is returning a pointer to the created block, this pointer is valid until we create another block. To get the pointer after another block creation, the `GetBlock` method can be used.
```cpp
DemoLinkRoot* rootBlock = builder.GetBlock(rootId);
```
This pointer will also be valid until another block is created.
To add a link, we use the `CreateLink` method.
```cpp
builder.CreateLink(rootId, offsetof(DemoLinkRoot, link), subId);
```
Once all the blocks are created, we can build the file. It can be done using the `Build` method or directly by using the `WriteToFile`.
```cpp
// build and return a pointer
dbflib::DB_FILE* buffer = Build();
// build and write the object into a file
builder.WriteToFile("path/to/your/file");
```