Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00025
00026 #ifndef HEADER_VERSION_HPP
00027 #define HEADER_VERSION_HPP
00028
00029 #include "../my_config.h"
00030 #include "infinint.hpp"
00031 #include "generic_file.hpp"
00032 #include "tools.hpp"
00033 #include "archive_version.hpp"
00034
00035 namespace libdar
00036 {
00037
00040
00041 const U_I VERSION_FLAG_SAVED_EA_ROOT = 0x80;
00042 const U_I VERSION_FLAG_SAVED_EA_USER = 0x40;
00043 const U_I VERSION_FLAG_SCRAMBLED = 0x20;
00044 const U_I VERSION_FLAG_SEQUENCE_MARK = 0x10;
00045 const U_I VERSION_FLAG_INITIAL_OFFSET = 0x08;
00046 const U_I VERSION_FLAG_HAS_AN_EXTENDED_SIZE = 0x01;
00047 const U_I VERSION_SIZE = 3;
00048 const U_I HEADER_CRC_SIZE = 2;
00049
00050
00052 struct header_version
00053 {
00054 archive_version edition;
00055 char algo_zip;
00056 std::string cmd_line;
00057 unsigned char flag;
00058 infinint initial_offset;
00059
00060 header_version()
00061 {
00062 algo_zip = ' ';
00063 cmd_line = "";
00064 flag = 0;
00065 initial_offset = 0;
00066 }
00067
00068 void read(generic_file &f)
00069 {
00070 crc *ctrl = NULL;
00071
00072 f.reset_crc(HEADER_CRC_SIZE);
00073 edition.read(f);
00074 f.read(&algo_zip, sizeof(algo_zip));
00075 tools_read_string(f, cmd_line);
00076 if(edition > 1)
00077 f.read((char *)&flag, 1);
00078 else
00079 flag = 0;
00080 if((flag & VERSION_FLAG_INITIAL_OFFSET) != 0)
00081 initial_offset.read(f);
00082 else
00083 initial_offset = 0;
00084
00085 ctrl = f.get_crc();
00086 if(ctrl == NULL)
00087 throw SRC_BUG;
00088 try
00089 {
00090 if((edition == empty_archive_version()))
00091 throw Erange("header_version::read", gettext("Consistency check failed for archive header"));
00092 if(edition > 7)
00093 {
00094 crc *coh = create_crc_from_file(f);
00095
00096 if(coh == NULL)
00097 throw SRC_BUG;
00098 try
00099 {
00100 if(typeid(*coh) != typeid(*ctrl))
00101 {
00102 if(coh->get_size() != ctrl->get_size())
00103 throw SRC_BUG;
00104 else
00105 throw SRC_BUG;
00106 }
00107 if(*coh != *ctrl)
00108 throw Erange("header_version::read", gettext("Consistency check failed for archive header"));
00109 }
00110 catch(...)
00111 {
00112 if(coh != NULL)
00113 delete coh;
00114 throw;
00115 }
00116 if(coh != NULL)
00117 delete coh;
00118 }
00119 if(initial_offset == 0)
00120 initial_offset = f.get_position();
00121 }
00122 catch(...)
00123 {
00124 if(ctrl != NULL)
00125 delete ctrl;
00126 throw;
00127 }
00128
00129 if(ctrl != NULL)
00130 delete ctrl;
00131 };
00132
00133 void write(generic_file &f)
00134 {
00135 crc *ctrl = NULL;
00136
00137
00138
00139 if(initial_offset != 0)
00140 flag |= VERSION_FLAG_INITIAL_OFFSET;
00141 else
00142 flag &= ~VERSION_FLAG_INITIAL_OFFSET;
00143
00144
00145
00146 f.reset_crc(HEADER_CRC_SIZE);
00147 edition.dump(f);
00148 f.write(&algo_zip, sizeof(algo_zip));
00149 tools_write_string(f, cmd_line);
00150 f.write((char *)&flag, 1);
00151 if(initial_offset != 0)
00152 initial_offset.dump(f);
00153
00154 ctrl = f.get_crc();
00155 if(ctrl == NULL)
00156 throw SRC_BUG;
00157 try
00158 {
00159 ctrl->dump(f);
00160 }
00161 catch(...)
00162 {
00163 if(ctrl != NULL)
00164 delete ctrl;
00165 throw;
00166 }
00167 if(ctrl != NULL)
00168 delete ctrl;
00169 };
00170 };
00171
00172 }
00173
00174 #endif