aboutsummaryrefslogtreecommitdiff
path: root/apps/SoilMoistureIo.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/SoilMoistureIo.h')
-rw-r--r--apps/SoilMoistureIo.h197
1 files changed, 147 insertions, 50 deletions
diff --git a/apps/SoilMoistureIo.h b/apps/SoilMoistureIo.h
index b8f08e9..b8f0b52 100644
--- a/apps/SoilMoistureIo.h
+++ b/apps/SoilMoistureIo.h
@@ -33,121 +33,216 @@ class SampleStreamParser;
class SampleOutputStream;
-unique_ptr<SampleStreamParser> open_sample_input_stream(shared_ptr<SampleOutputStream> output, sample_format_type type = sample_format_type::AUTO);
+class KeyDictionary;
-unique_ptr<SampleOutputStream> open_sample_output_stream(sample_format_type type, unique_ptr<ostream> output,
- o<vector<string>> fields = o<vector<string>>());
+class SampleKey;
-class Sample {
+unique_ptr<SampleStreamParser> open_sample_input_stream(
+ KeyDictionary &dict,
+ shared_ptr<SampleOutputStream> output,
+ sample_format_type type = sample_format_type::AUTO);
+
+unique_ptr<SampleOutputStream> open_sample_output_stream(
+ KeyDictionary &dict,
+ sample_format_type type,
+ unique_ptr<ostream> output,
+ o<vector<SampleKey>> fields = o<vector<SampleKey>>());
+
+class sample_exception : public runtime_error {
public:
- Sample() : entries() {
+ sample_exception(const string &what) : runtime_error(what) {
}
+};
- Sample(map<string, string> entries) : entries(entries) {
+struct SampleKey {
+ // TODO: only the dictionary should be able to create keys
+ SampleKey(string &name) : name(name) {
+ if (name.length() == 0) {
+ throw sample_exception("Bad sample key.");
+ }
}
- map<string, string>::iterator find(string &s) {
- return entries.find(s);
+ inline
+ bool operator==(const SampleKey &that) const {
+ return name == that.name;
}
- map<string, string>::iterator begin() {
- return entries.begin();
- }
+ string name;
+};
+
+class KeyDictionary {
+public:
+ typedef vector<SampleKey> v;
+ typedef v::size_type index_t;
- map<string, string>::iterator end() {
- return entries.end();
+ KeyDictionary() {
}
- /**
- * @throws std::out_of_range
- */
- inline const string &operator[](string key) {
- return at(key);
+ index_t indexOf(const SampleKey key) {
+ index_t i = 0;
+ for (auto ptr = keys.begin(); ptr != keys.end(); ptr++, i++) {
+ if (*ptr == key) {
+ return i;
+ }
+ }
+
+ keys.push_back(key);
+
+ return keys.size() - 1;
}
- /**
- * @throws std::out_of_range
- */
- const string &at(string key) {
- return entries.at(key);
+ vector<index_t> findIndexes(v keys);
+
+ inline
+ v::const_iterator begin() {
+ return keys.begin();
}
- template<class A>
- const A lexical_at(string key) {
- return boost::lexical_cast<A>(entries.at(key));
+ inline
+ v::const_iterator end() {
+ return keys.end();
}
- void set(const std::string &key, const std::string &value) {
- entries[key] = value;
+ string nameOf(index_t index) {
+ return keys.at(index).name;
}
private:
- map<string, string> entries;
+ v keys;
};
-class sample_exception : public runtime_error {
+class SampleRecord {
public:
- sample_exception(const string &what) : runtime_error(what) {
+ typedef vector<o<string>> vec;
+
+ SampleRecord(KeyDictionary &dict) : dict(dict) {
+ }
+
+ SampleRecord(KeyDictionary &dict, vec values)
+ : dict(dict), values(values) {
+ }
+
+ inline
+ vec::const_iterator begin() {
+ return values.begin();
+ }
+
+ inline
+ vec::const_iterator end() {
+ return values.end();
}
+
+ inline
+ bool empty() {
+ return values.empty();
+ }
+
+ o<string> at(size_t index) {
+ if (index >= values.size()) {
+ return o<string>();
+ }
+
+ return values.at(index);
+ }
+
+ void set(const KeyDictionary::index_t index, const std::string &value) {
+ values.resize(max(values.size(), index + 1));
+
+ values[index] = o<string>(value);
+ }
+
+ template<class A>
+ const o<A> lexical_at(KeyDictionary::index_t index) {
+ auto value = at(index);
+
+ if (!value) {
+ return o<A>();
+ }
+
+ return o<A>(boost::lexical_cast<A>(value.get()));
+ }
+
+ string to_string() {
+ KeyDictionary::index_t i = 0;
+ string s;
+ for (auto ptr = values.begin(); ptr != values.end(); ptr++, i++) {
+ auto o = *ptr;
+
+ if (!o) {
+ continue;
+ }
+
+ auto value = o.get();
+
+ s += dict.nameOf(i) + " = " + value + ", ";
+ }
+ return s;
+ }
+
+private:
+ KeyDictionary &dict;
+ vec values;
};
class SampleOutputStream {
public:
- virtual void write(Sample sample) = 0;
+ virtual void write(SampleRecord sample) = 0;
};
class VectorSampleOutputStream : public SampleOutputStream {
public:
- virtual void write(Sample sample) override;
+ virtual void write(SampleRecord sample) override;
public:
- vector<Sample> samples;
+ vector<SampleRecord> samples;
};
class CsvSampleOutputStream : public SampleOutputStream {
public:
- CsvSampleOutputStream(unique_ptr<ostream> stream);
+ CsvSampleOutputStream(KeyDictionary &dict, unique_ptr<ostream> stream);
- CsvSampleOutputStream(unique_ptr<ostream> stream, vector<string> fields);
+ CsvSampleOutputStream(KeyDictionary &dict, unique_ptr<ostream> stream, vector<SampleKey> fields);
- void write(Sample values);
+ void write(SampleRecord values);
private:
void writeHeader();
+ KeyDictionary &dict;
unique_ptr<ostream> stream;
bool headerWritten;
- bool filterFields;
- vector<string> fields;
+ vector<KeyDictionary::index_t> fields;
};
class JsonSampleOutputStream : public SampleOutputStream {
public:
- JsonSampleOutputStream(unique_ptr<ostream> stream);
+ JsonSampleOutputStream(KeyDictionary &dict, unique_ptr<ostream> stream);
- JsonSampleOutputStream(unique_ptr<ostream> stream, vector<string> fields);
+ JsonSampleOutputStream(KeyDictionary &dict, unique_ptr<ostream> stream, vector<SampleKey> fields);
- void write(Sample values);
+ void write(SampleRecord values);
private:
+ KeyDictionary &dict;
unique_ptr<ostream> stream;
bool filterFields;
- vector<string> fields;
+ vector<KeyDictionary::index_t> fields;
};
class SqlSampleOutputStream : public SampleOutputStream {
public:
- SqlSampleOutputStream(unique_ptr<ostream> stream, string table_name);
+ SqlSampleOutputStream(KeyDictionary &dict, unique_ptr<ostream> stream, string table_name);
- SqlSampleOutputStream(unique_ptr<ostream> stream, string table_name, vector<string> fields);
+ SqlSampleOutputStream(KeyDictionary &dict, unique_ptr<ostream> stream, string table_name, vector<SampleKey> fields);
- void write(Sample values);
+ void write(SampleRecord values);
private:
+ KeyDictionary &dict;
unique_ptr<ostream> stream;
bool filter_fields;
- vector<string> fields;
+ vector<KeyDictionary::index_t> fields;
const string table_name;
};
@@ -169,8 +264,9 @@ protected:
class CsvSampleParser : public SampleStreamParser {
public:
- CsvSampleParser(shared_ptr<SampleOutputStream> output) : SampleStreamParser(sample_format_type::CSV),
- output(output), line(make_shared<vector<uint8_t>>()) {
+ CsvSampleParser(KeyDictionary &dict, shared_ptr<SampleOutputStream> output) :
+ SampleStreamParser(sample_format_type::CSV), dict(dict), output(output),
+ line(make_shared<vector<uint8_t>>()) {
}
void process(mutable_buffers_1 buffer) override;
@@ -179,13 +275,14 @@ private:
void process_line(shared_ptr<vector<uint8_t>> packet);
static const uint8_t packet_delimiter = '\n';
+ KeyDictionary &dict;
shared_ptr<SampleOutputStream> output;
shared_ptr<vector<uint8_t>> line;
};
class AutoSampleParser : public SampleStreamParser {
public:
- AutoSampleParser(shared_ptr<SampleOutputStream> output);
+ AutoSampleParser(KeyDictionary &dict, shared_ptr<SampleOutputStream> output);
private:
unique_ptr<SampleStreamParser> parser;