forked from cryfs/cryfs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSerializer.h
More file actions
148 lines (117 loc) · 4.44 KB
/
Copy pathSerializer.h
File metadata and controls
148 lines (117 loc) · 4.44 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#pragma once
#ifndef MESSMER_CPPUTILS_DATA_SERIALIZER_H
#define MESSMER_CPPUTILS_DATA_SERIALIZER_H
#include "Data.h"
#include "FixedSizeData.h"
#include "../macros.h"
#include "../assert/assert.h"
#include <string>
#include "SerializationHelper.h"
namespace cpputils {
//TODO Test Serializer/Deserializer
//TODO Also test system (big endian/little endian) by adding a serialized data file to the repository and (a) reading it and (b) rewriting and comparing it
class Serializer final {
public:
Serializer(size_t size);
void writeBool(bool value);
void writeUint8(uint8_t value);
void writeInt8(int8_t value);
void writeUint16(uint16_t value);
void writeInt16(int16_t value);
void writeUint32(uint32_t value);
void writeInt32(int32_t value);
void writeUint64(uint64_t value);
void writeInt64(int64_t value);
void writeString(const std::string &value);
void writeData(const Data &value);
template<size_t SIZE> void writeFixedSizeData(const FixedSizeData<SIZE> &value);
// Write the data as last element when serializing.
// It does not store a data size but limits the size by the size of the serialization result
void writeTailData(const Data &value);
static size_t BoolSize();
static size_t DataSize(const Data &value);
static size_t StringSize(const std::string &value);
Data finished();
private:
template<typename DataType> void _write(DataType obj);
void _writeData(const void *data, size_t count);
size_t _pos;
Data _result;
DISALLOW_COPY_AND_ASSIGN(Serializer);
};
inline Serializer::Serializer(size_t size): _pos(0), _result(size) {
}
inline size_t Serializer::BoolSize() {
return sizeof(uint8_t);
}
inline void Serializer::writeBool(bool value) {
writeUint8(value ? 1 : 0);
}
inline void Serializer::writeUint8(uint8_t value) {
_write<uint8_t>(value);
}
inline void Serializer::writeInt8(int8_t value) {
_write<int8_t>(value);
}
inline void Serializer::writeUint16(uint16_t value) {
_write<uint16_t>(value);
}
inline void Serializer::writeInt16(int16_t value) {
_write<int16_t>(value);
}
inline void Serializer::writeUint32(uint32_t value) {
_write<uint32_t>(value);
}
inline void Serializer::writeInt32(int32_t value) {
_write<int32_t>(value);
}
inline void Serializer::writeUint64(uint64_t value) {
_write<uint64_t>(value);
}
inline void Serializer::writeInt64(int64_t value) {
_write<int64_t>(value);
}
template<typename DataType>
inline void Serializer::_write(DataType obj) {
if (_pos + sizeof(DataType) > _result.size()) {
throw std::runtime_error("Serialization failed - size overflow");
}
serialize<DataType>(_result.dataOffset(_pos), obj);
_pos += sizeof(DataType);
}
inline void Serializer::writeData(const Data &data) {
writeUint64(data.size());
_writeData(data.data(), data.size());
}
inline size_t Serializer::DataSize(const Data &data) {
return sizeof(uint64_t) + data.size();
}
template<size_t SIZE>
inline void Serializer::writeFixedSizeData(const FixedSizeData<SIZE> &data) {
_writeData(data.data(), SIZE);
}
inline void Serializer::writeTailData(const Data &data) {
ASSERT(_pos + data.size() == _result.size(), "Not enough data given to write until the end of the stream");
_writeData(data.data(), data.size());
}
inline void Serializer::_writeData(const void *data, size_t count) {
if (_pos + count > _result.size()) {
throw std::runtime_error("Serialization failed - size overflow");
}
std::memcpy(static_cast<char*>(_result.dataOffset(_pos)), static_cast<const char*>(data), count);
_pos += count;
}
inline void Serializer::writeString(const std::string &value) {
_writeData(value.c_str(), value.size() + 1); // +1 for the nullbyte
}
inline size_t Serializer::StringSize(const std::string &value) {
return value.size() + 1; // +1 for nullbyte
}
inline Data Serializer::finished() {
if (_pos != _result.size()) {
throw std::runtime_error("Serialization failed - size not fully used.");
}
return std::move(_result);
}
}
#endif