diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2017-09-01 15:27:56 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2017-09-01 15:27:56 +0200 |
commit | 07b6ff826546e931c0ebf03e30a872ba24e963fc (patch) | |
tree | 5ef8de3ceba68683c3bdeaaf316a70245d114bbd /apps | |
parent | f4f2d5e29ee02d7785ef0150398df7c164feee44 (diff) | |
download | ble-toys-07b6ff826546e931c0ebf03e30a872ba24e963fc.tar.gz ble-toys-07b6ff826546e931c0ebf03e30a872ba24e963fc.tar.bz2 ble-toys-07b6ff826546e931c0ebf03e30a872ba24e963fc.tar.xz ble-toys-07b6ff826546e931c0ebf03e30a872ba24e963fc.zip |
sample-tee.cpp: tool for writing and rotating log files, similar to unix's tee command.
sample-add-timestamp.cpp: Actually using the resolution flag.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/CMakeLists.txt | 1 | ||||
-rw-r--r-- | apps/sample-add-timestamp.cpp | 29 | ||||
-rw-r--r-- | apps/sample-tee.cpp | 111 |
3 files changed, 128 insertions, 13 deletions
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 98c9915..8f8feb3 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -103,6 +103,7 @@ add_app(NAME ble-scan) add_app(NAME sample-add-timestamp) add_app(NAME sample-convert) add_app(NAME sample-select) +add_app(NAME sample-tee) add_app(NAME sm-db-insert) add_app(NAME sm-db-select) add_app(NAME sm-get-value) diff --git a/apps/sample-add-timestamp.cpp b/apps/sample-add-timestamp.cpp index ec3c43a..5493524 100644 --- a/apps/sample-add-timestamp.cpp +++ b/apps/sample-add-timestamp.cpp @@ -13,9 +13,10 @@ namespace po = boost::program_options; class TimestampAddingSampleOutputStream : public SampleConsumer { public: - TimestampAddingSampleOutputStream(shared_ptr<SampleConsumer> output, KeyDictionary &dict, string timestamp_name) - : output_(output), timestamp_key(dict.indexOf(timestamp_name)) { - if (input_time_resolution_ == time_resolution::MILLISECONDS) { + TimestampAddingSampleOutputStream(shared_ptr<SampleConsumer> output, KeyDictionary &dict, + time_resolution resolution, string timestamp_name) : + output_(output), resolution_(resolution), timestamp_key(dict.indexOf(timestamp_name)) { + if (resolution_ == time_resolution::MILLISECONDS) { factor = 1000; } else { factor = 1; @@ -34,7 +35,7 @@ public: private: const SampleKey *timestamp_key; - const time_resolution input_time_resolution_ = time_resolution::MILLISECONDS; + const time_resolution resolution_; int factor; shared_ptr<SampleConsumer> output_; }; @@ -60,22 +61,24 @@ public: const int buffer_size = 1024; int main(app_execution &execution) override { - auto stdin = shared_ptr<istream>(&cin, noop_deleter); - auto stdout = shared_ptr<ostream>(&cout, noop_deleter); - KeyDictionary dict; + auto out = shared_ptr<ostream>(&cout, noop_deleter); + KeyDictionary dict; sample_output_stream_options options = {}; - auto writer = open_sample_writer(stdout, dict, output_format, options); - auto p = make_shared<TimestampAddingSampleOutputStream>(std::move(writer), dict, timestamp_name); + auto writer = open_sample_writer(out, dict, output_format, options); + auto p = make_shared<TimestampAddingSampleOutputStream>(std::move(writer), dict, resolution, timestamp_name); auto parser = open_sample_stream_parser(p, dict); int recordCount = 0; - while (!stdin->eof()) { + auto in = shared_ptr<istream>(&cin, noop_deleter); +// in->rdbuf(nullptr); + + while (!in->eof()) { char buffer[buffer_size]; - stdin->read(buffer, buffer_size); - auto gcount = static_cast<size_t>(stdin->gcount()); + in->read(buffer, buffer_size); + auto gcount = static_cast<size_t>(in->gcount()); recordCount++; @@ -83,7 +86,7 @@ public: parser->process(b); } - stdout->flush(); + out->flush(); return EXIT_SUCCESS; }; diff --git a/apps/sample-tee.cpp b/apps/sample-tee.cpp new file mode 100644 index 0000000..50c0c9b --- /dev/null +++ b/apps/sample-tee.cpp @@ -0,0 +1,111 @@ +#include "apps.h" +#include "trygvis/sensor/io.h" +#include <boost/tokenizer.hpp> +#include <fstream> + +namespace trygvis { +namespace apps { + +using namespace std; +using namespace trygvis::sensor; +using namespace trygvis::sensor::io; +using boost::tokenizer; +namespace po = boost::program_options; + +class sample_tee final : public app, public SampleConsumer { +private: + using clock = std::chrono::steady_clock; + using timestamp = std::chrono::time_point<clock>; + + sample_format_type output_format = sample_format_type::KEY_VALUE; + sample_format_type file_output_format = sample_format_type::KEY_VALUE; + string file_name; + sample_output_stream_options options = {}; + KeyDictionary dict; + + shared_ptr<ostream> out; + unique_ptr<SampleConsumer> out_writer; + ofstream file; + timestamp next_flush; + +public: + sample_tee() : app("sample-to-file") {} + + ~sample_tee() override = default; + + void add_options(po::options_description_easy_init &options) override + { + options("output-format", po::value<sample_format_type>(&output_format)->default_value(output_format)); + options("file-output-format", + po::value<sample_format_type>(&file_output_format)->default_value(file_output_format)); + options("file", po::value<string>(&file_name)); + } + + int main(app_execution &execution) override + { + if (file_name.size() == 0) { + cerr << "Missing required argument --file" << endl; + return EXIT_FAILURE; + } + + cerr << "Writing samples to " << file_name << endl; + + const int buffer_size = 1024; + char buffer[buffer_size]; + + out = shared_ptr<ostream>(&cout, noop_deleter); + out_writer = std::move(open_sample_writer(out, dict, output_format, options)); + + next_flush = clock::now(); + + auto parser = open_sample_stream_parser(shared_ptr<SampleConsumer>(this, noop_deleter), dict); + auto in = shared_ptr<istream>(&cin, noop_deleter); + in->rdbuf(nullptr); + while (!in->eof()) { + in->read(buffer, buffer_size); + auto gcount = static_cast<size_t>(in->gcount()); + + out->write(buffer, gcount); + + mutable_buffers_1 b = boost::asio::buffer(buffer, gcount); + parser->process(b); + } + + file.flush(); + file.close(); + + return EXIT_SUCCESS; + }; + +protected: + + void onSample(const SampleRecord &sample) override + { + out_writer->onSample(sample); + + file.open(file_name, ios_base::out | ios_base::app); + if (file.good()) { + shared_ptr<ostream> output(&file, noop_deleter); + auto file_writer = std::move(open_sample_writer(output, dict, file_output_format, options)); + file_writer->onSample(sample); + } + + auto now = clock::now(); + + if(now >= next_flush) { + file.flush(); + next_flush = now + chrono::seconds(3); + + cerr << "flush" << endl; + } + } +}; +} +} + +int main(int argc, const char *argv[]) +{ + using namespace trygvis::apps; + + return real_main(new sample_tee(), argc, argv); +} |