-
-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #81 from klonyyy/csv_streamer
CSV streamer
- Loading branch information
Showing
36 changed files
with
455 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,3 +36,6 @@ test/MCUViewer_test/.settings/ | |
# Executables | ||
*.out | ||
*.app | ||
|
||
# Log files | ||
*.csv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/usr/local/lib |
File renamed without changes.
File renamed without changes
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/env bash | ||
echo "Running postinstall script..." | ||
sudo ldconfig |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "CSVStreamer.hpp" | ||
|
||
#include <fstream> | ||
#include <future> | ||
#include <iostream> | ||
#include <string> | ||
|
||
bool CSVStreamer::Buffer::appendLine(std::string& line) | ||
{ | ||
if (isFull()) | ||
return false; | ||
|
||
buffer[index] = line; | ||
index++; | ||
return true; | ||
} | ||
|
||
bool CSVStreamer::Buffer::isFull() const | ||
{ | ||
return (index + 1) >= buffer.size(); | ||
} | ||
|
||
CSVStreamer::CSVStreamer(spdlog::logger* logger) : logger(logger) | ||
{ | ||
currentBuffer = &buffer1; | ||
buffer1.nextBuffer = &buffer2; | ||
buffer2.nextBuffer = &buffer1; | ||
} | ||
|
||
CSVStreamer::~CSVStreamer() | ||
{ | ||
finishLogging(); | ||
} | ||
|
||
bool CSVStreamer::prepareFile(std::string& directory) | ||
{ | ||
filePath = directory + logFileName; | ||
csvFile.open(filePath, std::ios::out); | ||
if (!csvFile.is_open()) | ||
{ | ||
logger->error("Failed to open file: {}", filePath); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
void CSVStreamer::createHeader(const std::vector<std::string>& values) | ||
{ | ||
std::string header = "time,"; | ||
for (const auto& value : values) | ||
{ | ||
header += value + ","; | ||
} | ||
header.back() = '\n'; | ||
currentBuffer->appendLine(header); | ||
} | ||
|
||
void CSVStreamer::writeLine(double time, const std::vector<double>& values) | ||
{ | ||
std::string line = std::to_string(time) + ","; | ||
for (const auto& value : values) | ||
{ | ||
line += std::to_string(value) + ","; | ||
} | ||
line.back() = '\n'; | ||
|
||
currentBuffer->appendLine(line); | ||
|
||
if (currentBuffer->isFull()) | ||
{ | ||
exchangeBuffers(); | ||
|
||
if (saveTask.valid() && saveTask.wait_for(std::chrono::seconds(0)) != std::future_status::ready) | ||
logger->error("Buffer overrun in CSVStreamer object!"); | ||
|
||
saveTask = std::async(std::launch::async, &CSVStreamer::writeFile, this); | ||
} | ||
} | ||
|
||
void CSVStreamer::exchangeBuffers() | ||
{ | ||
processingBuffer = currentBuffer; | ||
currentBuffer = currentBuffer->nextBuffer; | ||
currentBuffer->index = 0; | ||
} | ||
|
||
void CSVStreamer::writeFile() | ||
{ | ||
if (!csvFile.is_open()) | ||
{ | ||
logger->error("CSV file is not open!"); | ||
return; | ||
} | ||
|
||
for (size_t i = 0; i < processingBuffer->index; i++) | ||
{ | ||
csvFile << processingBuffer->buffer[i]; | ||
} | ||
} | ||
|
||
void CSVStreamer::finishLogging() | ||
{ | ||
if (csvFile.is_open()) | ||
{ | ||
exchangeBuffers(); | ||
writeFile(); | ||
csvFile.close(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#ifndef _CSV_STREAMER_HPP | ||
#define _CSV_STREAMER_HPP | ||
|
||
#include <fstream> | ||
#include <future> | ||
#include <iostream> | ||
#include <string> | ||
|
||
#include "spdlog/spdlog.h" | ||
|
||
class CSVStreamer | ||
{ | ||
public: | ||
struct Buffer | ||
{ | ||
bool appendLine(std::string& line); | ||
bool isFull() const; | ||
|
||
std::array<std::string, 1000> buffer; | ||
size_t index; | ||
Buffer* nextBuffer; | ||
}; | ||
|
||
CSVStreamer(spdlog::logger* logger); | ||
~CSVStreamer(); | ||
|
||
/// @brief Creates file in given directory with a fixed name | ||
/// @param directory directory string | ||
/// @return | ||
bool prepareFile(std::string& directory); | ||
|
||
/// @brief create csv file header from given argument, first column - time - is added internally | ||
/// @param values table headers | ||
void createHeader(const std::vector<std::string>& values); | ||
|
||
/// @brief writes single line to internal buffer | ||
/// @param time | ||
/// @param values | ||
void writeLine(double time, const std::vector<double>& values); | ||
|
||
/// @brief exchanges the buffer that is being processed with the one that's being written to | ||
void exchangeBuffers(); | ||
|
||
/// @brief writes the processing buffer to the opened csv file | ||
void writeFile(); | ||
|
||
/// @brief writes the rest of the buffer to the file and closes it | ||
void finishLogging(); | ||
|
||
private: | ||
const char* logFileName = "/logfile.csv"; | ||
|
||
spdlog::logger* logger; | ||
std::future<void> saveTask{}; | ||
std::string filePath; | ||
std::ofstream csvFile; | ||
Buffer buffer1{}; | ||
Buffer buffer2{}; | ||
Buffer* currentBuffer; | ||
Buffer* processingBuffer; | ||
}; | ||
|
||
#endif |
Oops, something went wrong.