20 #ifndef DATASKETCHES_SERDE_HPP_
21 #define DATASKETCHES_SERDE_HPP_
29 #include "memory_operations.hpp"
34 template<
typename T,
typename Enable =
void>
struct serde {
41 void serialize(std::ostream& os,
const T* items,
unsigned num)
const;
49 void deserialize(std::istream& is, T* items,
unsigned num)
const;
58 size_t serialize(
void* ptr,
size_t capacity,
const T* items,
unsigned num)
const;
67 size_t deserialize(
const void* ptr,
size_t capacity, T* items,
unsigned num)
const;
81 struct serde<T, typename std::enable_if<std::is_arithmetic<T>::value>::type> {
83 void serialize(std::ostream& os,
const T* items,
unsigned num)
const {
86 os.write(
reinterpret_cast<const char*
>(items),
sizeof(T) * num);
87 }
catch (std::ostream::failure&) {
90 if (failure || !os.good()) {
91 throw std::runtime_error(
"error writing to std::ostream with " + std::to_string(num) +
" items");
95 void deserialize(std::istream& is, T* items,
unsigned num)
const {
98 is.read((
char*)items,
sizeof(T) * num);
99 }
catch (std::istream::failure&) {
102 if (failure || !is.good()) {
103 throw std::runtime_error(
"error reading from std::istream with " + std::to_string(num) +
" items");
108 size_t serialize(
void* ptr,
size_t capacity,
const T* items,
unsigned num)
const {
109 const size_t bytes_written =
sizeof(T) * num;
110 check_memory_size(bytes_written, capacity);
111 memcpy(ptr, items, bytes_written);
112 return bytes_written;
116 size_t deserialize(
const void* ptr,
size_t capacity, T* items,
unsigned num)
const {
117 const size_t bytes_read =
sizeof(T) * num;
118 check_memory_size(bytes_read, capacity);
119 memcpy(items, ptr, bytes_read);
138 void serialize(std::ostream& os,
const std::string* items,
unsigned num)
const {
140 bool failure =
false;
142 for (; i < num && os.good(); i++) {
143 uint32_t length =
static_cast<uint32_t
>(items[i].size());
144 os.write((
char*)&length,
sizeof(length));
145 os.write(items[i].c_str(), length);
147 }
catch (std::ostream::failure&) {
150 if (failure || !os.good()) {
151 throw std::runtime_error(
"error writing to std::ostream at item " + std::to_string(i));
156 void deserialize(std::istream& is, std::string* items,
unsigned num)
const {
158 bool failure =
false;
160 for (; i < num; i++) {
162 is.read((
char*)&length,
sizeof(length));
163 if (!is.good()) {
break; }
166 for (uint32_t j = 0; j < length; j++) {
167 str.push_back(
static_cast<char>(is.get()));
169 if (!is.good()) {
break; }
170 new (&items[i]) std::string(std::move(str));
172 }
catch (std::istream::failure&) {
175 if (failure || !is.good()) {
177 for (
unsigned j = 0; j < i; ++j) {
178 items[j].~basic_string();
180 throw std::runtime_error(
"error reading from std::istream at item " + std::to_string(i));
185 size_t serialize(
void* ptr,
size_t capacity,
const std::string* items,
unsigned num)
const {
186 size_t bytes_written = 0;
187 for (
unsigned i = 0; i < num; ++i) {
188 const uint32_t length =
static_cast<uint32_t
>(items[i].size());
189 const size_t new_bytes = length +
sizeof(length);
190 check_memory_size(bytes_written + new_bytes, capacity);
191 memcpy(ptr, &length,
sizeof(length));
192 ptr =
static_cast<char*
>(ptr) +
sizeof(uint32_t);
193 memcpy(ptr, items[i].c_str(), length);
194 ptr =
static_cast<char*
>(ptr) + length;
195 bytes_written += new_bytes;
197 return bytes_written;
201 size_t deserialize(
const void* ptr,
size_t capacity, std::string* items,
unsigned num)
const {
202 size_t bytes_read = 0;
204 bool failure =
false;
205 for (; i < num && !failure; ++i) {
207 if (bytes_read +
sizeof(length) > capacity) {
208 bytes_read +=
sizeof(length);
212 memcpy(&length, ptr,
sizeof(length));
213 ptr =
static_cast<const char*
>(ptr) +
sizeof(uint32_t);
214 bytes_read +=
sizeof(length);
216 if (bytes_read + length > capacity) {
217 bytes_read += length;
221 new (&items[i]) std::string(
static_cast<const char*
>(ptr), length);
222 ptr =
static_cast<const char*
>(ptr) + length;
223 bytes_read += length;
228 for (
unsigned j = 0; j < i; ++j)
229 items[j].~basic_string();
231 check_memory_size(bytes_read, capacity);
239 return sizeof(uint32_t) + item.size();
DataSketches namespace.
Definition: binomial_bounds.hpp:38
size_t size_of_item(const T &item) const
Size of the given item.
Definition: serde.hpp:124
size_t deserialize(const void *ptr, size_t capacity, T *items, unsigned num) const
Raw bytes deserialization.
Definition: serde.hpp:116
void serialize(std::ostream &os, const T *items, unsigned num) const
Stream serialization.
Definition: serde.hpp:83
size_t serialize(void *ptr, size_t capacity, const T *items, unsigned num) const
Raw bytes serialization.
Definition: serde.hpp:108
void serialize(std::ostream &os, const std::string *items, unsigned num) const
Stream serialization.
Definition: serde.hpp:138
size_t serialize(void *ptr, size_t capacity, const std::string *items, unsigned num) const
Raw bytes serialization.
Definition: serde.hpp:185
size_t size_of_item(const std::string &item) const
Size of the given item.
Definition: serde.hpp:238
size_t deserialize(const void *ptr, size_t capacity, std::string *items, unsigned num) const
Raw bytes deserialization.
Definition: serde.hpp:201
void deserialize(std::istream &is, std::string *items, unsigned num) const
Stream deserialization.
Definition: serde.hpp:156
Interface for serializing and deserializing items.
Definition: serde.hpp:34
size_t size_of_item(const T &item) const
Size of the given item.
size_t deserialize(const void *ptr, size_t capacity, T *items, unsigned num) const
Raw bytes deserialization.
void deserialize(std::istream &is, T *items, unsigned num) const
Stream deserialization.
void serialize(std::ostream &os, const T *items, unsigned num) const
Stream serialization.
size_t serialize(void *ptr, size_t capacity, const T *items, unsigned num) const
Raw bytes serialization.