Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386322
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/examples/CSVFiles/main.cpp b/examples/CSVFiles/main.cpp
index 68e287a..d457785 100644
--- a/examples/CSVFiles/main.cpp
+++ b/examples/CSVFiles/main.cpp
@@ -1,153 +1,157 @@
//===-- examples/CSVFiles/main.cpp --------------------------------*- C++ -*-===//
//
// The RoSA Framework -- Example CSVFiles
//
//===----------------------------------------------------------------------===//
///
/// \file examples/CSVFiles/main.cpp
///
/// \author Edwin Willegger (edwin.willegger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief This example shows how you could use the CSVIterator class to
/// get data into RoSA from a CSV-file.
//===----------------------------------------------------------------------===//
// To compile with dumping record layout:
// $ clang++ -o variadic-tuple -Xclang -fdump-record-layouts variadic-tuple.cpp
// -Wall -g -std=c++11
#include <cstdint>
#include <cstddef>
#include <iostream>
#include <istream>
#include <sstream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>
#include <typeinfo>
#include <map>
#include <algorithm>
#include <tuple>
#include <type_traits>
#include <unistd.h>
#include "rosa/support/csv/CSVReader.hpp"
#include "rosa/support/csv/CSVWriter.hpp"
const std::string AppName = "test-csvfiles";
//the example will be executed in the bin directory, but the data files are located in another the examples folder
const std::string Path = "../examples/CSVFiles/";
void testtupleCSVReader(){
//different streams to get the csv data out of the files
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_2("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_3("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_4("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_5("HR-New.csv");
//file contains header and valid data entries, delimter = ','
std::ifstream file_header_data_6("HR-New.csv");
//file contains no header an valid data entries, delimter = ','
std::ifstream file2("HR.csv");
//file contains header and valid data entries, delimter = ';'
std::ifstream file3("HR-New-Semicolon.csv");
rosa::csv::CSVIterator<int, std::string, std::string, int, int> it(file_header_data);
it.setDelimeter(',');
it++;
it++;
//if you iterate over the end of file, the last values
//of the file will remain in the data structure but no
//error occurs.
it++;
it++;
//-------------------------------------------------------------------
// a possiblity to get the data out of the iterator
std::tuple<int, std::string, std::string, int, int> value = *it;
std::cout << "Values are: " << std::get<0>(value) << " "
<< std::get<1>(value) << " ,are you now happy?" << std::endl;
//--------------------------------------------------------------------
//testing differnet parameters to the constructor
//uncomment to see that it is not possible to iterate over an vector in the tuple.
//rosa::csv::CSVIterator<double, std::vector<int>> it2(file, 1);
//try to skip a valid number of lines after the header
rosa::csv::CSVIterator<double, float, int, int, float> it2_0(file_header_data_2, 1);
//try to skip a valid number of lines after the header, but you assume that the file has no header
//uncomment this line to crash the programm
//rosa::csv::CSVIterator<double, float, int, int, float> it2_1(file_header_data_3, 0, rosa::csv::HeaderInformation::HasNoHeader);
//try to skip a valid number of lines after the header, but you assume that the file has no header
//uncomment this line to crash the program
// rosa::csv::CSVIterator<double, float, int, int, float> it2_2(file_header_data_4, 1, rosa::csv::HeaderInformation::HasNoHeader);
//try to skip a valid number of lines of a file without header
rosa::csv::CSVIterator<double, float, int, int, float> it2_3(file2, 1, rosa::csv::HeaderInformation::HasNoHeader);
//try to skip a valid number of lines after the header, but with different delimeter
rosa::csv::CSVIterator<double, float, int, int, float> it2_4(file3, 2,rosa::csv::HeaderInformation::HasHeader, ';');
// if you skip more lines than valid, you generate an infinte loop
//rosa::csv::CSVIterator<double, float, int, int, float> it3(file_header_data_5, 500);
//if you don't need data from all columns just select the number of columns you
//need. You get the data back from the first column (index 0) to the fourth column
//all values from the fifth column are ignored.
rosa::csv::CSVIterator<double, float, int, float> it4(file_header_data_6);
}
void testtupleCSVWriter(){
std::ofstream file_header_out("csvwriter_noheader.csv");
rosa::csv::CSVTupleWriter<int, float, std::string> wri(file_header_out);
std::tuple<int, float, std::string> values(5, 8.3, "hallo");
std::tuple<int, float, std::string> values2(3, 8.3, "end");
- std::vector<std::string> header;
- header.push_back("first column");
- header.push_back("second column");
- header.push_back("third column");
+ std::array<std::string, 3> header {"first column", "second column", "third column"};
+
+ //wrong header size, which is unable to write as a header to the tuples above.
+ std::array<std::string, 4> headerWrong {"first column", "second column", "third column", "fourth column"};
wri.writeHeader(header);
wri.write(values);
wri.write(values);
wri.write(values);
wri << values;
wri << values2;
+ //uncomment this line to see, that you can't write a header with the wrong number of elements.
+ //wri.writeHeader(headerWrong);
+
+
}
int main(void) {
std::cout << "This is a short example to show you how you could use the CSVIterator class." << std::endl;
std::cout << "There are also some limitations explained in the source code of the example." << std::endl;
std::cout << "Testing CSVWriter CSVTupleItrator implementation: " << std::endl;
testtupleCSVWriter();
std::cout << "Testing CSVReader CSVTupleIterator implementation: " << std::endl;
testtupleCSVReader();
std::cout << "All tests finished sucessfully" << std::endl;
return 0;
}
diff --git a/include/rosa/support/csv/CSVWriter.hpp b/include/rosa/support/csv/CSVWriter.hpp
index b7d5389..5eb21ee 100755
--- a/include/rosa/support/csv/CSVWriter.hpp
+++ b/include/rosa/support/csv/CSVWriter.hpp
@@ -1,177 +1,180 @@
//===-- rosa/support/csv/CSVWriter.hpp --------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/csv/CSVWriter.hpp
///
/// \authors David Juhasz (david.juhasz@tuwien.ac.at)
/// Edwin Willegger (edwin.willegger@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Facitilities to write CSV files.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_SUPPORT_CSV_CSVWRITER_HPP
#define ROSA_SUPPORT_CSV_CSVWRITER_HPP
#include <iostream>
#include <ostream>
#include <tuple>
#include <vector>
+#include <array>
namespace rosa {
namespace csv {
/// Provides facilities to write values into a CSV file.
///
/// The writer emits a comma, the character `,`, between each written values.
/// The resulted stream is a flat CSV file as it consists of onlyone row, no new
/// line is emitted.
///
/// \tparam T type of values to write
template <typename T>
class CSVWriter {
public:
/// Creates a new instance.
///
/// \param [in,out] S output stream to write to
///
/// \note The writer operates on non-binary outputs as long as \p S is in
/// good state.
CSVWriter(std::ostream &S)
: Str(S.good() && !(S.flags() & std::ios::binary) ? &S : nullptr),
IsFirst(true) {}
/// Tells if the last operation was successful.
///
/// \return if the last operation was successful
bool good(void) const noexcept {
return Str != nullptr;
}
/// Writes an entry to the output stream.
///
/// The implementation does anything only if the last operation was
/// successful. If so, \p V is written to \c rosa::csv::CSVWriter::Str.
/// The emitted value is preceded with a comma if the actual call is not the
/// first one for \p this object. Success of the operation is checked at the
/// end.
///
/// \param V value to write
void write(const T &V) {
if (Str) {
if (!IsFirst) {
*Str << ',';
} else {
IsFirst = false;
}
*Str << V;
if (!Str->good()) {
Str = nullptr;
}
}
}
private:
std::ostream *Str; ///< Output stream to write to.
bool IsFirst; ///< Denotes if the next write would be the first one.
};
/// Writes a tuple of values into a CSV file
///
/// \tparam Ts tpyes of values to write
template <typename... Ts> class CSVTupleWriter {
public:
/// Creates a new instance.
///
/// \param [in,out] S output stream to write to
///
/// \note The writer operates on non-binary outputs as long as \p S is in
/// good state.
CSVTupleWriter(std::ostream &S)
: Str(S.good() && !(S.flags() & std::ios::binary) ? &S : nullptr),
IsFirst(true) {}
/// Tells if the last operation was successful.
///
/// \return if the last operation was successful
bool good(void) const noexcept {
return Str != nullptr;
}
template<size_t i = 0>
void write(std::tuple<Ts...> values) {
size_t size = 0;
std::cout << "Writing tuple values into file" << std::endl;
std::cout << "Tuple has ";
std::cout << std::tuple_size<decltype (values)>::value;
std::cout << " elements." << std::endl;
size = std::tuple_size<decltype (values)>::value;
std::cout << std::get<i>(values) << std::endl;
if(Str){
if constexpr(i+1 != sizeof...(Ts)){
*Str << std::get<i>(values) << ", ";
write<i+1>(values);
}else if constexpr(i + 1 == sizeof...(Ts)){
*Str << std::get<i>(values) << '\n';
}
}
}
- void writeHeader(std::vector<std::string> header){
+ void writeHeader(std::array<std::string, sizeof...(Ts)> header){
size_t index = 0;
if(Str){
index = 0;
for (auto i = header.begin(); i != header.end(); ++i){
index = index + 1;
if(index != header.size()){
*Str << *i << ", ";
}else {
*Str << *i;
}
}
*Str << '\n';
}
}
private:
std::ostream *Str; ///< Output stream to write to.
bool IsFirst; ///< Denotes if the next write would be the first one.
+ const size_t tupleSize = sizeof...(Ts); /// explicitly the number of elements of the tuple.
+
};
template <typename... Ts>
CSVTupleWriter<Ts...> &operator<<(CSVTupleWriter<Ts...> &W, const std::tuple<Ts...> V)
{
W.write(V);
return W;
}
/// Writes a value to a CSV file with \c rosa::csv::CSVWriter.
///
/// \see rosa::csv::CSVWriter
///
/// \tparam T type of value to write
///
/// \param [in,out] W object to write with
/// \param V value to write
///
/// \return \p W after writing \p V with it
template <typename T>
CSVWriter<T> &operator<<(CSVWriter<T> &W, const T& V) {
W.write(V);
return W;
}
} // End namespace csv
} // End namespace rosa
#endif // ROSA_SUPPORT_CSV_CSVWRITER_HPP
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jul 3, 1:11 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157169
Default Alt Text
(11 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment