12 std::int64_t
readInt(std::span<const std::byte> image, std::size_t& pos, std::size_t bytes,
bool isSigned) {
13 std::uint64_t raw = 0;
14 std::memcpy(&raw, image.data() + pos, bytes);
16 if (isSigned && bytes < 8) {
17 const std::uint64_t signBit = std::uint64_t{1} << (bytes * 8 - 1);
18 if (raw & signBit) raw |= ~((std::uint64_t{1} << (bytes * 8)) - 1);
20 return static_cast<std::int64_t
>(raw);
24 const auto raw =
static_cast<std::uint64_t
>(value);
25 for (std::size_t i = 0; i < bytes; ++i) out.push_back(
static_cast<std::byte
>((raw >> (i * 8)) & 0xff));
30 std::uint32_t readU32(std::span<const std::byte> image, std::size_t& pos) {
32 std::memcpy(&v, image.data() + pos, 4);
37 void writeU32(
FileBuffer& out, std::uint32_t v) {
38 const auto* b =
reinterpret_cast<const std::byte*
>(&v);
39 out.insert(out.end(), b, b + 4);
44 if (
block.empty()) std::ignore =
block.add(
"");
50 const std::vector<std::uint32_t>& journal,
51 std::size_t& cursor) {
52 const std::size_t slot = cursor++;
53 const std::string owned{value};
54 if (slot < journal.size()) {
55 const std::uint32_t original = journal[slot];
56 if (
block.at(original) == owned)
return original;
58 if (
const auto it =
lookup.find(owned); it !=
lookup.end())
return it->second;
59 const std::uint32_t offset =
block.add(owned);
60 lookup.emplace(owned, offset);
66 std::span<const std::byte> image,
71 for (
const Column& c : schema) {
78 for (std::uint16_t e = 0; e < c.arrayLen; ++e)
79 sink.
setInt(record, col, e,
readInt(image, pos, c.bits / 8u, c.isSigned));
82 for (std::uint16_t e = 0; e < c.arrayLen; ++e)
83 sink.
setFloat(record, col, e, std::bit_cast<float>(readU32(image, pos)));
86 for (std::uint16_t e = 0; e < c.arrayLen; ++e) {
87 const std::uint32_t off = readU32(image, pos);
93 for (std::uint8_t loc = 0; loc < c.localeCount; ++loc) {
94 const std::uint32_t off = readU32(image, pos);
98 sink.
setInt(record, col, c.localeCount, readU32(image, pos));
111 std::size_t& cursor) {
113 for (
const Column& c : schema) {
120 for (std::uint16_t e = 0; e < c.arrayLen; ++e)
writeInt(out, source.
getInt(record, col, e), c.bits / 8u);
123 for (std::uint16_t e = 0; e < c.arrayLen; ++e) writeU32(out, source.
getSlot(record, col, e));
126 for (std::uint16_t e = 0; e < c.arrayLen; ++e)
130 for (std::uint8_t loc = 0; loc < c.localeCount; ++loc)
132 writeU32(out,
static_cast<std::uint32_t
>(source.
getInt(record, col, c.localeCount)));
The decode target: the codecs build the record vector through this, one field at a time.
virtual void setFloat(std::size_t record, std::size_t column, std::size_t element, float value)=0
virtual void setString(std::size_t record, std::size_t column, std::size_t element, std::string_view value)=0
virtual void setInt(std::size_t record, std::size_t column, std::size_t element, std::int64_t value)=0
The encode source: the codecs read the record vector through this.
virtual std::int64_t getInt(std::size_t record, std::size_t column, std::size_t element) const =0
virtual std::uint32_t getSlot(std::size_t record, std::size_t column, std::size_t element) const =0
virtual std::string_view getString(std::size_t record, std::size_t column, std::size_t element) const =0
Shared codec internals for the fixed-stride formats (WDBC, WDB2): the string pool that reproduces byt...
std::int64_t readInt(std::span< const std::byte > image, std::size_t &pos, std::size_t bytes, bool isSigned)
Read a little-endian integer of bytes bytes at pos, sign-extended when isSigned, advancing pos.
void decodeInlineRecord(std::span< const Column > schema, std::size_t record, std::span< const std::byte > image, RecordSink &sink, TableState &state)
Decode one fixed-stride record's inline fields into sink and journal its string offsets (record then ...
void encodeInlineRecord(std::span< const Column > schema, const RecordSource &source, std::size_t record, FileBuffer &out, StringPool &pool, const TableState &state, std::size_t &cursor)
Encode one fixed-stride record's inline fields from source, appending to out and resolving strings th...
void writeInt(FileBuffer &out, std::int64_t value, std::size_t bytes)
Append value's low bytes bytes (little-endian) to out.
@ Int
An integer column; Column::bits / Column::isSigned give the shape.
@ Float
A 32-bit IEEE float column.
@ String
A string-block reference column (u32 offset on disk).
@ LocString
A pre-Cataclysm localized string column (see LocString).
std::vector< std::byte > FileBuffer
Owning byte buffer for file contents read out of a client storage.
One column of a record schema, derived from a record member by reflection (typed records) or from the...
The preserved decode state a table carries between read() and write() so a WDBC/WDB2 write is byte-pe...
formats::StringBlock strings
Preserved string block; offsets never move.
std::vector< std::uint32_t > stringOffsets
The original string-block offset of every string field, row-major in record then schema order — the b...
A writable string block resolving values to byte-perfect offsets: the journaled original offset while...
StringPool(const formats::StringBlock &source)
Copy source (leading with the mandatory zero byte) and index it.
formats::StringBlock block
std::unordered_map< std::string, std::uint32_t > lookup
std::uint32_t resolve(std::string_view value, const std::vector< std::uint32_t > &journal, std::size_t &cursor)
The offset to store for value: journal[cursor] when it still holds value, else a deduped/appended off...
One decoded string and the blob byte offset other chunks reference it by.