read bin file

This commit is contained in:
2025-03-14 16:25:25 +01:00
parent 90a16ddcb9
commit 5814fdd0cb
5 changed files with 253 additions and 1 deletions

View File

@ -39,6 +39,9 @@ add_executable(Sim_C__
src/services/Cost/ServiceCharge.h
src/helper/StringOperations.cpp
src/helper/StringOperations.h
src/helper/CsvBinary.cpp
src/helper/CsvBinary.h
tests/helper/test_CsvBinary.cpp
)
find_package(doctest CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)

192
src/helper/CsvBinary.cpp Normal file
View File

@ -0,0 +1,192 @@
//
// Created by stani on 3/14/25.
//
#include "CsvBinary.h"
#include <fstream>
#include <sstream>
#include <spdlog/spdlog.h>
#include <algorithm>
#include "../Config.h"
std::vector<std::string> CsvBinary::splitLine(const std::string &line, const char delimiter) {
std::vector<std::string> tokens;
std::stringstream ss(line);
std::string token;
while (std::getline(ss, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFile) {
std::ifstream inFile(csvFile);
std::ofstream outFile(binFile, std::ios::binary);
if (!inFile.is_open() || !outFile.is_open()) {
LOG_DEBUG_ERROR("Failed opening file");
return;
}
std::string line;
bool isHeader = true;
std::vector<std::string> header;
std::stringstream jsonHeader;
jsonHeader << "{\"headers\":[";
while (std::getline(inFile, line)) {
std::vector<std::string> row = splitLine(line, ';');
if (isHeader) {
header = row;
// Store header as JSON
for (size_t i = 0; i < header.size(); ++i) {
jsonHeader << "\"" << header[i] << "\"";
if (i < header.size() - 1) jsonHeader << ",";
}
jsonHeader << "]}";
std::string jsonStr = jsonHeader.str();
size_t jsonSize = jsonStr.size();
// Write JSON size and content at the beginning of the binary file
outFile.write(reinterpret_cast<const char *>(&jsonSize), sizeof(size_t));
outFile.write(jsonStr.c_str(), jsonSize);
isHeader = false;
continue;
}
for (const auto &field : row) {
size_t length = field.size();
outFile.write(reinterpret_cast<const char *>(&length), sizeof(size_t));
outFile.write(field.c_str(), length);
}
}
inFile.close();
outFile.close();
LOG_DEBUG_INFO("CSV converted to binary successfully.");
}
void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFile) {
std::ifstream inFile(binFile, std::ios::binary);
std::ofstream outFile(csvFile);
if (!inFile.is_open() || !outFile.is_open()) {
LOG_DEBUG_ERROR("Failed opening file");
return;
}
// Read JSON metadata
size_t jsonSize;
inFile.read(reinterpret_cast<char *>(&jsonSize), sizeof(size_t));
std::string jsonStr(jsonSize, ' ');
inFile.read(&jsonStr[0], jsonSize);
// Parse JSON to extract headers
std::vector<std::string> header;
size_t start = jsonStr.find("[") + 1;
size_t end = jsonStr.find("]");
std::string headersStr = jsonStr.substr(start, end - start);
std::stringstream ss(headersStr);
std::string field;
while (std::getline(ss, field, ',')) {
field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes
header.push_back(field);
}
// Write header to CSV
for (size_t i = 0; i < header.size(); ++i) {
outFile << header[i];
if (i < header.size() - 1) outFile << ";";
}
outFile << "\n";
while (!inFile.eof()) {
std::vector<std::string> row;
for (size_t i = 0; i < header.size(); ++i) {
size_t length;
if (!inFile.read(reinterpret_cast<char *>(&length), sizeof(size_t))) break;
std::string field(length, ' ');
inFile.read(&field[0], length);
row.push_back(field);
}
if (!row.empty()) {
for (size_t i = 0; i < row.size(); ++i) {
outFile << row[i];
if (i < row.size() - 1) outFile << ";";
}
outFile << "\n";
}
}
inFile.close();
outFile.close();
LOG_DEBUG_INFO("Binary converted back to CSV successfully.");
}
std::unique_ptr<std::vector<std::pair<std::string, std::vector<std::string>>>> CsvBinary::binaryToVector(
const std::string &binFile) {
std::ifstream inFile(binFile, std::ios::binary);
auto data = std::make_unique<std::vector<std::pair<std::string, std::vector<std::string>>>>();
if (!inFile.is_open()) {
LOG_DEBUG_ERROR("Failed to open binary file");
return data; // Return empty structure
}
// Read JSON metadata size
size_t jsonSize;
inFile.read(reinterpret_cast<char *>(&jsonSize), sizeof(size_t));
// Read JSON metadata
std::string jsonStr(jsonSize, ' ');
inFile.read(&jsonStr[0], jsonSize);
// Extract headers from JSON
std::vector<std::string> headers;
size_t start = jsonStr.find("[") + 1;
size_t end = jsonStr.find("]");
std::string headersStr = jsonStr.substr(start, end - start);
std::stringstream ss(headersStr);
std::string field;
while (std::getline(ss, field, ',')) {
field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes
headers.push_back(field);
}
// Initialize data structure for columns
for (const auto &header : headers) {
data->emplace_back(header, std::vector<std::string>());
}
// Read row data and distribute into columns
while (!inFile.eof()) {
for (size_t i = 0; i < headers.size(); ++i) {
size_t length;
if (!inFile.read(reinterpret_cast<char *>(&length), sizeof(size_t))) break;
std::string value(length, ' ');
if (!inFile.read(&value[0], length)) break;
data->at(i).second.push_back(value);
}
}
inFile.close();
return data;
}

33
src/helper/CsvBinary.h Normal file
View File

@ -0,0 +1,33 @@
//
// Created by stani on 3/14/25.
//
#ifndef CSVTOBINARY_H
#define CSVTOBINARY_H
#include <iosfwd>
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <vector>
class CsvBinary {
private:
static std::vector<std::string> splitLine(const std::string &line, char delimiter);
static void saveHeaderToFile(const std::string &string, const std::string &line);
public:
static void csvToBinary(const std::string &csvFile, const std::string &binFile);
static void binaryToCsv(const std::string &binFile, const std::string &csvFile);
[[nodiscard]] static std::unique_ptr<std::vector<std::pair<std::string, std::vector<std::string>>>> binaryToVector(
const std::string &binFile);
};
#endif //CSVTOBINARY_H

View File

@ -0,0 +1,25 @@
//
// Created by stani on 3/14/25.
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <numeric>
#include <doctest/doctest.h>
#include <spdlog/spdlog.h>
#include "../../src/Config.h"
#include "../../src/helper/CsvBinary.h"
TEST_CASE("Test Csv to binary and back") {
CsvBinary::csvToBinary("Verbrauchsprofile.csv","Verbrauchsprofil.bin");
CsvBinary::binaryToCsv("Verbrauchsprofil.bin","Restored.csv");
auto verbrauchsProfil = CsvBinary::binaryToVector("Verbrauchsprofil.bin");
for (auto &row: *verbrauchsProfil) {
LOG_DEBUG_INFO("Sum from {}: {}",row.first ,std::accumulate(
row.second.begin(), row.second.end(), 0.f,
[](float sum, const std::string& val) {
return sum + std::stof(val); // Convert string to float before addition
}
));
}
}

View File

@ -1,7 +1,6 @@
//
// Created by StanislausCichocki on 10.03.2025.
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <spdlog/spdlog.h>
#include "../../src/services/Surplus.h"