FOSSredder 0.5.0
Loading...
Searching...
No Matches
CsvExporter.cpp
Go to the documentation of this file.
1
5
7
9#include "ExportConstants.h"
10
11#include <fstream>
12#include <iomanip>
13#include <sstream>
14
15namespace {
16
17inline constexpr auto kGermanLocalePrefix = "de";
18
19std::string escapeCsv(const std::string &value, char separator) {
20 bool requiresQuoting = false;
21 for (const char c : value) {
22 if (c == '"' || c == '\n' || c == '\r' || c == separator) {
23 requiresQuoting = true;
24 break;
25 }
26 }
27 if (!requiresQuoting) {
28 return value;
29 }
30
31 std::string escaped;
32 escaped.push_back('"');
33 for (const char c : value) {
34 if (c == '"') {
35 escaped.push_back('"');
36 }
37 escaped.push_back(c);
38 }
39 escaped.push_back('"');
40 return escaped;
41}
42
43} // namespace
44
46
47namespace export_ports = core::ports::exporting;
48
49namespace {
50
51bool shouldStop(const export_ports::ExportRequest &request) {
52 if (request.waitIfPaused) {
53 request.waitIfPaused();
54 }
55 return request.shouldCancel && request.shouldCancel();
56}
57
58export_ports::ExportResult canceledResult(
59 const export_ports::ExportRequest &request) {
60 export_ports::ExportResult result;
61 result.actualFormat = export_ports::ExportFormat::Csv;
62 result.resolvedOutputPath = request.outputPath;
63 result.status = export_ports::ExportStatus::Canceled;
64 result.message = "Canceled";
65 return result;
66}
67
68} // namespace
69
73 const export_ports::ExportRequest &request) const {
74 export_ports::ExportResult result;
75 result.actualFormat = export_ports::ExportFormat::Csv;
76 result.resolvedOutputPath = request.outputPath;
77
78 if (shouldStop(request)) {
79 return canceledResult(request);
80 }
81
82 if (request.outputPath.empty()) {
83 result.status = export_ports::ExportStatus::InvalidInput;
84 result.errorCode =
86 result.message =
88 return result;
89 }
90 const auto matrix = internal::buildPropertyContractMatrix(state);
91
92 char decimalSeparator = '.';
93 if (request.locale.starts_with(kGermanLocalePrefix)) {
94 decimalSeparator = ',';
95 }
96 constexpr char separator = ';';
97
98 std::ofstream output(request.outputPath, std::ios::binary);
99 if (!output) {
100 result.status = export_ports::ExportStatus::WriteFailed;
101 result.errorCode =
103 result.message =
105 return result;
106 }
107
108 const unsigned char bom[] = {0xEF, 0xBB, 0xBF};
109 output.write(reinterpret_cast<const char *>(bom), sizeof(bom));
110
111 const auto formatAmount = [&](double value) {
112 std::ostringstream stream;
113 stream << std::fixed << std::setprecision(2) << value;
114 std::string text = stream.str();
115 if (decimalSeparator != '.') {
116 for (auto &c : text) {
117 if (c == '.') {
118 c = decimalSeparator;
119 }
120 }
121 }
122 return text;
123 };
124
126 for (const auto &contractType : matrix.contractTypes) {
127 output << separator << escapeCsv(contractType, separator);
128 }
129 output << separator
131
132 for (const auto &propertyName : matrix.propertyNames) {
133 if (shouldStop(request)) {
134 return canceledResult(request);
135 }
136 output << escapeCsv(propertyName, separator);
137 double rowSum = 0.0;
138 const auto propertyIt = matrix.amountsByProperty.find(propertyName);
139 for (const auto &contractType : matrix.contractTypes) {
140 double value = 0.0;
141 if (propertyIt != matrix.amountsByProperty.end()) {
142 const auto contractIt = propertyIt->second.find(contractType);
143 if (contractIt != propertyIt->second.end()) {
144 value = contractIt->second;
145 }
146 }
147 output << separator << formatAmount(value);
148 rowSum += value;
149 }
150 output << separator << formatAmount(rowSum) << "\n";
151 }
152
153 output.close();
154 if (!output) {
155 result.status = export_ports::ExportStatus::WriteFailed;
156 result.errorCode =
158 result.message =
160 return result;
161 }
162
163 result.status = export_ports::ExportStatus::Ok;
164 result.success = true;
165 return result;
166}
167
168} // namespace core::application::exporting
Declares CSV export for the property/contract-type matrix.
Defines private constants shared by core export implementations.
Declares private helpers for building export matrix data from workspace state.
core::ports::exporting::ExportResult exportData(const core::domain::catalog::WorkspaceCatalog &state, const core::ports::exporting::ExportRequest &request) const
Exports the property/contract matrix to a CSV file.
PropertyContractMatrix buildPropertyContractMatrix(const core::domain::catalog::WorkspaceCatalog &state)
Builds the property/contract matrix from the current workspace snapshot.