aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README-apps.md1
-rw-r--r--apps/CMakeLists.txt2
-rw-r--r--apps/sample-add-timestamp.cpp101
-rw-r--r--apps/sample-timestamp.cpp212
-rw-r--r--sensor/include/trygvis/sensor.h9
-rw-r--r--sensor/main/sensor.cpp24
6 files changed, 136 insertions, 213 deletions
diff --git a/README-apps.md b/README-apps.md
index 228691a..2157631 100644
--- a/README-apps.md
+++ b/README-apps.md
@@ -34,3 +34,4 @@ Graphing values
rrdtool graph graph.png --width 1024 --height 512 \
--start 1425593989 --end 1425991529 \
DEF:a=test.rrd:analog:AVERAGE LINE2:a#FF0000
+
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index 15a1f0b..988a989 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -1,7 +1,7 @@
list(APPEND APPS log4cplus-test)
list(APPEND APPS ble-inspect-device)
+list(APPEND APPS sample-add-timestamp)
list(APPEND APPS sample-convert)
-list(APPEND APPS sample-timestamp)
list(APPEND APPS sample-select)
list(APPEND APPS sm-db-insert)
list(APPEND APPS sm-db-select)
diff --git a/apps/sample-add-timestamp.cpp b/apps/sample-add-timestamp.cpp
new file mode 100644
index 0000000..dbf24a1
--- /dev/null
+++ b/apps/sample-add-timestamp.cpp
@@ -0,0 +1,101 @@
+#include "trygvis/sensor.h"
+#include "trygvis/sensor/io.h"
+#include "apps.h"
+#include <vector>
+
+namespace trygvis {
+namespace apps {
+
+using namespace std;
+using namespace trygvis::apps;
+using namespace trygvis::sensor;
+using namespace trygvis::sensor::io;
+namespace po = boost::program_options;
+
+class TimestampAddingSampleOutputStream : public SampleOutputStream {
+
+public:
+ TimestampAddingSampleOutputStream(shared_ptr<SampleOutputStream> output, KeyDictionary &dict, string timestamp_name)
+ :
+ timestamp_key(dict.indexOf(timestamp_name)) {
+ if (input_time_resolution_ == time_resolution::MILLISECONDS) {
+ factor = 1000;
+ } else {
+ factor = 1;
+ }
+ }
+
+ virtual void write(SampleRecord const &sample) override {
+ time_t now = time(NULL) * factor;
+
+ SampleRecord updated_sample(sample);
+
+ updated_sample.set(timestamp_key, std::to_string(now));
+
+ output_->write(updated_sample);
+ };
+
+private:
+ const SampleKey *timestamp_key;
+ time_resolution input_time_resolution_;
+ int factor;
+ shared_ptr<SampleOutputStream> output_;
+};
+
+class sample_add_timestamp : public app {
+
+private:
+ string timestamp_name;
+ time_resolution resolution;
+ sample_format_type output_format;
+
+public:
+ void add_options(po::options_description_easy_init &options) override {
+ options
+ ("help", "produce this help message")
+ ("resolution", po::value<time_resolution>(&resolution)->default_value(time_resolution::SECONDS))
+ ("timestamp-name", po::value<string>(&timestamp_name)->default_value("timestamp"))
+ ("output-format", po::value<sample_format_type>(&output_format)->default_value(sample_format_type::KEY_VALUE));
+ }
+
+ const int buffer_size = 1024;
+
+ int main(app_execution &execution) override {
+ shared_ptr<istream> input;
+
+ input = shared_ptr<istream>(&cin, noop_deleter);
+
+ KeyDictionary dict;
+
+ sample_output_stream_options options = {};
+ unique_ptr<SampleOutputStream> unique_output_stream = open_sample_output_stream(shared_ptr<ostream>(&cout, noop_deleter), dict, output_format, options);
+ shared_ptr<SampleOutputStream> output_stream{std::move(unique_output_stream)};
+ shared_ptr<SampleOutputStream> p = make_shared<TimestampAddingSampleOutputStream>(output_stream, dict, timestamp_name);
+ auto parser = open_sample_stream_parser(p, dict);
+
+ int recordCount = 0;
+
+ while (!input->eof()) {
+ char buffer[buffer_size];
+ input->read(buffer, buffer_size);
+ size_t gcount = (size_t)input->gcount();
+
+ recordCount++;
+
+ mutable_buffers_1 b = boost::asio::buffer(buffer, gcount);
+ parser->process(b);
+ }
+
+ return EXIT_SUCCESS;
+ };
+};
+
+}
+}
+
+using namespace trygvis::apps;
+
+int main(int argc, char *argv[]) {
+ sample_add_timestamp app;
+ return launch_app(argc, argv, app);
+}
diff --git a/apps/sample-timestamp.cpp b/apps/sample-timestamp.cpp
deleted file mode 100644
index cf0b7fe..0000000
--- a/apps/sample-timestamp.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-#include "trygvis/sensor.h"
-#include "trygvis/sensor/io.h"
-#include "apps.h"
-#include <fstream>
-#include <sys/stat.h>
-
-namespace trygvis {
-namespace apps {
-
-using namespace std;
-using namespace trygvis::apps;
-using namespace trygvis::sensor;
-using namespace trygvis::sensor::io;
-namespace po = boost::program_options;
-
-enum class time_resolution {
- SECONDS,
- MILLISECONDS,
-};
-
-std::ostream& operator<<(std::ostream& os, time_resolution const& type) {
- if (type == time_resolution::SECONDS) {
- os << "seconds";
- } else if(type == time_resolution::MILLISECONDS) {
- os << "milliseconds";
- }
-
- return os;
-}
-
-std::istream& operator>>(std::istream& is, time_resolution & type) {
- string s;
-
- is >> s;
-
- if(s == "seconds") {
- type = time_resolution::SECONDS;
- } else if(s == "milliseconds") {
- type = time_resolution::MILLISECONDS;
- }
-
- return is;
-}
-
-class TimestampFixingSampleOutputStream : public SampleOutputStream {
-
-public:
- TimestampFixingSampleOutputStream(shared_ptr<SampleOutputStream> output, KeyDictionary &dict, string timestamp_name, string relative_name, time_resolution input_time_resolution, time_t start_time) :
- timestamp_key(dict.indexOf(timestamp_name)), relative_key(dict.indexOf(relative_name)), input_time_resolution_(input_time_resolution), start_time_(start_time), output_(output) {
- }
-
- virtual void write(SampleRecord const &sample) override {
- o<long> relative_time_o = sample.lexical_at<long>(relative_key);
-
- if (!relative_time_o) {
- return;
- }
-
- long relative_time = relative_time_o.get();
-
- long updated_time;
- if (input_time_resolution_ == time_resolution::SECONDS) {
- updated_time = start_time_ + relative_time;
- } else if (input_time_resolution_ == time_resolution::MILLISECONDS) {
- updated_time = start_time_ + relative_time / 1000;
- }
-
- string updated_value = std::to_string(updated_time);
-
- SampleRecord updated_sample(sample);
-
- updated_sample.set(timestamp_key, updated_value);
-
- output_->write(updated_sample);
- };
-
-private:
- const SampleKey* relative_key, *timestamp_key;
- time_t start_time_;
- time_resolution input_time_resolution_;
- shared_ptr<SampleOutputStream> output_;
-};
-
-class sample_timestamp : public app {
-
-private:
- string input_file, timestamp_name, relative_name;
- time_resolution relative_resolution;
- SampleKey* relative_key;
-
-public:
- sample_timestamp() : input_file("") {
- }
-
- void add_options(po::options_description_easy_init &options) override {
- options
- ("help", "produce this help message")
- ("input", po::value<string>(&input_file)->required())
- ("relative-name", po::value<string>(&relative_name)->default_value("relative"))
- ("relative-resolution", po::value<time_resolution>(&relative_resolution)->default_value(time_resolution::SECONDS))
- ("timestamp-name", po::value<string>(&timestamp_name)->default_value("timestamp"));
- }
-
- int main(app_execution &execution) override {
- ifstream input(input_file, std::ifstream::in | std::ifstream::binary);
-
- if (input.fail()) {
- cerr << "Could not open file: " << input_file << endl;
- return EXIT_FAILURE;
- }
-
- const int buffer_size = 1024;
-
- input.seekg(-buffer_size, ios_base::end);
-
- struct stat buf;
-
- if (stat(input_file.c_str(), &buf)) {
- cerr << "stat failed" << endl;
- return EXIT_FAILURE;
- }
-
- KeyDictionary dict;
-
- relative_key = dict.indexOf(relative_name);
-
- auto sample_buffer = make_shared<VectorSampleOutputStream>();
- auto parser = open_sample_stream_parser(sample_buffer, dict);
- while (!input.fail()) {
- char buffer[buffer_size];
- input.read(buffer, buffer_size);
- auto count = (size_t) input.gcount();
-
- cerr << "eof? " << input.eof() << endl;
- mutable_buffers_1 b = boost::asio::buffer(buffer, count);
- parser->process(b);
- }
-
- if (sample_buffer->samples.empty()) {
- cerr << "Could not find any samples" << endl;
- return EXIT_FAILURE;
- }
-
- time_t end_time = buf.st_mtim.tv_sec;
-
- SampleRecord sample = *--sample_buffer->samples.end();
-
- o<string> s = sample.at(relative_key);
- if (!s) {
- cerr << "Missing key '" + relative_name + "'." << endl;
- cerr << "Found " << sample_buffer->samples.size() << " samples." << endl;
- cerr << "keys: " << sample.to_string() << endl;
- return EXIT_FAILURE;
- }
-
- long relative;
- try {
- relative = boost::lexical_cast<long>(s.get());
- } catch (const boost::bad_lexical_cast &e) {
- cerr << "Bad integer value '" + s.get() + "'." << endl;
- return EXIT_FAILURE;
- }
-
- if (relative_resolution == time_resolution::MILLISECONDS) {
- relative /= 1000;
- }
-
- time_t start_time = end_time - relative;
- cerr << "end_time " << end_time << endl;
- cerr << "relative " << relative << endl;
- cerr << "start_time " << start_time << endl;
-
- // Restart the reading of the input file and add the adjusted timestamp
- input.clear(ios::eofbit);
- input.seekg(0);
- if(input.fail()) {
- cerr << "Coult not seek input file" << endl;
- return EXIT_FAILURE;
- }
-
- sample_output_stream_options options;
- unique_ptr<SampleOutputStream> unique_output_stream = open_sample_output_stream(shared_ptr<ostream>(&cout, noop_deleter), dict, parser->type(), options);
- shared_ptr<SampleOutputStream> output_stream{std::move(unique_output_stream)};
- shared_ptr<SampleOutputStream> p = make_shared<TimestampFixingSampleOutputStream>(output_stream, dict, timestamp_name, relative_name, relative_resolution, start_time);
- parser = open_sample_stream_parser(p, dict, parser->type());
-
- int recordCount = 0;
-
- while (!input.eof()) {
- char buffer[buffer_size];
- input.read(buffer, buffer_size);
- size_t gcount = (size_t)input.gcount();
-
- recordCount++;
-
- mutable_buffers_1 b = boost::asio::buffer(buffer, gcount);
- parser->process(b);
- }
-
- return EXIT_SUCCESS;
- };
-};
-
-}
-}
-
-using namespace trygvis::apps;
-
-int main(int argc, char *argv[]) {
- sample_timestamp app;
- return launch_app(argc, argv, app);
-}
diff --git a/sensor/include/trygvis/sensor.h b/sensor/include/trygvis/sensor.h
index f8cfbe5..bcbd43b 100644
--- a/sensor/include/trygvis/sensor.h
+++ b/sensor/include/trygvis/sensor.h
@@ -29,6 +29,15 @@ std::ostream& operator<<(std::ostream& os, sample_format_type const& type);
std::istream& operator>>(std::istream& is, sample_format_type& type);
+enum class time_resolution {
+ SECONDS,
+ MILLISECONDS,
+};
+
+std::ostream& operator<<(std::ostream& os, time_resolution const& type);
+
+std::istream& operator>>(std::istream& is, time_resolution & type);
+
class sample_exception : public runtime_error {
public:
sample_exception(const string &what) : runtime_error(what) {
diff --git a/sensor/main/sensor.cpp b/sensor/main/sensor.cpp
index a773e0b..be3d31e 100644
--- a/sensor/main/sensor.cpp
+++ b/sensor/main/sensor.cpp
@@ -53,6 +53,30 @@ std::istream& operator>>(std::istream& is, sample_format_type& type) {
return is;
}
+std::ostream& operator<<(std::ostream& os, time_resolution const& type) {
+ if (type == time_resolution::SECONDS) {
+ os << "seconds";
+ } else if(type == time_resolution::MILLISECONDS) {
+ os << "milliseconds";
+ }
+
+ return os;
+}
+
+std::istream& operator>>(std::istream& is, time_resolution & type) {
+ string s;
+
+ is >> s;
+
+ if(s == "seconds") {
+ type = time_resolution::SECONDS;
+ } else if(s == "milliseconds") {
+ type = time_resolution::MILLISECONDS;
+ }
+
+ return is;
+}
+
template<>
const o<long> SampleRecord::lexical_at(const SampleKey *key) const {
auto value = at(key);