00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __PARCMDLINE_H__
00027 #define __PARCMDLINE_H__
00028
00029
00030 #ifdef WIN32
00031
00032 #define WIN32_LEAN_AND_MEAN
00033 #include
00034
00035
00036 #include
00037 #include
00038 #include
00039 #include
00040 #include
00041 #include
00042 #include
00043 #include
00044 #include
00045
00046 #define snprintf _snprintf
00047
00048 #define __LITTLE_ENDIAN 1234
00049 #define __BIG_ENDIAN 4321
00050 #define __PDP_ENDIAN 3412
00051
00052 #define __BYTE_ORDER __LITTLE_ENDIAN
00053
00054 typedef unsigned char u8;
00055 typedef unsigned short u16;
00056 typedef unsigned long u32;
00057 typedef unsigned __int64 u64;
00058
00059 #ifndef _SIZE_T_DEFINED
00060 # ifdef _WIN64
00061 typedef unsigned __int64 size_t;
00062 # else
00063 typedef unsigned int size_t;
00064 # endif
00065 # define _SIZE_T_DEFINED
00066 #endif
00067
00068
00069 #else // WIN32
00070 #ifdef HAVE_CONFIG_H
00071
00072 #include
00073
00074 #ifdef HAVE_STDLIB_H
00075 # include
00076 #endif
00077
00078 #ifdef HAVE_STDIO_H
00079 # include
00080 #endif
00081
00082 #if HAVE_DIRENT_H
00083 # include
00084 # define NAMELEN(dirent) strlen((dirent)->d_name)
00085 #else
00086 # define dirent direct
00087 # define NAMELEN(dirent) (dirent)->d_namelen
00088 # if HAVE_SYS_NDIR_H
00089 # include
00090 # endif
00091 # if HAVE_SYS_DIR_H
00092 # include
00093 # endif
00094 # if HAVE_NDIR_H
00095 # include
00096 # endif
00097 #endif
00098
00099 #if STDC_HEADERS
00100 # include
00101 #else
00102 # if !HAVE_STRCHR
00103 # define strchr index
00104 # define strrchr rindex
00105 # endif
00106 char *strchr(), *strrchr();
00107 # if !HAVE_MEMCPY
00108 # define memcpy(d, s, n) bcopy((s), (d), (n))
00109 # define memove(d, s, n) bcopy((s), (d), (n))
00110 # endif
00111 #endif
00112
00113 #if HAVE_MEMORY_H
00114 # include
00115 #endif
00116
00117 #ifndef __WIN32__
00118 # define stricmp strcasecmp
00119 #endif
00120
00121 #if HAVE_INTTYPES_H
00122 # include
00123 #endif
00124
00125 #if HAVE_STDINT_H
00126 # include
00127 typedef uint8_t u8;
00128 typedef uint16_t u16;
00129 typedef uint32_t u32;
00130 typedef uint64_t u64;
00131 #else
00132 typedef unsigned char u8;
00133 typedef unsigned short u16;
00134 typedef unsigned int u32;
00135 typedef unsigned long long u64;
00136 #endif
00137
00138 #if HAVE_SYS_STAT_H
00139 # include
00140 #endif
00141
00142 #if HAVE_SYS_TYPES_H
00143 # include
00144 #endif
00145
00146 #if HAVE_UNISTD_H
00147 # include
00148 #endif
00149
00150 #define _MAX_PATH 255
00151
00152 #if HAVE_ENDIAN_H
00153 # include
00154 # ifndef __LITTLE_ENDIAN
00155 # ifdef _LITTLE_ENDIAN
00156 # define __LITTLE_ENDIAN _LITTLE_ENDIAN
00157 # define __LITTLE_ENDIAN _LITTLE_ENDIAN
00158 # define __BIG_ENDIAN _BIG_ENDIAN
00159 # define __PDP_ENDIAN _PDP_ENDIAN
00160 # else
00161 # error does not define __LITTLE_ENDIAN etc.
00162 # endif
00163 # endif
00164 #else
00165 # define __LITTLE_ENDIAN 1234
00166 # define __BIG_ENDIAN 4321
00167 # define __PDP_ENDIAN 3412
00168 # if WORDS_BIGENDIAN
00169 # define __BYTE_ORDER __BIG_ENDIAN
00170 # else
00171 # define __BYTE_ORDER __LITTLE_ENDIAN
00172 # endif
00173 #endif
00174
00175 #else // HAVE_CONFIG_H
00176
00177 #include
00178 #include
00179 #include
00180 #include
00181 #include
00182 #include
00183 #include
00184 #include
00185 #include
00186 #include
00187
00188 #include
00189
00190 #define _MAX_PATH 255
00191 #define stricmp strcasecmp
00192 #define _stat stat
00193
00194 typedef unsigned char u8;
00195 typedef unsigned short u16;
00196 typedef unsigned int u32;
00197 typedef unsigned long long u64;
00198
00199 #endif
00200 #endif
00201
00202 #ifdef WIN32
00203 #define PATHSEP "\\"
00204 #define ALTPATHSEP "/"
00205
00206 #ifdef UNICODE
00207 #define stat _wstati64
00208 #define struct_stat struct _stati64
00209
00210 #define utf8_string_to_native_char_array(x) ::UTF8_to_UTF16(x).c_str()
00211 #define utf8_char_array_to_native_char_array(x) ::UTF8_to_UTF16(x, strlen(x)).c_str()
00212 #define utf8_string_to_cout_parameter(x) ::UTF8_string_to_cout_string(x)
00213 #define native_char_array_to_utf8_string(x) ::UTF16_to_UTF8(x)
00214 #define native_char_array_to_utf8_char_array(x) ::UTF16_to_UTF8(x).c_str()
00215 #else
00216 #define stat _stati64
00217 #define struct_stat struct _stati64
00218
00219 #define utf8_string_to_native_char_array(x) x.c_str()
00220 #define utf8_char_array_to_native_char_array(x) x
00221 #define utf8_string_to_cout_parameter(x) x
00222 #define native_char_array_to_utf8_string(x) string(x)
00223 #define native_char_array_to_utf8_char_array(x) x
00224 #endif
00225 #else
00226 #define PATHSEP "/"
00227 #define ALTPATHSEP "\\"
00228
00229 #define struct_stat struct stat
00230
00231 #define utf8_string_to_native_char_array(x) x.c_str()
00232 #define utf8_char_array_to_native_char_array(x) x
00233 #define utf8_string_to_cout_parameter(x) x
00234 #define native_char_array_to_utf8_string(x) string(x)
00235 #define native_char_array_to_utf8_char_array(x) x
00236
00237 typedef char TCHAR;
00238 #define _tcschr strchr
00239 #endif
00240
00241
00242 typedef enum Result
00243 {
00244 eSuccess = 0,
00245
00246 eRepairPossible = 1,
00247
00248
00249
00250 eRepairNotPossible = 2,
00251
00252
00253
00254 eInvalidCommandLineArguments = 3,
00255
00256
00257 eInsufficientCriticalData = 4,
00258
00259
00260
00261 eRepairFailed = 5,
00262
00263
00264
00265 eFileIOError = 6,
00266 eLogicError = 7,
00267 eMemoryError = 8,
00268
00269 } Result;
00270
00271 #define LONGMULTIPLY
00272
00273
00274 #include
00275 #include
00276 #include
00277 #include
00278 #include
00279
00280 #include
00281 #include
00282 #include
00283
00284 #include
00285
00286 #include
00287
00288 using namespace std;
00289
00290 #ifdef WIN32
00291 extern wstring UTF8_to_UTF16(const char* utf8_str, size_t utf8_length);
00292 extern wstring UTF8_to_UTF16(const string& utf8);
00293 extern string UTF8_string_to_cout_string(const string& utf8);
00294 extern string UTF16_to_UTF8(const wchar_t* utf16);
00295 #endif
00296
00297 #ifdef offsetof
00298 #undef offsetof
00299 #endif
00300 #define offsetof(TYPE, MEMBER) ((size_t) ((char*)(&((TYPE *)1)->MEMBER) - (char*)1))
00301
00302 #if WANT_CONCURRENT
00303 #include "tbb/task_scheduler_init.h"
00304 #include "tbb/atomic.h"
00305 #include "tbb/concurrent_hash_map.h"
00306 #include "tbb/concurrent_vector.h"
00307 #include "tbb/tick_count.h"
00308 #include "tbb/blocked_range.h"
00309 #include "tbb/parallel_for.h"
00310 #include "tbb/mutex.h"
00311
00312 class CTimeInterval {
00313 public:
00314 CTimeInterval(const std::string& label) :
00315 _label(label), _start(tbb::tick_count::now()), _done(false) {}
00316 ~CTimeInterval(void) { emit(); }
00317 void suppress_emission(void) { _done = true; }
00318 void emit(void) {
00319 if (!_done) {
00320 _done = true;
00321 tbb::tick_count end = tbb::tick_count::now();
00322 cout << _label << " took " << (end-_start).seconds() << " seconds." << endl;
00323 }
00324 }
00325 private:
00326 std::string _label;
00327 tbb::tick_count _start;
00328 bool _done;
00329 };
00330
00331 #define WANT_PARALLEL_WHILE 1
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 #include "tbb/parallel_while.h"
00345 #include "tbb_misc.h"
00346
00347
00348
00349 template <typename ITEM>
00350 class item_stream {
00351 ITEM _item;
00352 public:
00353 bool pop_if_present( ITEM& item ) {
00354 if ( _item ) {
00355 item = _item;
00356 _item = get_next_item(_item);
00357 return true;
00358 } else {
00359 return false;
00360 }
00361 }
00362
00363 item_stream(ITEM root_item) : _item(root_item) {}
00364 };
00365
00366 template <typename BODY>
00367 class incrementing_parallel_while : public tbb::parallel_while {
00368 tbb::atomic _nexti;
00369 public:
00370 incrementing_parallel_while(size_t start_i = 0) { _nexti = start_i; }
00371 size_t get_next_i(void) const { return _nexti; }
00372
00373 std::pair increment_next_i_up_to(size_t max_i) {
00374 size_t i = 1 + _nexti.fetch_and_increment();
00375 if (i < max_i)
00376 return std::pair(true, i);
00377
00378 _nexti.fetch_and_decrement();
00379 return std::pair(false, 0);
00380 }
00381 };
00382
00383 template <typename BODY>
00384 class incrementing_parallel_while_with_max : public incrementing_parallel_while {
00385 size_t _maxi;
00386 public:
00387 incrementing_parallel_while_with_max(size_t start_i, size_t max_i) :
00388 incrementing_parallel_while(start_i), _maxi(max_i) { assert(start_i != max_i); }
00389
00390 std::pair increment_next_i(void)
00391 { return incrementing_parallel_while::increment_next_i_up_to(_maxi); }
00392 };
00393
00394 template <typename ITEM, template <typename ITEM> class PARALLEL_WHILE = incrementing_parallel_while>
00395 class item_applier {
00396 PARALLEL_WHILE< item_applier- >& _w;
00397 public:
00398 void operator()( ITEM item ) const {
00399 apply_to_item(item);
00400 if (!add_next_items(_w, item))
00401 dispose_item(item);
00402 }
00403
00404 typedef ITEM argument_type;
00405 item_applier(PARALLEL_WHILE< item_applier
- >& w) : _w(w) {}
00406 };
00407
00408 template <typename ITEM>
00409 static
00410 ITEM*
00411 get_next_item(ITEM* item)
00412 {
00413 return item->next();
00414 }
00415
00416 template <typename ITEM>
00417 static
00418 void
00419 apply_to_item(ITEM* item)
00420 {
00421 item->apply();
00422 }
00423
00424 template <typename ITEM>
00425 static
00426 void
00427 dispose_item(ITEM* item)
00428 {
00429 delete item;
00430 }
00431
00432
00433
00434 template <typename ITEM>
00435 static
00436 bool
00437 add_next_items(
00438 incrementing_parallel_while_with_max< item_applier
- 00439 incrementing_parallel_while_with_max> >& w,
00440 ITEM* item)
00441 {
00442 const size_t n = item->is_first() ? tbb::DetectNumberOfWorkers() : 1;
00443
00444 bool res = false;
00445 std::pair pr(w.increment_next_i());
00446 if (pr.first && item->set_next_i(pr.second)) {
00447 w.add(item);
00448 res = true;
00449
00450 for (size_t i = 1; i != n; ++i) {
00451 pr = w.increment_next_i();
00452 if (pr.first) {
00453 ITEM* clone = item->clone_for_next_i(pr.second);
00454 if (clone) {
00455 w.add(clone);
00456 continue;
00457 }
00458 }
00459 break;
00460 }
00461 }
00462
00463 return res;
00464 }
00465
00466 template <typename ITEM, template <typename ITEM> class PARALLEL_WHILE>
00467 static
00468 void
00469 parallel_while(ITEM* first_item, size_t item_count)
00470 {
00471 std::auto_ptr
- item(first_item);
00472 PARALLEL_WHILE< item_applier
- >
00473 w(0, item_count);
00474 item_applier
- body(w);
00475 item_stream
- stream(item.release());
00476 w.run( stream, body );
00477 }
00478
00479
00480
00481 enum { ALL_SERIAL, CHECKSUM_SERIALLY_BUT_PROCESS_CONCURRENTLY, ALL_CONCURRENT };
00482 #endif
00483
00484 #include "letype.h"
00485
00486
00487 #include "galois.h"
00488 #include "crc.h"
00489 #include "md5.h"
00490 #include "par2fileformat.h"
00491 #include "commandline.h"
00492 #include "reedsolomon.h"
00493
00494 #include "diskfile.h"
00495 #include "datablock.h"
00496
00497 #include "criticalpacket.h"
00498 #include "par2creatorsourcefile.h"
00499
00500 #include "mainpacket.h"
00501 #include "creatorpacket.h"
00502 #include "descriptionpacket.h"
00503 #include "verificationpacket.h"
00504 #include "recoverypacket.h"
00505
00506 #include "par2repairersourcefile.h"
00507
00508 #include "filechecksummer.h"
00509 #include "verificationhashtable.h"
00510
00511 #include "par2creator.h"
00512 #include "par2repairer.h"
00513
00514 #include "par1fileformat.h"
00515 #include "par1repairersourcefile.h"
00516 #include "par1repairer.h"
00517
00518
00519 #ifdef _MSC_VER
00520 #define _CRTDBG_MAP_ALLOC
00521 #include
00522 #define DEBUG_NEW new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
00523 #endif
00524
00525 #endif // __PARCMDLINE_H__
00526