Line data Source code
1 : #ifndef ROUTING_KIT_VECTOR_IO_H
2 : #define ROUTING_KIT_VECTOR_IO_H
3 :
4 : #include <routingkit/bit_vector.h>
5 :
6 : #include <string>
7 : #include <vector>
8 : #include <stdexcept>
9 : #include <fstream>
10 : #include <type_traits>
11 : #include <functional>
12 :
13 : namespace RoutingKit{
14 :
15 : template<class T>
16 : void save_vector(const std::string&file_name, const std::vector<T>&vec){
17 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
18 : std::ofstream out(file_name, std::ios::binary);
19 : if(!out)
20 : throw std::runtime_error("Can not open \""+file_name+"\" for writing.");
21 : out.write(reinterpret_cast<const char*>(&vec[0]), vec.size()*sizeof(T));
22 : }
23 :
24 : template<class T>
25 : std::vector<T>load_vector(const std::string&file_name){
26 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
27 : std::ifstream in(file_name, std::ios::binary);
28 : if(!in)
29 : throw std::runtime_error("Can not open \""+file_name+"\" for reading.");
30 : in.seekg(0, std::ios::end);
31 : unsigned long long file_size = in.tellg();
32 : if(file_size % sizeof(T) != 0)
33 : throw std::runtime_error("File \""+file_name+"\" can not be a vector of the requested type because it's size is no multiple of the element type's size.");
34 : in.seekg(0, std::ios::beg);
35 : std::vector<T>vec(file_size / sizeof(T));
36 : in.read(reinterpret_cast<char*>(&vec[0]), file_size);
37 : return vec; // NVRO
38 : }
39 :
40 :
41 : template<> void save_vector<std::string>(const std::string&file_name, const std::vector<std::string>&vec);
42 : extern template void save_vector<std::string>(const std::string&file_name, const std::vector<std::string>&vec);
43 :
44 : template<> std::vector<std::string>load_vector<std::string>(const std::string&file_name);
45 : extern template std::vector<std::string> load_vector<std::string>(const std::string&file_name);
46 :
47 : void save_bit_vector(const std::string&file_name, const BitVector&vec);
48 : BitVector load_bit_vector(const std::string&file_name);
49 :
50 :
51 :
52 :
53 : template<class T>
54 : void save_value(const std::string&file_name, const T&val){
55 : save_vector(file_name, std::vector<T>{val});
56 : }
57 :
58 :
59 : template<class T>
60 : T load_value(const std::string&file_name){
61 : auto v = load_vector<T>(file_name);
62 : if(v.empty())
63 : throw std::runtime_error(file_name+" is empty");
64 : if(v.size() > 1)
65 : throw std::runtime_error(file_name+" contains more than one element");
66 : return v.front();
67 : }
68 :
69 :
70 : template<class T>
71 : void write_value(std::ostream&out, const T&val){
72 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
73 : out.write((const char*)&val, sizeof(T));
74 : if(!out)
75 : throw std::runtime_error("Could not write value to file");
76 : }
77 :
78 : template<class T>
79 : T read_value(std::istream&in){
80 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
81 : T val;
82 : in.read((char*)&val, sizeof(T));
83 : if(!in)
84 : throw std::runtime_error("Could not read value to file");
85 : return val; // NVRO
86 : }
87 :
88 : template<class T>
89 : void write_vector(std::ostream&out, const std::vector<T>&v){
90 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
91 : out.write((const char*)&v[0], sizeof(T)*v.size());
92 : if(!out)
93 : throw std::runtime_error("Could not write vector data");
94 :
95 : }
96 :
97 : template<class T>
98 : std::vector<T> read_vector(std::istream&in, unsigned long long size){
99 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
100 : std::vector<T>v(size);
101 : in.read((char*)&v[0], sizeof(T)*size);
102 : if(!in)
103 : throw std::runtime_error("Could not read vector data");
104 : return v; // NVRO
105 : }
106 :
107 :
108 :
109 :
110 : template<class T>
111 0 : void write_value(const std::function<void(const char*, unsigned long long)>&out, const T&val){
112 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
113 0 : out((const char*)&val, sizeof(T));
114 0 : }
115 :
116 : template<class T>
117 0 : T read_value(const std::function<void(char*, unsigned long long)>&in){
118 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
119 : T val;
120 0 : in((char*)&val, sizeof(T));
121 0 : return val; // NVRO
122 : }
123 :
124 : template<class T>
125 0 : void write_vector(const std::function<void(const char*, unsigned long long)>&out, const std::vector<T>&v){
126 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
127 0 : out((const char*)&v[0], sizeof(T)*v.size());
128 0 : }
129 :
130 : template<class T>
131 0 : std::vector<T> read_vector(const std::function<void(char*, unsigned long long)>&in, unsigned long long size){
132 : static_assert(std::is_pod<T>::value, "Cannot find non-trivial serialization code for this type, maybe a header is missing or serialization is simply not available");
133 0 : std::vector<T>v(size);
134 0 : in((char*)&v[0], sizeof(T)*size);
135 0 : return v; // NVRO
136 0 : }
137 :
138 :
139 :
140 :
141 : inline
142 0 : BitVector read_bit_vector(const std::function<void(char*, unsigned long long)>&in, unsigned long long size){
143 0 : BitVector v(size);
144 0 : in((char*)v.data(), ((size+511)/512)*64);
145 0 : return v;
146 0 : }
147 :
148 : inline
149 0 : void write_bit_vector(const std::function<void(const char*, unsigned long long)>&out, const BitVector&v){
150 0 : out((const char*)v.data(), ((v.size()+511)/512)*64);
151 0 : }
152 :
153 :
154 :
155 : template<class F>
156 0 : void open_file_for_saving(const std::string&file_name, const F&f){
157 0 : std::ofstream out(file_name, std::ios::binary);
158 0 : if(!out)
159 0 : throw std::runtime_error("Can not open \""+file_name+"\" for writing.");
160 : f(out);
161 0 : }
162 :
163 : template<class F>
164 0 : void open_file_for_loading(const std::string&file_name, const F&f){
165 0 : std::ifstream in(file_name, std::ios::binary);
166 0 : if(!in)
167 0 : throw std::runtime_error("Can not open \""+file_name+"\" for reading.");
168 :
169 0 : in.seekg(0, std::ios_base::end);
170 0 : unsigned long long file_size = in.tellg();
171 0 : in.seekg(0, std::ios_base::beg);
172 0 : f(in, file_size);
173 0 : }
174 :
175 : } // RoutingKit
176 :
177 : #endif
|