00001 #ifndef __FILE_ABSTRACTION_CPP__
00002 #define __FILE_ABSTRACTION_CPP__
00003
00004 #include <fstream>
00005 #include <string>
00006
00007 #include <system/file_abstraction.h>
00008 #include <utilities/exception.h>
00009
00010 #ifdef NIX_PLATFORM
00011 #include <unistd.h>
00012 #endif
00013
00014 #include <sys/stat.h>
00015 #include <sys/types.h>
00016
00017 namespace nitro
00018 {
00019 FileAbstraction::FileAbstraction( void )
00020 {
00021 FileData = NULL;
00022 }
00023
00024 void FileAbstraction::Open( const char * FilePath , const std::size_t theMode )
00025 {
00026 try
00027 {
00028 Close();
00029
00030 Mode = theMode;
00031
00032 if( !( Mode & FA_FILE_READ ) && !( Mode & FA_FILE_WRITE ) )
00033 {
00034
00035
00036 throw( nitro::exception( "Neither reading nor writing modes specified - error" , 1 ) );
00037 }
00038
00039 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00040 FileData = ( void * ) new HANDLE();
00041
00042 unsigned int Access( 0 );
00043
00044 if( Mode & FA_FILE_READ ) Access |= GENERIC_READ;
00045 if( Mode & FA_FILE_WRITE ) Access |= GENERIC_WRITE;
00046 if( Mode & FA_FILE_APPEND ) Access |= GENERIC_WRITE;
00047
00048 unsigned int Creation( 0 );
00049
00050 if( Mode & FA_FILE_READ && Mode & FA_FILE_WRITE )
00051 {
00052 Creation |= OPEN_ALWAYS;
00053 }
00054 else
00055 {
00056 if( Mode & FA_FILE_READ ) Creation |= OPEN_EXISTING;
00057 if( Mode & FA_FILE_WRITE ) Creation |= OPEN_ALWAYS;
00058 }
00059
00060 if( Mode & FA_FILE_TRUNCATE )
00061 {
00062
00063 std::ifstream file( FilePath );
00064 if( file.good() )
00065 {
00066 Creation |= TRUNCATE_EXISTING;
00067 }
00068 }
00069
00070 * ( ( HANDLE * )FileData ) = CreateFile( FilePath , Access , ( DWORD )NULL , NULL , Creation , ( DWORD )NULL , NULL );
00071
00072 if( * ( ( HANDLE * )FileData ) == INVALID_HANDLE_VALUE )
00073 {
00074 throw( nitro::exception( std::string( "An error occured while opening file " ) + FilePath , 1 ) );
00075 }
00076 #endif
00077
00078 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00079
00080 std::string PlatformMode( "" );
00081
00082 if( Mode & FA_FILE_READ && Mode & FA_FILE_WRITE )
00083 {
00084
00085
00086 if( Mode & FA_FILE_TRUNCATE )
00087 {
00088 PlatformMode += "w+";
00089 }
00090 else
00091 {
00092 PlatformMode += "a+";
00093 }
00094 }
00095
00096 if( Mode & FA_FILE_READ && !( Mode & FA_FILE_WRITE ) )
00097 {
00098
00099
00100 PlatformMode += "r";
00101 }
00102
00103 if( !( Mode & FA_FILE_READ ) && Mode & FA_FILE_WRITE )
00104 {
00105
00106
00107 if( Mode & FA_FILE_TRUNCATE )
00108 {
00109 PlatformMode += "w";
00110 }
00111 else
00112 {
00113 std::ifstream file( FilePath );
00114
00115 if( file.good() )
00116 {
00117
00118
00119 PlatformMode += "r+";
00120 }
00121 else
00122 {
00123
00124
00125 PlatformMode += "w";
00126 }
00127 }
00128 }
00129
00130 PlatformMode += "b";
00131
00132 FileData = ( void * )fopen( FilePath , PlatformMode.c_str() );
00133
00134 if( FileData == NULL )
00135 {
00136 throw( nitro::exception( std::string( "An error occured while opening file " ) + FilePath , 1 ) );
00137 }
00138
00139 #endif
00140
00141
00142 if( Mode & FA_FILE_APPEND )
00143 {
00144 Seek( 0 , FA_FILE_END );
00145 }
00146 else
00147 {
00148 Seek( 0 , FA_FILE_BEGIN );
00149 }
00150 }
00151 catch( nitro::exception e )
00152 {
00153 throw( nitro::exception( std::string( "FileAbstraction::Open( const char * FilePath , const std::size_t theMode )::" ) + e.what() , e.code() ) );
00154 }
00155 catch( ... )
00156 {
00157 throw( nitro::exception( std::string( "FileAbstraction::Open( const char * FilePath , const std::size_t theMode )::An error occured" ) , 0 ) );
00158 }
00159 }
00160
00161 void FileAbstraction::Seek( std::size_t Offset , std::size_t theMode )
00162 {
00163 try
00164 {
00165 if( FileData == NULL )
00166 {
00167 throw( nitro::exception( std::string( "File was not opened" ) , 1 ) );
00168 }
00169
00170 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00171 switch( theMode )
00172 {
00173 case( FA_FILE_BEGIN ):
00174 SetFilePointer( * ( ( HANDLE * )FileData ) , ( LONG )Offset , NULL , FILE_BEGIN );
00175 break;
00176
00177 case( FA_FILE_CURRENT ):
00178 SetFilePointer( * ( ( HANDLE * )FileData ) , ( LONG )Offset , NULL , FILE_CURRENT );
00179 break;
00180
00181 case( FA_FILE_END ):
00182 SetFilePointer( * ( ( HANDLE * )FileData ) , ( LONG )Offset , NULL , FILE_END );
00183 break;
00184 }
00185 #endif
00186
00187 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00188 switch( theMode )
00189 {
00190 case( FA_FILE_BEGIN ):
00191 fseek( ( FILE * )FileData , Offset , SEEK_SET );
00192 break;
00193
00194 case( FA_FILE_CURRENT ):
00195 fseek( ( FILE * )FileData , Offset , SEEK_CUR );
00196 break;
00197
00198 case( FA_FILE_END ):
00199 fseek( ( FILE * )FileData , Offset , SEEK_END );
00200 break;
00201 }
00202 #endif
00203 }
00204 catch( nitro::exception e )
00205 {
00206 throw( nitro::exception( std::string( "FileAbstraction::Seek( std::size_t Offset , std::size_t theMode )::" ) + e.what() , e.code() ) );
00207 }
00208 catch( ... )
00209 {
00210 throw( nitro::exception( std::string( "FileAbstraction::Seek( std::size_t Offset , std::size_t theMode )::An error occured" ) , 0 ) );
00211 }
00212 }
00213
00214 std::size_t FileAbstraction::Tell( void )
00215 {
00216 try
00217 {
00218 if( FileData == NULL )
00219 {
00220 throw( nitro::exception( std::string( "File was not opened" ) , 1 ) );
00221 }
00222 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00223 return( ( std::size_t )SetFilePointer( * ( ( HANDLE * )FileData ) , ( LONG )NULL , NULL , FILE_CURRENT ) );
00224 #endif
00225
00226 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00227 return( ( std::size_t )ftell( ( FILE * )FileData ) );
00228 #endif
00229 }
00230 catch( nitro::exception e )
00231 {
00232 throw( nitro::exception( std::string( "FileAbstraction::Tell( void )::" ) + e.what() , e.code() ) );
00233 }
00234 catch( ... )
00235 {
00236 throw( nitro::exception( std::string( "FileAbstraction::Tell( void )::An error occured" ) , 0 ) );
00237 }
00238
00239 return( 0 );
00240 }
00241
00242 void FileAbstraction::Write( const char * Buffer , std::size_t BufferLength )
00243 {
00244 try
00245 {
00246 if( FileData == NULL )
00247 {
00248 throw( nitro::exception( std::string( "File was not opened" ) , 1 ) );
00249 }
00250 if( ( Mode & FA_FILE_WRITE ) == 0 )
00251 {
00252 throw( nitro::exception( "File was not opened for writing" , 1 ) );
00253 }
00254
00255 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00256 DWORD WriteBytes;
00257
00258 WriteFile( * ( ( HANDLE * )FileData ) , Buffer , ( LONG )BufferLength , & WriteBytes , NULL );
00259 #endif
00260
00261 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00262 fwrite( Buffer , BufferLength , 1 , ( FILE * )FileData );
00263 #endif
00264 }
00265 catch( nitro::exception e )
00266 {
00267 throw( nitro::exception( std::string( "FileAbstraction::Write( const char * Buffer , const std::size_t BufferLength )::" ) + e.what() , e.code() ) );
00268 }
00269 catch( ... )
00270 {
00271 throw( nitro::exception( std::string( "FileAbstraction::Write( const char * Buffer , const std::size_t BufferLength )::An error occured" ) , 0 ) );
00272 }
00273 }
00274
00275 std::size_t FileAbstraction::Read( char * Buffer , std::size_t BufferLength )
00276 {
00277 try
00278 {
00279 if( FileData == NULL )
00280 {
00281 throw( nitro::exception( std::string( "File was not opened" ) , 1 ) );
00282 }
00283 if( ( Mode & FA_FILE_READ ) == 0 )
00284 {
00285 throw( nitro::exception( "File was not opened for reading" , 1 ) );
00286 }
00287
00288 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00289 DWORD ReadBytes( 0 );
00290
00291 if( !ReadFile( * ( ( HANDLE * )FileData ) , ( LPVOID )Buffer , ( LONG )BufferLength , & ReadBytes , NULL ) )
00292 {
00293 throw( nitro::exception( "FileAbstraction::Read( char * Buffer , const std::size_t BufferLength )::An error occured while reading data from file" , 1 ) );
00294 }
00295
00296 return( ( std::size_t )ReadBytes );
00297 #endif
00298
00299 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00300 return( fread( Buffer , 1 , BufferLength , ( FILE * )FileData ) );
00301 #endif
00302 }
00303 catch( nitro::exception e )
00304 {
00305 throw( nitro::exception( std::string( "FileAbstraction::Read( char * Buffer , const std::size_t BufferLength )::" ) + e.what() , e.code() ) );
00306 }
00307 catch( ... )
00308 {
00309 throw( nitro::exception( std::string( "FileAbstraction::Read( char * Buffer , const std::size_t BufferLength )::An error occured" ) , 0 ) );
00310 }
00311
00312 return( 0 );
00313 }
00314
00315 void FileAbstraction::Close( void )
00316 {
00317 try
00318 {
00319 if( FileData )
00320 {
00321 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00322 CloseHandle( * ( ( HANDLE * )FileData ) );
00323
00324 delete ( HANDLE * ) FileData;
00325 #endif
00326
00327 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00328 fclose( ( FILE * )FileData );
00329 #endif
00330
00331 FileData = NULL;
00332 }
00333 }
00334 catch( nitro::exception e )
00335 {
00336 throw( nitro::exception( std::string( "FileAbstraction::Close( void )::" ) + e.what() , e.code() ) );
00337 }
00338 catch( ... )
00339 {
00340 throw( nitro::exception( std::string( "FileAbstraction::Close( void )::An error occured" ) , 0 ) );
00341 }
00342 }
00343
00344 FileAbstraction::~FileAbstraction()
00345 {
00346 try
00347 {
00348 Close();
00349 }
00350 catch( ... )
00351 {
00352 }
00353 }
00354
00355 void FileAbstraction::DeleteFile( const char * FilePath )
00356 {
00357 try
00358 {
00359 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00360 if( ::DeleteFileA( FilePath ) == 0 )
00361 {
00362 throw( nitro::exception( std::string( "An error occured while deleting file " ) + FilePath , 0 ) );
00363 }
00364 #endif
00365 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00366 if( unlink( FilePath ) != 0 )
00367 {
00368 throw( nitro::exception( std::string( "An error occured while deleting file " ) + FilePath , 0 ) );
00369 }
00370 #endif
00371 }
00372 catch( nitro::exception e )
00373 {
00374 throw( nitro::exception( std::string( "FileAbstraction::DeleteFile( const char * FilePath )::" ) + e.what() , e.code() ) );
00375 }
00376 catch( ... )
00377 {
00378 throw( nitro::exception( std::string( "FileAbstraction::DeleteFile( const char * FilePath )::An error occured" ) , 0 ) );
00379 }
00380 }
00381
00382 void FileAbstraction::RenameFile( const char * FilePathFrom , const char * FilePathTo )
00383 {
00384 try
00385 {
00386 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00387 if( MoveFile( FilePathFrom , FilePathTo ) == 0 )
00388 {
00389 throw( nitro::exception( std::string( "An error cccured while renaming file " ) + FilePathFrom , 0 ) );
00390 }
00391 #endif
00392 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00393 if( rename( FilePathFrom , FilePathTo ) != 0 )
00394 {
00395 throw( nitro::exception( std::string( "An error cccured while renaming file " ) + FilePathFrom , 0 ) );
00396 }
00397 #endif
00398 }
00399 catch( nitro::exception e )
00400 {
00401 throw( nitro::exception( std::string( "FileAbstraction::RenameFile( const char * FilePathFrom , const char * FilePathTo )::" ) + e.what() , e.code() ) );
00402 }
00403 catch( ... )
00404 {
00405 throw( nitro::exception( std::string( "FileAbstraction::RenameFile( const char * FilePathFrom , const char * FilePathTo )::An error occured" ) , 0 ) );
00406 }
00407 }
00408
00409 void FileAbstraction::Open( const std::string & FilePath , const std::size_t theMode )
00410 {
00411 try
00412 {
00413 Open( FilePath.c_str() , theMode );
00414 }
00415 catch( nitro::exception e )
00416 {
00417 throw( nitro::exception( std::string( "FileAbstraction::Open( const std::string & FilePath , const std::size_t theMode )::" ) + e.what() , e.code() ) );
00418 }
00419 catch( ... )
00420 {
00421 throw( nitro::exception( std::string( "FileAbstraction::Open( const std::string & FilePath , const std::size_t theMode )::An error occured" ) , 0 ) );
00422 }
00423 }
00424
00425 void FileAbstraction::DeleteFile( const std::string & FilePath )
00426 {
00427 try
00428 {
00429 DeleteFile( FilePath.c_str() );
00430 }
00431 catch( nitro::exception e )
00432 {
00433 throw( nitro::exception( std::string( "FileAbstraction::DeleteFile( const std::string & FilePath )::" ) + e.what() , e.code() ) );
00434 }
00435 catch( ... )
00436 {
00437 throw( nitro::exception( std::string( "FileAbstraction::DeleteFile( const std::string & FilePath )::An error occured" ) , 0 ) );
00438 }
00439 }
00440
00441 void FileAbstraction::RenameFile( const std::string & FilePathFrom , const std::string & FilePathTo )
00442 {
00443 try
00444 {
00445 RenameFile( FilePathFrom.c_str() , FilePathTo.c_str() );
00446 }
00447 catch( nitro::exception e )
00448 {
00449 throw( nitro::exception( std::string( "FileAbstraction::RenameFile( const std::string & FilePathFrom , const std::string & FilePathTo )::" ) + e.what() , e.code() ) );
00450 }
00451 catch( ... )
00452 {
00453 throw( nitro::exception( std::string( "FileAbstraction::RenameFile( const std::string & FilePathFrom , const std::string & FilePathTo )::An error occured" ) , 0 ) );
00454 }
00455 }
00456
00457 int FileAbstraction::GetOwner( const std::string & Path )
00458 {
00459 try
00460 {
00461 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00462 struct _stat s;
00463 int Result( _stat( Path.c_str() , & s ) );
00464 #endif
00465 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00466 struct stat s;
00467 int Result( stat( Path.c_str() , & s ) );
00468 #endif
00469
00470 if( Result == 0 )
00471 {
00472 return( s.st_uid );
00473 }
00474 else
00475 {
00476 throw( nitro::exception( "Path does not exists" , 0 ) );
00477 }
00478 }
00479 catch( nitro::exception e )
00480 {
00481 throw( nitro::exception( std::string( "FileAbstraction::GetOwner( const std::string & Path )::" ) + e.what() , e.code() ) );
00482 }
00483 catch( ... )
00484 {
00485 throw( nitro::exception( std::string( "FileAbstraction::GetOwner( const std::string & Path )::An error occured" ) , 0 ) );
00486 }
00487 }
00488
00489 int FileAbstraction::GetGroup( const std::string & Path )
00490 {
00491 try
00492 {
00493 #if defined( WIN32_PLATFORM ) || defined( MINGW_PLATFORM )
00494 struct _stat s;
00495 int Result( _stat( Path.c_str() , & s ) );
00496 #endif
00497 #if defined( NIX_PLATFORM ) || defined( CYGWIN_PLATFORM )
00498 struct stat s;
00499 int Result( stat( Path.c_str() , & s ) );
00500 #endif
00501
00502 if( Result == 0 )
00503 {
00504 return( s.st_gid );
00505 }
00506 else
00507 {
00508 throw( nitro::exception( "Path does not exists" , 0 ) );
00509 }
00510 }
00511 catch( nitro::exception e )
00512 {
00513 throw( nitro::exception( std::string( "FileAbstraction::GetGroup( const std::string & Path )::" ) + e.what() , e.code() ) );
00514 }
00515 catch( ... )
00516 {
00517 throw( nitro::exception( std::string( "FileAbstraction::GetGroup( const std::string & Path )::An error occured" ) , 0 ) );
00518 }
00519 }
00520
00521
00522
00523
00524 BEGIN_TESTING_SECTION()
00525
00526 ENABLE_CLASS_TESTING( FileAbstraction )
00527
00528 CLASS_MEMBER_FUNCTION_TESTING_2( FileAbstraction , aliasOpen , tstOpen , const char * , std::size_t , void , NO_RET )
00529 CLASS_MEMBER_FUNCTION_TESTING_0( FileAbstraction , Close , tstClose , void , NO_RET )
00530 CLASS_MEMBER_FUNCTION_TESTING_2( FileAbstraction , Seek , tstSeek , unsigned int , unsigned int , void , NO_RET )
00531 CLASS_MEMBER_FUNCTION_TESTING_0( FileAbstraction , Tell , tstTell , std::size_t , std::size_t )
00532 CLASS_MEMBER_FUNCTION_TESTING_2( FileAbstraction , Write , tstWrite , const char * , std::size_t , void , NO_RET )
00533 CLASS_MEMBER_FUNCTION_TESTING_2( FileAbstraction , Read , tstRead , char * , std::size_t , std::size_t , std::size_t )
00534
00535
00536
00537 FUNCTION_TESTING_2( aliasRenameFile , tstRenameFile , const char * , const char * , void , NO_RET )
00538 FUNCTION_TESTING_1( aliasDeleteFile , tstDeleteFile , const char * , void , NO_RET )
00539
00540 END_TESTING_SECTION()
00541 }
00542
00543 #endif