1/* sane - Scanner Access Now Easy. 2 3 Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> 4 5 This file is part of the SANE package. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the 10 License, or (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. 19*/ 20 21#ifndef BACKEND_GENESYS_SERIALIZE_H 22#define BACKEND_GENESYS_SERIALIZE_H 23 24#include "error.h" 25#include <array> 26#include <iostream> 27#include <limits> 28#include <string> 29#include <vector> 30 31namespace genesys { 32 33// it would be best to use something like boost.serialization 34 35inline void serialize_newline(std::ostream& str) { str << '\n'; } 36inline void serialize_newline(std::istream& str) { (void) str; } 37 38inline void serialize(std::ostream& str, bool x) { str << static_cast<unsigned>(x) << " "; } 39inline void serialize(std::istream& str, bool& x) { unsigned v; str >> v; x = v; } 40inline void serialize(std::ostream& str, char x) { str << static_cast<int>(x) << " "; } 41inline void serialize(std::istream& str, char& x) { int v; str >> v; x = v; } 42inline void serialize(std::ostream& str, unsigned char x) { str << static_cast<unsigned>(x) << " "; } 43inline void serialize(std::istream& str, unsigned char& x) { unsigned v; str >> v; x = v; } 44inline void serialize(std::ostream& str, signed char x) { str << static_cast<int>(x) << " "; } 45inline void serialize(std::istream& str, signed char& x) { int v; str >> v; x = v; } 46inline void serialize(std::ostream& str, short x) { str << x << " "; } 47inline void serialize(std::istream& str, short& x) { str >> x; } 48inline void serialize(std::ostream& str, unsigned short x) { str << x << " "; } 49inline void serialize(std::istream& str, unsigned short& x) { str >> x; } 50inline void serialize(std::ostream& str, int x) { str << x << " "; } 51inline void serialize(std::istream& str, int& x) { str >> x; } 52inline void serialize(std::ostream& str, unsigned int x) { str << x << " "; } 53inline void serialize(std::istream& str, unsigned int& x) { str >> x; } 54inline void serialize(std::ostream& str, long x) { str << x << " "; } 55inline void serialize(std::istream& str, long& x) { str >> x; } 56inline void serialize(std::ostream& str, unsigned long x) { str << x << " "; } 57inline void serialize(std::istream& str, unsigned long& x) { str >> x; } 58inline void serialize(std::ostream& str, long long x) { str << x << " "; } 59inline void serialize(std::istream& str, long long& x) { str >> x; } 60inline void serialize(std::ostream& str, unsigned long long x) { str << x << " "; } 61inline void serialize(std::istream& str, unsigned long long& x) { str >> x; } 62inline void serialize(std::ostream& str, float x) { str << x << " "; } 63inline void serialize(std::istream& str, float& x) { str >> x; } 64inline void serialize(std::ostream& str, double x) { str << x << " "; } 65inline void serialize(std::istream& str, double& x) { str >> x; } 66inline void serialize(std::ostream& str, const std::string& x) { str << x << " "; } 67inline void serialize(std::istream& str, std::string& x) { str >> x; } 68 69template<class T> 70void serialize(std::ostream& str, std::vector<T>& x) 71{ 72 serialize(str, x.size()); 73 serialize_newline(str); 74 75 for (auto& item : x) { 76 serialize(str, item); 77 serialize_newline(str); 78 } 79} 80 81template<class T> 82void serialize(std::istream& str, std::vector<T>& x, 83 size_t max_size = std::numeric_limits<size_t>::max()) 84{ 85 size_t new_size; 86 serialize(str, new_size); 87 88 if (new_size > max_size) { 89 throw SaneException("Too large std::vector to deserialize"); 90 } 91 x.reserve(new_size); 92 for (size_t i = 0; i < new_size; ++i) { 93 T item; 94 serialize(str, item); 95 x.push_back(item); 96 } 97} 98 99template<class T, size_t Size> 100void serialize(std::ostream& str, std::array<T, Size>& x) 101{ 102 serialize(str, x.size()); 103 serialize_newline(str); 104 105 for (auto& item : x) { 106 serialize(str, item); 107 serialize_newline(str); 108 } 109} 110 111template<class T, size_t Size> 112void serialize(std::istream& str, std::array<T, Size>& x) 113{ 114 size_t new_size; 115 serialize(str, new_size); 116 117 if (new_size > Size) { 118 throw SaneException("Incorrect std::array size to deserialize"); 119 } 120 for (auto& item : x) { 121 serialize(str, item); 122 } 123} 124 125} // namespace genesys 126 127#endif 128