Go to the documentation of this file.00001 #ifndef __CSVFILE_H__
00002 #define __CSVFILE_H__
00003
00004 #include <system/file_abstraction.h>
00005 #include <utilities/binary_data.h>
00006
00007 #if !defined( WIN32_PLATFORM ) && !defined( NIX_PLATFORM ) && !defined( MINGW_PLATFORM ) && !defined( CYGWIN_PLATFORM )
00008 #define WIN32_PLATFORM
00009 #endif
00010
00011 #ifdef CSV_FILE
00012 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM ) || defined( CYGWIN_PLATFORM )
00013 #define CSV_FILE_DLL_ENTITY __declspec( dllexport )
00014 #endif
00015
00016 #if defined( NIX_PLATFORM )
00017 #define CSV_FILE_DLL_ENTITY
00018 #endif
00019 #else
00020 #ifdef WIN32_PLATFORM
00021 #define CSV_FILE_DLL_ENTITY __declspec( dllimport )
00022 #pragma comment( lib , "csv_file.lib" )
00023 #endif
00024
00025 #if defined( CYGWIN_PLATFORM ) || defined( MINGW_PLATFORM )
00026 #define CSV_FILE_DLL_ENTITY __declspec( dllimport )
00027 #endif
00028
00029 #if defined( NIX_PLATFORM )
00030 #define CSV_FILE_DLL_ENTITY
00031 #endif
00032 #endif
00033
00034 namespace nitro
00035 {
00036
00047 const std::size_t CSV_AUTO_ESCAPE( 1 );
00048
00061 class CSV_FILE_DLL_ENTITY CSVReadable{
00062 public:
00063
00086 virtual void AddField( const char * Buffer , const std::size_t & BufferSize ) = 0;
00087
00098 virtual ~CSVReadable();
00099 };
00100
00113 class CSV_FILE_DLL_ENTITY CSVWritable{
00114 public:
00115
00134 virtual std::size_t GetFieldCount( void ) = 0;
00135
00166 virtual void GetField( const std::size_t & FieldCursor , const char * & Buffer , std::size_t & BufferSize , const std::size_t & MODE ) = 0;
00167
00178 virtual ~CSVWritable();
00179 };
00180
00193 class CSV_FILE_DLL_ENTITY CSVFile{
00194 public:
00195
00214 void OpenFile( const char * FilePath );
00215
00216 ALIAS_FUNCTION_1( OpenFile , aliasOpenFile , const char * )
00217
00218
00236 void OpenFile( const std::string & FilePath );
00237
00264 bool ReadRecord( CSVReadable * Readable , const std::size_t MODE = 0 );
00265
00284 void ReadHeader( const std::size_t MODE = 0 );
00285
00304 std::size_t GetHeaderItemsCount( void );
00305
00324 nitro::BinaryData & GetHeaderItem( std::size_t i );
00325
00356 template< class cont >bool ReadRecord( cont & Container , const std::size_t MODE = 0 );
00357
00380 template< class cont >void ReadAllRecords( cont & Container , const std::size_t MODE = 0 );
00381
00404 void AppendRecord( CSVWritable * Writable , const std::size_t MODE = 0 );
00405
00432 template< class cont >void AppendRecord( cont & Container , const std::size_t MODE = 0 );
00433
00460 template< class cont >void AppendAllRecords( cont & Container , const std::size_t MODE = 0 );
00461
00476 void CloseFile( void );
00477
00488 virtual ~CSVFile();
00489
00500 static void SetReadBufferSize( std::size_t ReadBufferSize );
00501
00502 private:
00503
00514 nitro::FileAbstraction FileStream;
00515
00526 std::vector< nitro::BinaryData >Header;
00527 };
00528
00529 template< class cont >bool CSVFile::ReadRecord( cont & Container , const std::size_t MODE )
00530 {
00531 try
00532 {
00533 class CSVRecordReader:public CSVReadable{
00534 cont * Container;
00535
00536 typedef typename cont::value_type FieldType;
00537 public:
00538 CSVRecordReader( cont * theContainer )
00539 {
00540 Container = theContainer;
00541 }
00542
00543 virtual void AddField( const char * Buffer , const std::size_t & BufferSize )
00544 {
00545 std::back_inserter( * Container ) = FieldType();
00546 Container->back().AppendData( Buffer , BufferSize );
00547 }
00548 };
00549
00550 CSVRecordReader Reader( & Container );
00551
00552 return( ReadRecord( ( CSVReadable * ) & Reader , MODE ) );
00553 }
00554 catch( nitro::exception e )
00555 {
00556 throw( nitro::exception( std::string( "CSVFile::ReadRecord( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) );
00557 }
00558 catch( ... )
00559 {
00560 throw( nitro::exception( std::string( "CSVFile::ReadRecord( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) );
00561 }
00562 }
00563
00564 template< class cont >void CSVFile::ReadAllRecords( cont & Container , const std::size_t MODE )
00565 {
00566 try
00567 {
00568 typedef typename cont::value_type FieldType;
00569
00570 FieldType CSVRecord;
00571
00572 bool EndOfFile( false );
00573
00574 do
00575 {
00576 EndOfFile = ReadRecord( CSVRecord , MODE );
00577
00578 * ( std::back_inserter( Container ) ) = CSVRecord;
00579
00580 CSVRecord.erase( CSVRecord.begin() , CSVRecord.end() );
00581 }
00582 while( EndOfFile == false );
00583 }
00584 catch( nitro::exception e )
00585 {
00586 throw( nitro::exception( std::string( "CSVFile::ReadAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) );
00587 }
00588 catch( ... )
00589 {
00590 throw( nitro::exception( std::string( "CSVFile::ReadAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) );
00591 }
00592 }
00593
00594 template< class cont >void CSVFile::AppendRecord( cont & Container , const std::size_t MODE )
00595 {
00596 try
00597 {
00598 class CSVRecordWriter:public CSVWritable{
00599 cont * Container;
00600 public:
00601 CSVRecordWriter( cont * theContainer )
00602 {
00603 Container = theContainer;
00604 }
00605
00606 virtual void GetField( const std::size_t & FieldCursor , const char * & Buffer , std::size_t & BufferSize , const std::size_t & MODE = 0 )
00607 {
00608 Buffer = ( * Container )[ FieldCursor ].GetBuffer();
00609 BufferSize = ( * Container )[ FieldCursor ].GetBufferLength();
00610 }
00611
00612 virtual std::size_t GetFieldCount( void )
00613 {
00614 return( Container->size() );
00615 }
00616 };
00617
00618 CSVRecordWriter Writer( & Container );
00619
00620 return( AppendRecord( ( CSVWritable * ) & Writer , MODE ) );
00621 }
00622 catch( nitro::exception e )
00623 {
00624 throw( nitro::exception( std::string( "CSVFile::AppendRecord( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) );
00625 }
00626 catch( ... )
00627 {
00628 throw( nitro::exception( std::string( "CSVFile::AppendRecord( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) );
00629 }
00630 }
00631
00632 template< class cont >void CSVFile::AppendAllRecords( cont & Container , const std::size_t MODE )
00633 {
00634 try
00635 {
00636 typedef typename cont::iterator IterType;
00637
00638 for( IterType i( Container.begin() ) ; i != Container.end() ; ++i )
00639 {
00640 AppendRecord( *i , MODE );
00641 }
00642 }
00643 catch( nitro::exception e )
00644 {
00645 throw( nitro::exception( std::string( "CSVFile::AppendAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::" ) + e.what() , e.code() ) );
00646 }
00647 catch( ... )
00648 {
00649 throw( nitro::exception( std::string( "CSVFile::AppendAllRecords( cont & Container , const std::size_t MODE /* = 0 */ )::An error occured" ) , 1 ) );
00650 }
00651 }
00652 }
00653
00654 #endif