aboutsummaryrefslogtreecommitdiff
path: root/src/format_v2.h
diff options
context:
space:
mode:
authorJan Sucan <jan@jansucan.com>2025-01-20 13:02:22 +0100
committerJán Sučan <jan@jansucan.com>2025-01-22 15:55:33 +0100
commitcf8eac7777e81590b24e8d285560188e31035c16 (patch)
treec90ec77b6446c87b13bc1a4e638095bf6811b096 /src/format_v2.h
parent79a8749249c61799ff894695431376f997c25781 (diff)
Add header to diff file format v2
Diffstat (limited to 'src/format_v2.h')
-rw-r--r--src/format_v2.h51
1 files changed, 48 insertions, 3 deletions
diff --git a/src/format_v2.h b/src/format_v2.h
index e9b4edb..e1c752a 100644
--- a/src/format_v2.h
+++ b/src/format_v2.h
@@ -35,6 +35,8 @@
namespace FormatV2
{
+const std::string FileSignature{"diff-dd image"};
+const uint16_t FileVersion{2};
const size_t RecordHeaderSize{sizeof(uint64_t) + sizeof(uint32_t)};
struct RecordData {
@@ -42,11 +44,20 @@ struct RecordData {
std::shared_ptr<char[]> data;
};
+class Error : public DiffddError
+{
+ public:
+ explicit Error(const std::string &message) : DiffddError(message) {}
+};
+
class Writer
{
public:
Writer(std::ostream &ostream, size_t buffer_size)
- : m_writer{BufferedStream::Writer{ostream, buffer_size}} {};
+ : m_writer{BufferedStream::Writer{ostream, buffer_size}}
+ {
+ writeFileHeader();
+ };
void writeDiffRecord(
uint64_t offset, size_t size,
@@ -62,6 +73,14 @@ class Writer
private:
BufferedStream::Writer m_writer;
+ void writeFileHeader()
+ {
+ m_writer.write(FileSignature.data(), FileSignature.size());
+
+ uint16_t val{htobe16(FileVersion)};
+ m_writer.write(reinterpret_cast<char *>(&val), sizeof(val));
+ };
+
void writeOffset(uint64_t offset)
{
uint64_t val{htobe64(offset)};
@@ -84,11 +103,37 @@ class Reader
{
public:
Reader(std::istream &istream, size_t buffer_size)
- : m_reader{BufferedStream::Reader{istream, buffer_size, 1}},
- m_eof{false} {};
+ : m_reader{BufferedStream::Reader{istream, buffer_size, 1}}, m_eof{
+ false}
+ {
+ readFileHeader();
+ };
bool eof() { return m_eof; };
+ void readFileHeader()
+ {
+ auto rawSignature{std::make_unique<char[]>(FileSignature.size())};
+ size_t r{m_reader.read(FileSignature.size(), rawSignature.get())};
+ if (r < FileSignature.size()) {
+ throw new Error("cannot read file header signature");
+ }
+ const std::string signature{rawSignature.get(), FileSignature.size()};
+ if (signature != FileSignature) {
+ throw new Error("wrong file header signature");
+ }
+
+ uint16_t rawVersion;
+ r = {m_reader.read(sizeof(rawVersion),
+ reinterpret_cast<char *>(&rawVersion))};
+ if (r < sizeof(rawVersion)) {
+ throw new Error("cannot read file header version");
+ }
+ if (be16toh(rawVersion) != FileVersion) {
+ throw new Error("wrong file header version");
+ }
+ };
+
uint64_t readOffset()
{
uint64_t raw_offset;