Wildmeshing Toolkit
Loading...
Searching...
No Matches
BinaryIO.hpp
1#pragma once
2
3// The binary encoding the history files share -- the surface's and curves' (History.cpp) and the
4// volume's (VolumeHistory.cpp): unsigned LEB128 varints, little-endian f64s, written to bytes in
5// memory and read from them, which a file holds as they are.
6
7#include <wmtk/utils/Logger.hpp>
8
9#include <Eigen/Core>
10
11#include <cstdint>
12#include <cstring>
13#include <string>
14#include <vector>
15
16namespace wmtk::history::detail {
17
19template <typename Put>
20void put_varint(uint64_t n, Put&& put)
21{
22 do {
23 uint8_t b = n & 0x7F;
24 n >>= 7;
25 if (n) b |= 0x80;
26 put(b);
27 } while (n);
28}
29
31template <typename Get>
32bool get_varint(Get&& get, uint64_t& n)
33{
34 n = 0;
35 for (int shift = 0; shift < 64; shift += 7) {
36 const uint8_t b = get();
37 n |= uint64_t(b & 0x7F) << shift;
38 if (!(b & 0x80)) return true;
39 }
40 return false;
41}
42
45inline uint64_t zigzag(const int64_t x)
46{
47 return (uint64_t(x) << 1) ^ uint64_t(x >> 63);
48}
49
50inline int64_t unzigzag(const uint64_t x)
51{
52 return int64_t(x >> 1) ^ -int64_t(x & 1);
53}
54
56class Writer
57{
58public:
59 explicit Writer(std::vector<uint8_t>& out)
60 : m_out(out)
61 {}
62 template <typename T>
63 void put(const T& x)
64 {
65 const auto* p = reinterpret_cast<const uint8_t*>(&x);
66 m_out.insert(m_out.end(), p, p + sizeof(T));
67 }
68 void byte(const uint8_t b) { m_out.push_back(b); }
69 void varint(const uint64_t n)
70 {
71 put_varint(n, [this](const uint8_t b) { m_out.push_back(b); });
72 }
73 void position(const Eigen::Vector3d& p)
74 {
75 const size_t at = m_out.size();
76 m_out.resize(at + 3 * sizeof(double));
77 std::memcpy(m_out.data() + at, p.data(), 3 * sizeof(double));
78 }
79 void bytes(const char* p, const size_t n)
80 {
81 m_out.insert(
82 m_out.end(),
83 reinterpret_cast<const uint8_t*>(p),
84 reinterpret_cast<const uint8_t*>(p) + n);
85 }
86
87private:
88 std::vector<uint8_t>& m_out;
89};
90
96class Reader
97{
98public:
99 Reader(const uint8_t* p, const uint8_t* end, std::string what, std::string name)
100 : m_p(p)
101 , m_end(end)
102 , m_what(std::move(what))
103 , m_name(std::move(name))
104 {}
106 Reader(const std::vector<uint8_t>& in, std::string name)
107 : Reader(in.data(), in.data() + in.size(), "history", std::move(name))
108 {}
110 uint64_t remaining() const { return uint64_t(m_end - m_p); }
111 const uint8_t* at() const { return m_p; }
114 uint64_t count(const uint64_t min_bytes = 1)
115 {
116 const uint64_t n = varint();
117 if (n > remaining() / min_bytes) corrupt();
118 return n;
119 }
120 [[noreturn]] void corrupt() const { log_and_throw_error("{}: {} is corrupt", m_what, m_name); }
121 template <typename T>
122 T get()
123 {
124 T x;
125 bytes(reinterpret_cast<char*>(&x), sizeof(T));
126 return x;
127 }
128 uint8_t byte() { return get<uint8_t>(); }
129 uint64_t varint()
130 {
131 uint64_t n;
132 if (!get_varint([this]() { return byte(); }, n)) {
133 log_and_throw_error("{}: {} holds a malformed integer", m_what, m_name);
134 }
135 return n;
136 }
137 Eigen::Vector3d position()
138 {
139 Eigen::Vector3d x;
140 for (int k = 0; k < 3; ++k) x[k] = get<double>();
141 return x;
142 }
143 void bytes(char* p, const size_t n)
144 {
145 if (n > remaining()) log_and_throw_error("{}: {} is truncated", m_what, m_name);
146 std::memcpy(p, m_p, n);
147 m_p += n;
148 }
149 std::string string(const uint64_t n)
150 {
151 if (n > remaining()) log_and_throw_error("{}: {} is truncated", m_what, m_name);
152 std::string s(reinterpret_cast<const char*>(m_p), size_t(n));
153 m_p += n;
154 return s;
155 }
156 const std::string& name() const { return m_name; }
157
158private:
159 const uint8_t* m_p;
160 const uint8_t* m_end;
161 std::string m_what, m_name;
162};
163
164} // namespace wmtk::history::detail
Reads the bytes of a history, [p, end). what and name say what they are in messages,...
Definition BinaryIO.hpp:97
uint64_t count(const uint64_t min_bytes=1)
Definition BinaryIO.hpp:114
uint64_t remaining() const
The bytes not read yet, and where they start.
Definition BinaryIO.hpp:110
Reader(const std::vector< uint8_t > &in, std::string name)
All of in, the bytes of a surface's or curves' history.
Definition BinaryIO.hpp:106
Appends to the bytes of a history, as a file holds them.
Definition BinaryIO.hpp:57