#ifndef SOIL_MOISTURE_IO_H #define SOIL_MOISTURE_IO_H #include #include #include #include #include #include #include #include #include namespace trygvis { namespace soil_moisture { using namespace std; using namespace boost::asio; template using o = boost::optional; enum class sample_format_type { AUTO, CSV, JSON, SQL }; string to_string(const sample_format_type &arg); class SampleStreamParser; class SampleOutputStream; unique_ptr open_sample_input_stream(shared_ptr output, sample_format_type type = sample_format_type::AUTO); unique_ptr open_sample_output_stream(sample_format_type type, unique_ptr output, o> fields = o>()); class Sample { public: Sample() : entries() { } Sample(map entries) : entries(entries) { } map::iterator find(string &s) { return entries.find(s); } map::iterator begin() { return entries.begin(); } map::iterator end() { return entries.end(); } /** * @throws std::out_of_range */ inline const string &operator[](string key) { return at(key); } /** * @throws std::out_of_range */ const string &at(string key) { return entries.at(key); } template const A lexical_at(string key) { return boost::lexical_cast(entries.at(key)); } void set(const std::string &key, const std::string &value) { entries[key] = value; } private: map entries; }; class sample_exception : public runtime_error { public: sample_exception(const string &what) : runtime_error(what) { } }; class SampleOutputStream { public: virtual void write(Sample sample) = 0; }; class VectorSampleOutputStream : public SampleOutputStream { public: virtual void write(Sample sample) override; public: vector samples; }; class CsvSampleOutputStream : public SampleOutputStream { public: CsvSampleOutputStream(unique_ptr stream); CsvSampleOutputStream(unique_ptr stream, vector fields); void write(Sample values); private: void writeHeader(); unique_ptr stream; bool headerWritten; bool filterFields; vector fields; }; class JsonSampleOutputStream : public SampleOutputStream { public: JsonSampleOutputStream(unique_ptr stream); JsonSampleOutputStream(unique_ptr stream, vector fields); void write(Sample values); private: unique_ptr stream; bool filterFields; vector fields; }; class SqlSampleOutputStream : public SampleOutputStream { public: SqlSampleOutputStream(unique_ptr stream, string table_name); SqlSampleOutputStream(unique_ptr stream, string table_name, vector fields); void write(Sample values); private: unique_ptr stream; bool filter_fields; vector fields; const string table_name; }; class SampleStreamParser { public: virtual void process(mutable_buffers_1 buffer) = 0; virtual sample_format_type type() { return type_; } protected: sample_format_type type_; SampleStreamParser(const sample_format_type type) : type_(type) { } }; class CsvSampleParser : public SampleStreamParser { public: CsvSampleParser(shared_ptr output) : SampleStreamParser(sample_format_type::CSV), output(output), line(make_shared>()) { } void process(mutable_buffers_1 buffer) override; private: void process_line(shared_ptr> packet); static const uint8_t packet_delimiter = '\n'; shared_ptr output; shared_ptr> line; }; class AutoSampleParser : public SampleStreamParser { public: AutoSampleParser(shared_ptr output); private: unique_ptr parser; unique_ptr csvParser; public: virtual void process(mutable_buffers_1 buffer); }; } } #endif