wowlib
0.0.0
Read & write World of Warcraft client files — a C++26 core
Toggle main menu visibility
Loading...
Searching...
No Matches
bit_stream.hpp
Go to the documentation of this file.
1
#pragma once
2
9
10
#include <cstddef>
11
#include <cstdint>
12
#include <cstring>
13
14
namespace
wowlib::db::wdc
{
16
class
BitReader
{
17
public
:
20
BitReader
(
const
std::byte* base, std::size_t limit) : _base(base), _limit(limit) {}
21
30
std::uint64_t
read
(std::size_t bitOffset, std::size_t bits)
const
{
31
if
(bits == 0 || bits > 64)
return
0;
32
const
std::size_t
byte
= bitOffset / 8;
33
const
std::size_t shift = bitOffset % 8;
34
const
std::size_t spanBytes = (shift + bits + 7) / 8;
35
if
(
byte
+ spanBytes > _limit)
return
0;
36
// Load the touched bytes as two little-endian halves: `lo` holds the
37
// first eight, `hi` the ninth when the value straddles that far.
38
std::uint64_t lo = 0, hi = 0;
39
const
std::size_t loBytes = spanBytes > 8 ? 8 : spanBytes;
40
std::memcpy(&lo, _base +
byte
, loBytes);
41
if
(spanBytes > 8) std::memcpy(&hi, _base +
byte
+ 8, spanBytes - 8);
42
// Drop the leading bits that belong to the previous field, then splice
43
// the high half's contribution in above them.
44
std::uint64_t raw = lo >> shift;
45
if
(shift != 0 && spanBytes > 8) raw |= hi << (64 - shift);
46
if
(bits < 64) raw &= (std::uint64_t{1} << bits) - 1;
47
return
raw;
48
}
49
50
private
:
51
const
std::byte* _base;
52
std::size_t _limit;
53
};
54
59
class
BitWriter
{
60
public
:
63
BitWriter
(std::byte* base, std::size_t limit) : _base(base), _limit(limit) {}
64
71
void
write
(std::size_t bitOffset, std::size_t bits, std::uint64_t value) {
72
for
(std::size_t i = 0; i < bits; ++i) {
73
const
std::size_t bo = bitOffset + i;
74
if
(bo / 8 >= _limit)
return
;
75
const
std::byte mask{
static_cast<
unsigned
char
>
(1u << (bo % 8))};
76
if
((value >> i) & 1) _base[bo / 8] |= mask;
77
else
_base[bo / 8] &= ~mask;
78
}
79
}
80
81
private
:
82
std::byte* _base;
83
std::size_t _limit;
84
};
85
}
wowlib::db::wdc::BitReader::read
std::uint64_t read(std::size_t bitOffset, std::size_t bits) const
Read bits (<= 64) starting at absolute bit offset bitOffset.
Definition
bit_stream.hpp:30
wowlib::db::wdc::BitReader::BitReader
BitReader(const std::byte *base, std::size_t limit)
Definition
bit_stream.hpp:20
wowlib::db::wdc::BitWriter::BitWriter
BitWriter(std::byte *base, std::size_t limit)
Definition
bit_stream.hpp:63
wowlib::db::wdc::BitWriter::write
void write(std::size_t bitOffset, std::size_t bits, std::uint64_t value)
Write the low bits of value starting at absolute bit offset bitOffset, overwriting whatever was there...
Definition
bit_stream.hpp:71
wowlib::db::wdc
Definition
binary.hpp:30
src
wowlib
db
wdc
bit_stream.hpp
Generated by
1.17.0