Class provides CSV files manipulation routine. More...
#include <loaders/csv_file.h>
Public Member Functions | |
void | OpenFile (const char *FilePath) |
void | OpenFile (const std::string &FilePath) |
bool | ReadRecord (CSVReadable *Readable, const std::size_t MODE=0) |
void | ReadHeader (const std::size_t MODE=0) |
std::size_t | GetHeaderItemsCount (void) |
nitro::BinaryData & | GetHeaderItem (std::size_t i) |
template<class cont > | |
bool | ReadRecord (cont &Container, const std::size_t MODE=0) |
template<class cont > | |
void | ReadAllRecords (cont &Container, const std::size_t MODE=0) |
void | AppendRecord (CSVWritable *Writable, const std::size_t MODE=0) |
template<class cont > | |
void | AppendRecord (cont &Container, const std::size_t MODE=0) |
template<class cont > | |
void | AppendAllRecords (cont &Container, const std::size_t MODE=0) |
void | CloseFile (void) |
virtual | ~CSVFile () |
Static Public Member Functions | |
static void | SetReadBufferSize (std::size_t ReadBufferSize) |
Private Attributes | |
nitro::FileAbstraction | FileStream |
std::vector< nitro::BinaryData > | Header |
Class provides CSV files manipulation routine.
Definition at line 193 of file csv_file.h.
nitro::CSVFile::~CSVFile | ( | ) | [virtual] |
Destructor.
Definition at line 494 of file csv_file.cpp.
References CloseFile().
{ try { CloseFile(); } catch( ... ) { } }
void nitro::CSVFile::AppendAllRecords | ( | cont & | Container, | |
const std::size_t | MODE = 0 | |||
) |
Function writes all records.
Container | - STL container with nitro::BinaryData objects. | |
MODE | - Record reading mode. |
nitro::exception | hrows an exception of that type with the error description. |
Definition at line 632 of file csv_file.h.
References AppendRecord(), nitro::exception::code(), and nitro::exception::what().
{ try { typedef typename cont::iterator IterType; for( IterType i( Container.begin() ) ; i != Container.end() ; ++i ) { AppendRecord( *i , MODE ); } } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::AppendAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::AppendAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::AppendRecord | ( | CSVWritable * | Writable, | |
const std::size_t | MODE = 0 | |||
) |
Function writes one record.
Writable | - Interface for saving data in file. | |
MODE | - Record writing mode. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 355 of file csv_file.cpp.
References nitro::BinaryData::AppendData(), nitro::exception::code(), nitro::CSV_AUTO_ESCAPE(), nitro::FA_FILE_BEGIN, nitro::FA_FILE_END, FileStream, nitro::BinaryData::GetBuffer(), nitro::BinaryData::GetBufferLength(), nitro::CSVWritable::GetField(), nitro::CSVWritable::GetFieldCount(), nitro::BinaryData::GetOccuranceCount(), nitro::FileAbstraction::Read(), nitro::BinaryData::Reserve(), nitro::FileAbstraction::Seek(), nitro::FileAbstraction::Tell(), nitro::exception::what(), and nitro::FileAbstraction::Write().
Referenced by AppendAllRecords(), and AppendRecord().
{ try { std::size_t FilePosition( FileStream.Tell() ); // \~russian сначала считаем сколько нам понадобится байт // \~english count how many bytes do we need std::size_t BytesCount( 0 ); // \~russian смотрим что в конце файла // \~english what do we have at the end of the file? FileStream.Seek( 0 , FA_FILE_END ); std::size_t EndOfFilePosition( FileStream.Tell() ); FileStream.Seek( EndOfFilePosition - 2 , FA_FILE_BEGIN ); char EndOfFile[ 2 ]; FileStream.Read( EndOfFile , 2 ); bool PrependCRLF( false ); if( EndOfFile[ 0 ] != '\r' || EndOfFile[ 1 ] != '\n' ) { PrependCRLF = true; BytesCount += 2; } const char * Buffer; std::size_t BufferSize; int Tmp; // \~russian длина полей (нужно ли обрамлять поле кавычками) // \~english fields length (should be the field bounded by braces) for( std::size_t i( 0 ) ; i < Writable->GetFieldCount() ; i++ ) { Writable->GetField( i , Buffer , BufferSize , MODE ); BytesCount += BufferSize; if( MODE & CSV_AUTO_ESCAPE ) { Tmp = nitro::BinaryData::GetOccuranceCount( Buffer , BufferSize , "\"" , 1 ); if( Tmp != 0 ) { BytesCount += 2 + Tmp; } } } // \~russian запятые // \~english commas BytesCount += Writable->GetFieldCount() - 1; // \~russian добавляем CRLF // \~english appending CRLF BytesCount += 2; nitro::BinaryData Data; if( PrependCRLF ) { Data.Reserve( BytesCount + 2 ); Data.AppendData( "\r\n" ); } else { Data.Reserve( BytesCount ); } for( std::size_t i( 0 ) ; i < Writable->GetFieldCount() ; i++ ) { Writable->GetField( i , Buffer , BufferSize , MODE ); Tmp = 0; if( MODE & CSV_AUTO_ESCAPE ) { Tmp = nitro::BinaryData::GetOccuranceCount( Buffer , BufferSize , "\"" , 1 ); } if( Tmp != 0 ) { Data.AppendData( '"' ); } for( std::size_t j( 0 ) ; j < BufferSize ; j++ ) { if( Buffer[ j ] == '"' && ( MODE & CSV_AUTO_ESCAPE ) ) { Data.AppendData( '"' ); } Data.AppendData( Buffer[ j ] ); } if( Tmp != 0 ) { Data.AppendData( '"' ); } if( i < Writable->GetFieldCount() - 1 ) { Data.AppendData( ',' ); } else { Data.AppendData( "\r\n" , 2 ); } } FileStream.Write( Data.GetBuffer() , Data.GetBufferLength() ); FileStream.Seek( FilePosition , FA_FILE_BEGIN ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::AppendRecord( CSVWritable * Writable , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::AppendRecord( CSVWritable * Writable , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::AppendRecord | ( | cont & | Container, | |
const std::size_t | MODE = 0 | |||
) |
Function writes one record.
Container | - STL container with nitro::BinaryData objects. | |
MODE | - Record reading mode. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 594 of file csv_file.h.
References AppendRecord(), nitro::exception::code(), and nitro::exception::what().
{ try { class CSVRecordWriter:public CSVWritable{ cont * Container; public: CSVRecordWriter( cont * theContainer ) { Container = theContainer; } virtual void GetField( const std::size_t & FieldCursor , const char * & Buffer , std::size_t & BufferSize , const std::size_t & MODE = 0 ) { Buffer = ( * Container )[ FieldCursor ].GetBuffer(); BufferSize = ( * Container )[ FieldCursor ].GetBufferLength(); } virtual std::size_t GetFieldCount( void ) { return( Container->size() ); } }; CSVRecordWriter Writer( & Container ); return( AppendRecord( ( CSVWritable * ) & Writer , MODE ) ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::AppendRecord( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::AppendRecord( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::CloseFile | ( | void | ) |
Function closes file.
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 478 of file csv_file.cpp.
References nitro::FileAbstraction::Close(), nitro::exception::code(), FileStream, and nitro::exception::what().
Referenced by ~CSVFile().
{ try { FileStream.Close(); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::CloseFile( void )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::CloseFile( void )::An error occured" ) , 1 ) ); } }
nitro::BinaryData & nitro::CSVFile::GetHeaderItem | ( | std::size_t | i | ) |
Function returns header's item.
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 339 of file csv_file.cpp.
References nitro::exception::code(), Header, and nitro::exception::what().
{ try { return( Header[ i ] ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::GetHeaderItem( std::size_t i )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::GetHeaderItem( std::size_t i )::An error occured" ) , 1 ) ); } }
std::size_t nitro::CSVFile::GetHeaderItemsCount | ( | void | ) |
Function returns count of items in header.
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 323 of file csv_file.cpp.
References nitro::exception::code(), Header, and nitro::exception::what().
{ try { return( Header.size() ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::GetHeaderItemsCount( void )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::GetHeaderItemsCount( void )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::OpenFile | ( | const char * | FilePath | ) |
Function opens file for reading.
FilePath | - Path to the opening file. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 43 of file csv_file.cpp.
References nitro::exception::code(), nitro::FA_FILE_BINARY, nitro::FA_FILE_READ, nitro::FA_FILE_WRITE, FileStream, nitro::FileAbstraction::Open(), and nitro::exception::what().
Referenced by OpenFile().
{ try { FileStream.Open( FilePath , nitro::FA_FILE_BINARY | nitro::FA_FILE_READ | nitro::FA_FILE_WRITE ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::OpenFile( const char * FilePath )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::OpenFile( const char * FilePath )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::OpenFile | ( | const std::string & | FilePath | ) |
Function opens file for reading.
FilePath | - Path to the opening file. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 59 of file csv_file.cpp.
References nitro::exception::code(), OpenFile(), and nitro::exception::what().
{ try { OpenFile( FilePath.c_str() ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::OpenFile( const std::string & FilePath )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::OpenFile( const std::string & FilePath )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::ReadAllRecords | ( | cont & | Container, | |
const std::size_t | MODE = 0 | |||
) |
Function reads all records.
Container | - STL container with containers with objects of type nitro::BinaryData. | |
MODE | - Record reading mode. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 564 of file csv_file.h.
References nitro::exception::code(), ReadRecord(), and nitro::exception::what().
{ try { typedef typename cont::value_type FieldType; FieldType CSVRecord; bool EndOfFile( false ); do { EndOfFile = ReadRecord( CSVRecord , MODE ); * ( std::back_inserter( Container ) ) = CSVRecord; CSVRecord.erase( CSVRecord.begin() , CSVRecord.end() ); } while( EndOfFile == false ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::ReadAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::ReadAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::ReadHeader | ( | const std::size_t | MODE = 0 |
) |
Function reads header.
MODE | - Header reading mode. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 307 of file csv_file.cpp.
References nitro::exception::code(), Header, ReadRecord(), and nitro::exception::what().
{ try { ReadRecord( Header , MODE ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::ReadHeader( const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::ReadHeader( const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
bool nitro::CSVFile::ReadRecord | ( | cont & | Container, | |
const std::size_t | MODE = 0 | |||
) |
Function reads one record.
Container | - STL container with nitro::BinaryData objects. | |
MODE | - Record reading mode. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 529 of file csv_file.h.
References nitro::exception::code(), ReadRecord(), and nitro::exception::what().
{ try { class CSVRecordReader:public CSVReadable{ cont * Container; typedef typename cont::value_type FieldType; public: CSVRecordReader( cont * theContainer ) { Container = theContainer; } virtual void AddField( const char * Buffer , const std::size_t & BufferSize ) { std::back_inserter( * Container ) = FieldType(); Container->back().AppendData( Buffer , BufferSize ); } }; CSVRecordReader Reader( & Container ); return( ReadRecord( ( CSVReadable * ) & Reader , MODE ) ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::ReadRecord( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::ReadRecord( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
bool nitro::CSVFile::ReadRecord | ( | CSVReadable * | Readable, | |
const std::size_t | MODE = 0 | |||
) |
Function reads one record.
Readable | - Interface for saving data. | |
MODE | - Record reading mode. |
nitro::exception | Throws an exception of that type with the error description. |
Definition at line 75 of file csv_file.cpp.
References nitro::ADD_FIELD(), nitro::CSVReadable::AddField(), nitro::BinaryData::AppendData(), nitro::exception::code(), nitro::CSV_AUTO_ESCAPE(), nitro::CSV_FILE_READ_BUFFER_SIZE(), nitro::END_QUOTED_FIELD(), nitro::END_RECORD(), nitro::FA_FILE_BEGIN, FileStream, nitro::BinaryData::GetBuffer(), nitro::BinaryData::GetBufferLength(), nitro::QUOTE_WAS_FOUND(), nitro::FileAbstraction::Read(), nitro::READ_DATA(), nitro::BinaryData::ReplaceBuffer(), nitro::FileAbstraction::Seek(), nitro::START_FIELD(), nitro::FileAbstraction::Tell(), nitro::TRY_READ_NEXT(), and nitro::exception::what().
Referenced by ReadAllRecords(), ReadHeader(), and ReadRecord().
{ try { std::size_t FilePosition; std::size_t ReadBytes; // saving this value on stack to avoid 'ass pain' debug in multy-threaded applications const std::size_t ReadBufferSize( CSV_FILE_READ_BUFFER_SIZE ); char * Buffer( new char[ ReadBufferSize ] ); bool QFieldStart( false ); bool FieldStart( false ); std::size_t FieldStartCursor( 0 ); std::size_t State( START_FIELD ); std::size_t FieldRawSize( 0 ); do { FilePosition = FileStream.Tell(); ReadBytes = FileStream.Read( Buffer , ReadBufferSize ); for( std::size_t i( 0 ) ; i < ReadBufferSize + 1 && i < ReadBytes + 1 ; i++ ) { if( ReadBytes == 0 || ( ReadBytes < ReadBufferSize && i == ReadBytes ) ) { if( QFieldStart == true ) { throw( nitro::exception( "Illegal sintax (quote was not found)" , 1 ) ); } if( FieldStart == true ) { State = ADD_FIELD; } } else { if( i == ReadBufferSize || i == ReadBytes ) { continue; } } if( State == START_FIELD ) { FieldRawSize = 0; if( ( Buffer[ i ] >= 0x20 && Buffer[ i ] <= 0x21 ) || ( Buffer[ i ] >= 0x23 && Buffer[ i ] <= 0x2b ) || ( Buffer[ i ] >= 0x2d && Buffer[ i ] <= 0x7e ) || Buffer[ i ] == ',' ) { FieldStart = true; FieldStartCursor = FilePosition + i; State = READ_DATA; } if( Buffer[ i ] == '"' ) { FieldRawSize++; QFieldStart = true; FieldStartCursor = FilePosition + i; State = READ_DATA; continue; } } if( State == READ_DATA ) { FieldRawSize++; if( Buffer[ i ] == '"' && QFieldStart == false ) { throw( nitro::exception( "Illegal sintax (quote was found)" , 1 ) ); } if( Buffer[ i ] == '\r' && QFieldStart == false ) { FieldRawSize--; State = ADD_FIELD; } if( Buffer[ i ] == '\n' && QFieldStart == false ) { throw( nitro::exception( "Illegal sintax (LF was found)" , 1 ) ); } if( Buffer[ i ] == '"' && QFieldStart == true ) { if( i < ReadBytes - 1 ) { State = QUOTE_WAS_FOUND; continue; } else { State = ADD_FIELD; } } if( Buffer[ i ] == ',' && FieldStart == true ) { FieldRawSize--; State = ADD_FIELD; } } if( State == QUOTE_WAS_FOUND ) { if( Buffer[ i ] == '"' ) { FieldRawSize++; State = READ_DATA; continue; } if( Buffer[ i ] == ',' || Buffer[ i ] == '\r' ) { State = ADD_FIELD; } else { throw( nitro::exception( "Can't end quoted field (1)'" , 1 ) ); } } if( State == END_QUOTED_FIELD ) { if( Buffer[ i ] == ',' ) { State = ADD_FIELD; } else { throw( nitro::exception( "Can't end quoted field (2)'" , 1 ) ); } } if( State == ADD_FIELD ) { if( FieldRawSize > 0 ) { nitro::BinaryData Data; std::size_t Decreaser( 0 ); if( QFieldStart == true ) { Decreaser = 1; } if( FieldStartCursor < FilePosition ) { // data is stored in several buffers, so let's read it in memory char * FieldValue( new char [ FieldRawSize - 2 * Decreaser ] ); FileStream.Seek( FieldStartCursor + Decreaser , FA_FILE_BEGIN ); FileStream.Read( FieldValue , FieldRawSize - 2 * Decreaser ); Data.AppendData( FieldValue , FieldRawSize - 2 * Decreaser ); FileStream.Seek( FilePosition + ReadBufferSize , FA_FILE_BEGIN ); delete [] FieldValue; } else { // data is stored in one buffer, so it is already in memory std::size_t BufferOffset( FieldStartCursor + Decreaser - FilePosition ); Data.AppendData( Buffer + BufferOffset , FieldRawSize - 2 * Decreaser ); } if( MODE & CSV_AUTO_ESCAPE ) { nitro::BinaryData::ReplaceBuffer( Data , ( const char * )"\"\"" , ( const std::size_t )2 , ( const char * )"\"" , ( const std::size_t )1 ); } Readable->AddField( Data.GetBuffer() , Data.GetBufferLength() ); } else { Readable->AddField( "" , 0 ); } QFieldStart = false; FieldStart = false; State = TRY_READ_NEXT; } if( State == TRY_READ_NEXT ) { if( Buffer[ i ] == ',' ) { State = START_FIELD; } if( Buffer[ i ] == '\r' ) { State = END_RECORD; continue; } } if( State == END_RECORD ) { if( Buffer[ i ] == '\n' ) { // чтение закончено State = START_FIELD; FileStream.Seek( FilePosition + i + 1 , FA_FILE_BEGIN ); delete [] Buffer; return( false ); } else { throw( nitro::exception( "Can't find LF symbol" , 1 ) ); } } } } while( ReadBytes == ReadBufferSize ); delete [] Buffer; return( true ); } catch( nitro::exception e ) { throw( nitro::exception( std::string( "CSVFile::ReadRecord( CSVReadable * Readable , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) ); } catch( ... ) { throw( nitro::exception( std::string( "CSVFile::ReadRecord( CSVReadable * Readable , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) ); } }
void nitro::CSVFile::SetReadBufferSize | ( | std::size_t | ReadBufferSize | ) | [static] |
Function sets read buffer size.
Definition at line 505 of file csv_file.cpp.
References nitro::CSV_FILE_READ_BUFFER_SIZE().
{ CSV_FILE_READ_BUFFER_SIZE = ReadBufferSize; }
File stream.
Definition at line 514 of file csv_file.h.
Referenced by AppendRecord(), CloseFile(), OpenFile(), and ReadRecord().
std::vector< nitro::BinaryData > nitro::CSVFile::Header [private] |
File's header.
Definition at line 526 of file csv_file.h.
Referenced by GetHeaderItem(), GetHeaderItemsCount(), and ReadHeader().