mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
99 lines
2.4 KiB
C++
99 lines
2.4 KiB
C++
|
|
||
|
|
||
|
#include "csv.h"
|
||
|
|
||
|
#include <wx/txtstrm.h>
|
||
|
|
||
|
|
||
|
#include <rapidcsv/rapidcsv.h>
|
||
|
|
||
|
|
||
|
CSV_WRITER::CSV_WRITER( wxOutputStream& aStream ) :
|
||
|
m_stream( aStream ), m_delimiter( wxT( "," ) ), m_quote( wxT( "\"" ) ), m_lineTerminator( wxT( "\n" ) ),
|
||
|
m_escape( wxEmptyString )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSV_WRITER::WriteLines( const std::vector<std::vector<wxString>>& aRows )
|
||
|
{
|
||
|
for( const auto& row : aRows )
|
||
|
{
|
||
|
WriteLine( row );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSV_WRITER::WriteLine( const std::vector<wxString>& cols )
|
||
|
{
|
||
|
wxString line;
|
||
|
for( size_t i = 0; i < cols.size(); ++i )
|
||
|
{
|
||
|
wxString colVal = cols[i];
|
||
|
|
||
|
if( i > 0 )
|
||
|
line += m_delimiter;
|
||
|
|
||
|
double test;
|
||
|
if( !colVal.ToDouble( &test ) )
|
||
|
{
|
||
|
bool useEscape = m_escape.size();
|
||
|
|
||
|
if( useEscape )
|
||
|
{
|
||
|
colVal.Replace( m_quote, m_escape + m_quote, true );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
colVal.Replace( m_quote, m_quote + m_quote, true );
|
||
|
}
|
||
|
|
||
|
colVal = m_quote + colVal + m_quote;
|
||
|
}
|
||
|
|
||
|
line += colVal;
|
||
|
}
|
||
|
line += m_lineTerminator;
|
||
|
|
||
|
m_stream.Write( line.c_str(), line.length() );
|
||
|
}
|
||
|
|
||
|
|
||
|
bool AutoDecodeCSV( const wxString& aInput, std::vector<std::vector<wxString>>& aData )
|
||
|
{
|
||
|
// Read the first line to determine the delimiter
|
||
|
bool trimCells = true;
|
||
|
bool skipCommentLines = true;
|
||
|
bool skipEmptyLines = true;
|
||
|
char commentPrefix = '#';
|
||
|
char delimiter = ',';
|
||
|
|
||
|
// Assume if we find a tab, we are dealing with a TSV file
|
||
|
if( aInput.find( '\t' ) != std::string::npos )
|
||
|
{
|
||
|
delimiter = '\t';
|
||
|
}
|
||
|
|
||
|
std::istringstream inputStream( aInput.ToStdString() );
|
||
|
|
||
|
rapidcsv::Document doc( inputStream, rapidcsv::LabelParams( -1, -1 ),
|
||
|
rapidcsv::SeparatorParams( delimiter, trimCells ), rapidcsv::ConverterParams(),
|
||
|
rapidcsv::LineReaderParams( skipCommentLines, commentPrefix, skipEmptyLines ) );
|
||
|
|
||
|
// Read the data into aData
|
||
|
aData.clear();
|
||
|
|
||
|
for( size_t i = 0; i < doc.GetRowCount(); ++i )
|
||
|
{
|
||
|
std::vector<wxString>& row = aData.emplace_back();
|
||
|
for( size_t j = 0; j < doc.GetColumnCount(); ++j )
|
||
|
{
|
||
|
std::string cell = doc.GetCell<std::string>( j, i );
|
||
|
row.emplace_back( cell );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Anything in the first row?
|
||
|
return aData[0].size() > 0;
|
||
|
}
|