00001 #ifndef __TAR_ABSTRACTION_CPP__
00002 #define __TAR_ABSTRACTION_CPP__
00003
00004 #include <system/tar_abstraction.h>
00005
00006 namespace nitro
00007 {
00008 std::size_t TARFileHeader::GetCheckSum( const TARFileHeader & Header )
00009 {
00010 try
00011 {
00012 TARFileHeader LocalHeader;
00013 memcpy( ( void * ) & LocalHeader , ( void * ) & Header , sizeof( TARFileHeader ) );
00014 memset( LocalHeader.CheckSum , ' ' , 8 );
00015
00016 std::size_t CheckSum( 0 );
00017 for( std::size_t i( 0 ) ; i < sizeof( TARFileHeader ) ; i++ )
00018 {
00019 CheckSum += ( ( unsigned char * ) & LocalHeader )[ i ];
00020 }
00021
00022 return( CheckSum );
00023 }
00024 catch( nitro::exception e )
00025 {
00026 throw( nitro::exception( std::string( "TARFileHeader::GetCheckSum( const TARFileHeader & Header )::" ) + e.what() , e.code() ) );
00027 }
00028 catch( ... )
00029 {
00030 throw( nitro::exception( std::string( "TARFileHeader::GetCheckSum( const TARFileHeader & Header )::An error occured while opening file" ) , 1 ) );
00031 }
00032 }
00033
00034 void TARFileHeader::SetCheckSum( TARFileHeader & Header )
00035 {
00036 try
00037 {
00038 std::size_t CheckSum( GetCheckSum( Header ) );
00039
00040 memset( Header.CheckSum , 0 , 8 );
00041
00042 sprintf( Header.CheckSum , "%08o" , CheckSum );
00043 }
00044 catch( nitro::exception e )
00045 {
00046 throw( nitro::exception( std::string( "TARFileHeader::SetCheckSum( TARFileHeader & Header )::" ) + e.what() , e.code() ) );
00047 }
00048 catch( ... )
00049 {
00050 throw( nitro::exception( std::string( "TARFileHeader::SetCheckSum( TARFileHeader & Header )::An error occured while opening file" ) , 1 ) );
00051 }
00052 }
00053
00054 UnTARAbstraction::UnTARAbstraction( void )
00055 {
00056 try
00057 {
00058 }
00059 catch( nitro::exception e )
00060 {
00061 throw( nitro::exception( std::string( "UnTARAbstraction::UnTARAbstraction( void )::" ) + e.what() , e.code() ) );
00062 }
00063 catch( ... )
00064 {
00065 throw( nitro::exception( std::string( "UnTARAbstraction::UnTARAbstraction( void )::An error occured while opening file" ) , 1 ) );
00066 }
00067 }
00068
00069 UnTARAbstraction::UnTARAbstraction( const std::string & FilePath )
00070 {
00071 try
00072 {
00073 OpenFile( FilePath );
00074 }
00075 catch( nitro::exception e )
00076 {
00077 throw( nitro::exception( std::string( "UnTARAbstraction::UnTARAbstraction( void )::" ) + e.what() , e.code() ) );
00078 }
00079 catch( ... )
00080 {
00081 throw( nitro::exception( std::string( "UnTARAbstraction::UnTARAbstraction( void )::An error occured while opening file" ) , 1 ) );
00082 }
00083 }
00084
00085 void UnTARAbstraction::OpenFile( const std::string & FilePath )
00086 {
00087 try
00088 {
00089 LoadedFile.Open( FilePath , nitro::FA_FILE_BINARY | nitro::FA_FILE_READ | nitro::FA_FILE_WRITE );
00090
00091 GotoFirstFile();
00092 }
00093 catch( nitro::exception e )
00094 {
00095 throw( nitro::exception( std::string( "UnTARAbstraction::OpenFile( const std::string & FilePath )::" ) + e.what() , e.code() ) );
00096 }
00097 catch( ... )
00098 {
00099 throw( nitro::exception( std::string( "UnTARAbstraction::OpenFile( const std::string & FilePath )::An error occured while opening file" ) , 1 ) );
00100 }
00101 }
00102
00103 std::size_t UnTARAbstraction::GetCountOfFiles( void )
00104 {
00105 try
00106 {
00107 std::size_t CurrentCursor( Cursor );
00108 std::size_t CurrentFilePosition( LoadedFile.Tell() );
00109 TARFileHeader CurrentHeader( Header );
00110
00111 GotoFirstFile();
00112 std::size_t Counter( 0 );
00113 for( ; std::string( "" ) != Header.FileName ; Counter++ )
00114 {
00115 int FileSize( nitro::Converters::atoi( Header.FileSize , nitro::OCTAL ) );
00116 if( FileSize )
00117 {
00118 int Offset( FileSize / 512 * 512 + ( FileSize % 512 ? 512 : 0 ) );
00119 LoadedFile.Seek( Offset , nitro::FA_FILE_CURRENT );
00120 }
00121 ReadHeader();
00122 }
00123
00124 Cursor = CurrentCursor;
00125 Header = CurrentHeader;
00126 LoadedFile.Seek( CurrentFilePosition , nitro::FA_FILE_BEGIN );
00127 return( Counter );
00128 }
00129 catch( nitro::exception e )
00130 {
00131 throw( nitro::exception( std::string( "UnTARAbstraction::GetCountOfFiles( void )::" ) + e.what() , e.code() ) );
00132 }
00133 catch( ... )
00134 {
00135 throw( nitro::exception( std::string( "UnTARAbstraction::GetCountOfFiles( void )::An error occured while getting count of files" ) , 1 ) );
00136 }
00137 }
00138
00139 void UnTARAbstraction::ExtractFile( const std::size_t & FileCursor , const std::string & Folder , bool IgnoreFilePath )
00140 {
00141 try
00142 {
00143 SetReadCursor( FileCursor );
00144
00145 if( '0' == Header.LinkType )
00146 {
00147 std::string FilePath( "" );
00148 if( IgnoreFilePath )
00149 {
00150 FilePath = nitro::FSPath::AddEndSlash( std::string( Folder ) ) + nitro::FSPath::ExtractFileName( std::string( Header.FileName ) );
00151 }
00152 else
00153 {
00154 FilePath = nitro::FSPath::AddEndSlash( std::string( Folder ) ) + std::string( Header.FileName );
00155 }
00156
00157 nitro::BinaryData Storage;
00158 ExtractFile( FileCursor , Storage );
00159 nitro::File::SaveBinDataToFile( Storage , FilePath );
00160 }
00161 }
00162 catch( nitro::exception e )
00163 {
00164 throw( nitro::exception( std::string( "UnTARAbstraction::ExtractFile( const std::size_t & FileCursor , const std::string & Folder , bool IgnoreFilePath /* = true */ )::" ) + e.what() , e.code() ) );
00165 }
00166 catch( ... )
00167 {
00168 throw( nitro::exception( std::string( "UnTARAbstraction::ExtractFile( const std::size_t & FileCursor , const std::string & Folder , bool IgnoreFilePath /* = true */ )::An error occured while extracting file" ) , 1 ) );
00169 }
00170 }
00171
00172 void UnTARAbstraction::CloseFile( void )
00173 {
00174 try
00175 {
00176 LoadedFile.Close();
00177 }
00178 catch( nitro::exception e )
00179 {
00180 throw( nitro::exception( std::string( "UnTARAbstraction::CloseFile( void )::" ) + e.what() , e.code() ) );
00181 }
00182 catch( ... )
00183 {
00184 throw( nitro::exception( std::string( "UnTARAbstraction::CloseFile( void )::An error occured while closing file" ) , 1 ) );
00185 }
00186 }
00187
00188 UnTARAbstraction::~UnTARAbstraction()
00189 {
00190 try
00191 {
00192 CloseFile();
00193 }
00194 catch( nitro::exception e )
00195 {
00196 }
00197 catch( ... )
00198 {
00199 }
00200 }
00201
00202 void UnTARAbstraction::GotoFirstFile( void )
00203 {
00204 try
00205 {
00206 LoadedFile.Seek( 0 , nitro::FA_FILE_BEGIN );
00207
00208 Cursor = 0;
00209
00210 ReadHeader();
00211 }
00212 catch( nitro::exception e )
00213 {
00214 throw( nitro::exception( std::string( "UnTARAbstraction::GotoFirstFile( void )::" ) + e.what() , e.code() ) );
00215 }
00216 catch( ... )
00217 {
00218 throw( nitro::exception( std::string( "UnTARAbstraction::GotoFirstFile( void )::An error occured while moving cursor to the begin" ) , 1 ) );
00219 }
00220 }
00221
00222 void UnTARAbstraction::ReadHeader( void )
00223 {
00224 try
00225 {
00226 LoadedFile.Read( ( char * ) & Header , sizeof( Header ) );
00227 }
00228 catch( nitro::exception e )
00229 {
00230 throw( nitro::exception( std::string( "UnTARAbstraction::ReadHeader( void )::" ) + e.what() , e.code() ) );
00231 }
00232 catch( ... )
00233 {
00234 throw( nitro::exception( std::string( "UnTARAbstraction::ReadHeader( void )::An error occured while reading header" ) , 1 ) );
00235 }
00236 }
00237
00238 void UnTARAbstraction::SetReadCursor( const std::size_t & ReadCursor )
00239 {
00240 try
00241 {
00242
00243 if( Cursor > ReadCursor )
00244 {
00245 GotoFirstFile();
00246 }
00247
00248
00249 if( Cursor != ReadCursor )
00250 {
00251 for( std::size_t i( 0 ) ; i < ReadCursor - Cursor ; i++ )
00252 {
00253 int FileSize( nitro::Converters::atoi( Header.FileSize , nitro::OCTAL ) );
00254 int Offset( FileSize / 512 * 512 + ( FileSize % 512 ? 512 : 0 ) );
00255 if( Offset )
00256 {
00257 LoadedFile.Seek( Offset , nitro::FA_FILE_CURRENT );
00258 }
00259 ReadHeader();
00260 }
00261 Cursor = ReadCursor;
00262 }
00263 }
00264 catch( nitro::exception e )
00265 {
00266 throw( nitro::exception( std::string( "UnTARAbstraction::SetReadCursor( const std::size_t & ReadCursor )::" ) + e.what() , e.code() ) );
00267 }
00268 catch( ... )
00269 {
00270 throw( nitro::exception( std::string( "UnTARAbstraction::SetReadCursor( const std::size_t & ReadCursor )::An error occured while setting cursor" ) , 1 ) );
00271 }
00272 }
00273 }
00274
00275 #endif