-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbindings.cpp
More file actions
87 lines (73 loc) · 3.36 KB
/
bindings.cpp
File metadata and controls
87 lines (73 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "libbbf.h"
#include "bbf_reader.h"
namespace py = pybind11;
PYBIND11_MODULE(_bbf, m) {
m.doc() = "Bound Book Format (BBF) Python Bindings";
// --- BBFBuilder (Writer) ---
py::class_<BBFBuilder>(m, "BBFBuilder")
.def(py::init<const std::string &>())
.def("add_page", &BBFBuilder::addPage,
py::arg("path"), py::arg("type"), py::arg("flags") = 0,
"Add a page from a file path.")
.def("add_section", &BBFBuilder::addSection,
py::arg("title"), py::arg("start_page"), py::arg("parent") = 0xFFFFFFFF,
"Add a section. start_page is the 0-based index.")
.def("add_metadata", &BBFBuilder::addMetadata,
"Add Key:Value metadata.")
.def("finalize", &BBFBuilder::finalize,
"Write the footer and close the file.");
// --- BBFReader (Reader) ---
py::class_<BBFReader>(m, "BBFReader")
.def(py::init<const std::string &>())
.def_readonly("is_valid", &BBFReader::isValid)
.def("close", [](BBFReader& r)
{
r.mmap.unmap();
r.isValid = false; // Prevent further reads
}, "Unmaps the file immediately.")
.def("get_page_count", [](BBFReader& r) { return r.footer.pageCount; })
.def("get_asset_count", [](BBFReader& r) { return r.footer.assetCount; })
.def("verify", &BBFReader::verify,
py::call_guard<py::gil_scoped_release>(),
"Verify integrity. Returns: -1 (Success), -2 (Directory Fail), or >=0 (Index of corrupt asset).")
.def("verify_page", &BBFReader::verifyPage,
"Verify a single page, returns a dict <uint64_t, bool>, {calculated hash, match?}.")
.def("get_sections", [](BBFReader& r)
{
py::list result;
const auto sections = r.getSections();
for (const auto& s : sections) {
py::dict d;
d["title"] = s.title;
d["startPage"] = s.startPage;
d["parent"] = s.parent;
result.append(d);
}
return result;
}, "Returns sections as [{'title': str, 'startPage': int, 'parent': int}]")
.def("get_footer", &BBFReader::getFooterInfo,
"Returns a dict representing the footer.")
.def("get_metadata", &BBFReader::getMetadata,
"Returns a list of (Key, Value) tuples.")
.def("get_page_info", &BBFReader::getPageInfo,
"Returns dict with keys: length, offset, hash, type, decodedLength")
.def("get_page_data", [](BBFReader& r, uint32_t idx)
{
auto raw = r.getPageRaw(idx);
if (!raw.first) return py::bytes("");
return py::bytes(raw.first, raw.second);
}, "Returns the raw bytes of the page asset (1-Copy).")
.def("get_page_view", [](BBFReader& r, uint32_t idx)
{
auto raw = r.getPageRaw(idx);
if (!raw.first) return py::memoryview(py::bytes(""));
return py::memoryview::from_memory(
const_cast<char*>(raw.first),
raw.second,
true // read-only
);
}, py::keep_alive<0, 1>(),
"Returns a zero-copy memoryview of the asset. Fastest method.");
}