-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdatamapwriter.h
160 lines (135 loc) · 4.03 KB
/
datamapwriter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. See the enclosed file LICENSE for a copy or if
* that was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright 2017 Max H. Gerlach
*
* */
/*
* datamapwriter.h
*
* Created on: Jan 28, 2011
* Author: gerlach
*/
#ifndef DATAMAPWRITER_H_
#define DATAMAPWRITER_H_
#include <memory>
#include <string>
#include <sstream>
#include <fstream>
#include <map>
#include "metadata.h"
/*
* write a map containing key-value data to an ascii file
* supports a header of the form:
*
* ## blah blah
* ## blah
* # foo1 = bar
* # foo2 = 124
* # foo4 = 28.983
* ## palaver palaver
* key0 data0
* key1 data1
* ...
* etc.
*
* if errors are set the data is written out as follows instead:
* key0 data0 error0
* key1 data1 error1
* ...
*
*
*
* 20121214 -- move to smart pointers (shared_ptr) to improve resource management
*
* 20140123 -- added IO error handling
*
*/
template <typename Key, typename Value>
class DataMapWriter {
public:
DataMapWriter();
typedef std::shared_ptr<const std::map<Key,Value>> MapPtr;
void setData(MapPtr dataMap);
void setErrors(MapPtr errorMap);
template <typename ValueType>
void addMeta(const std::string& key, ValueType val);
void addMetadataMap(const MetadataMap& meta);
void addHeaderText(const std::string& headerText);
void writeToFile(const std::string& filename);
//direct string manipulation (no special handling of line comments or other)
std::string getHeader();
void addHeaderDirectly(const std::string& headerNew);
private:
MapPtr data;
MapPtr errors;
std::string header;
};
template<typename Key, typename Value>
DataMapWriter<Key, Value>::DataMapWriter() :
data(), errors(), header("") {
}
template <typename Key, typename Value>
void DataMapWriter<Key,Value>::setData(MapPtr dataMap) {
data = dataMap;
}
template <typename Key, typename Value>
void DataMapWriter<Key,Value>::setErrors(MapPtr errorMap) {
errors = errorMap;
}
template <typename Key, typename Value>
template <typename ValueType>
void DataMapWriter<Key,Value>::addMeta(const std::string& key, ValueType val) {
std::stringstream ss;
ss << "# " << key << " = " << val << '\n';
header += ss.str();
}
template <typename Key, typename Value>
void DataMapWriter<Key,Value>::addMetadataMap(const MetadataMap& meta) {
header += metadataToString(meta, "# ");
}
template <typename Key, typename Value>
void DataMapWriter<Key,Value>::addHeaderText(const std::string& headerText) {
std::stringstream ss(headerText);
std::string line;
while (std::getline(ss, line)) {
header += "## " + line + '\n';
}
}
template <typename Key, typename Value>
void DataMapWriter<Key,Value>::writeToFile(const std::string& filename) {
std::ofstream output(filename.c_str());
if (output) {
output << header;
output.precision(15);
output.setf(std::ios::scientific, std::ios::floatfield);
if (not errors) {
for (auto iter = data->cbegin(); iter != data->cend(); ++iter) {
output << iter->first << '\t' << iter->second << '\n';
}
} else {
for (auto iter = data->cbegin(); iter != data->cend(); ++iter) {
Key key = iter->first;
output << key << '\t' << iter->second << '\t' << errors->at(key) << '\n';
}
}
} else {
std::cerr << "Could not open file " << filename << " for writing.\n";
std::cerr << "Error code: " << strerror(errno) << "\n";
}
}
template<typename Key, typename Value>
inline std::string DataMapWriter<Key, Value>::getHeader() {
return header;
}
template<typename Key, typename Value>
inline void DataMapWriter<Key, Value>::addHeaderDirectly(
const std::string& headerNew) {
header += headerNew;
}
typedef DataMapWriter<double, double> DoubleMapWriter;
typedef DataMapWriter<int, double> IntDoubleMapWriter;
typedef DataMapWriter<std::string, double> StringDoubleMapWriter;
#endif /* DATAMAPWRITER_H_ */