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: common_defs.hpp:32
size_t size_of_item(const T &item) const
Definition: serde.hpp:124
void serialize(std::ostream &os, const T *items, unsigned num) const
Definition: serde.hpp:83
size_t serialize(void *ptr, size_t capacity, const T *items, unsigned num) const
Definition: serde.hpp:108
size_t deserialize(const void *ptr, size_t capacity, T *items, unsigned num) const
Definition: serde.hpp:116
void serialize(std::ostream &os, const std::string *items, unsigned num) const
Definition: serde.hpp:138
void deserialize(std::istream &is, std::string *items, unsigned num) const
Definition: serde.hpp:156
size_t serialize(void *ptr, size_t capacity, const std::string *items, unsigned num) const
Definition: serde.hpp:185
size_t deserialize(const void *ptr, size_t capacity, std::string *items, unsigned num) const
Definition: serde.hpp:201
size_t size_of_item(const std::string &item) const
Definition: serde.hpp:238
Interface for serializing and deserializing items.
Definition: serde.hpp:34
void deserialize(std::istream &is, T *items, unsigned num) const
size_t serialize(void *ptr, size_t capacity, const T *items, unsigned num) const
size_t deserialize(const void *ptr, size_t capacity, T *items, unsigned num) const
size_t size_of_item(const T &item) const
void serialize(std::ostream &os, const T *items, unsigned num) const