Initial commit
[Praktika/Routenplanung/cpp-base.git] / vector_io.h
1 #ifndef VECTOR_IO_H
2 #define VECTPR_IO_H
3
4 #include <string>
5 #include <vector>
6 #include <stdexcept>
7 #include <fstream>
8
9 template<class T>
10 void save_vector(const std::string&file_name, const std::vector<T>&vec){
11         std::ofstream out(file_name, std::ios::binary);
12         if(!out)
13                 throw std::runtime_error("Can not open \""+file_name+"\" for writing.");
14         out.write(reinterpret_cast<const char*>(&vec[0]), vec.size()*sizeof(T));
15 }
16
17 template<class T>
18 std::vector<T>load_vector(const std::string&file_name){
19         std::ifstream in(file_name, std::ios::binary);
20         if(!in)
21                 throw std::runtime_error("Can not open \""+file_name+"\" for reading.");
22         in.seekg(0, std::ios::end);
23         unsigned long long file_size = in.tellg();
24         if(file_size % sizeof(T) != 0)
25                 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.");
26         in.seekg(0, std::ios::beg);
27         std::vector<T>vec(file_size / sizeof(T));
28         in.read(reinterpret_cast<char*>(&vec[0]), file_size);
29         return vec; // NVRO
30 }
31
32 template<>
33 void save_vector<std::string>(const std::string&file_name, const std::vector<std::string>&vec){
34         std::ofstream out(file_name, std::ios::binary);
35         for(unsigned i=0; i<vec.size(); ++i){
36                 const char*x = vec[i].c_str();
37                 out.write(x, vec[i].length()+1);
38         }
39 }
40
41 template<>
42 std::vector<std::string>load_vector<std::string>(const std::string&file_name){
43         std::vector<char>data = load_vector<char>(file_name);
44         std::vector<std::string>ret;
45         std::vector<char>::const_iterator 
46                 str_begin = data.begin(), 
47                 str_end = data.begin(), 
48                 data_end = data.end();
49
50         while(str_end != data_end){
51                 if(*str_end == '\0'){
52                         ret.push_back(std::string(str_begin, str_end));
53                         ++str_end;
54                         str_begin = str_end;
55                 }else{
56                         ++str_end;
57                 }
58         }
59
60         ret.shrink_to_fit();
61         return ret; // NVRO
62 }
63
64 template<class T>
65 void save_value(const std::string&file_name, const T&val){
66         save_vector(file_name, std::vector<T>{val});
67 }
68
69 template<class T>
70 T load_value(const std::string&file_name){
71         auto v = load_vector<T>(file_name);
72         if(v.empty())
73                 throw std::runtime_error(file_name+" is empty");
74         if(v.size() >= 2)
75                 throw std::runtime_error(file_name+" contains more than one element");
76         return v.front();
77 }
78
79 #endif