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
00027
#include <wx/wxprec.h>
00028
00029
#ifdef __BORLANDC__
00030
#pragma hdrstop
00031
#endif
00032
00033
#ifndef WX_PRECOMP
00034
00035
#include <wx/wx.h>
00036
#endif
00037
00038
#include <wx/txtstrm.h>
00039
#include <wx/wfstream.h>
00040
00041
#include "sfvfile.hpp"
00042
#include "appprefs.hpp"
00043
#include "crc32.hpp"
00044
#include "osdep.hpp"
00045
#include "utils.hpp"
00046
00047
#include "compat.hpp"
00048
00049
00050
00051
using namespace std;
00052
00053
00054
00055
00056
00057 SFVFile::SFVFile() :
SumFile()
00058 {
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 void SFVFile::clone(
const SFVFile& source)
00071 {
00072 SumFile::clone(source);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 SFVFile::SFVFile(
const SFVFile& source)
00083 {
00084
clone(source);
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 SFVFile&
SFVFile::operator=(
const SFVFile& source)
00096 {
00097
clone(source);
00098
return *
this;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 Checksum*
SFVFile::getChecksumCalculator()
const
00112
{
00113
return new CRC32();
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123 wxString
SFVFile::getFileType()
const
00124
{
00125
return wxString(wxT(
"SFV"));
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 bool SFVFile::read(
const wxFileName& fileName)
00145 {
00146
const int MAX_INVALID = 64;
00147 wxString line;
00148 size_t l;
00149 size_t i;
00150
bool comment;
00151
bool stop;
00152
int invalid = 0;
00153
int valid = 0;
00154
int ccomment = 0;
00155 wxChar c;
00156 wxString name;
00157 wxString sum;
00158 wxFileName nameRel;
00159 wxFileName nameAbs;
00160 wxPathFormat format;
00161
00162
00163 wxLogNull logNo;
00164
00165
00166 format = static_cast<wxPathFormat>(
AppPrefs::get()->
readLong(prSFV_READ_PATH_SEPARATOR));
00167
if (format == wxPATH_NATIVE)
00168 format = getPathFormat(fileName);
00169
00170
00171 wxFileInputStream input(fileName.GetFullPath());
00172
if (!input.Ok())
00173
return false;
00174 wxTextInputStream text(input);
00175
00176
00177
reset();
00178
00179
00180 line = text.ReadLine();
00181
while (!input.Eof() && invalid - valid <= MAX_INVALID)
00182 {
00183 l = line.size();
00184
00185
00186 i = 0;
00187 stop =
false;
00188 comment = line.empty();
00189
while (!stop && !comment && i < l)
00190 {
00191 c = line[i];
00192
if (c == wxT(
';'))
00193 comment =
true;
00194
else
00195
if (line[i] == wxT(
' ') || line[i] == wxT(
'\t'))
00196 i++;
00197
else
00198 stop =
true;
00199 }
00200
00201
if (comment || i == l)
00202
00203 {
00204 valid++;
00205 ccomment++;
00206 }
00207
else
00208 {
00209 name = line.BeforeLast(wxT(
' '));
00210 sum = line.AfterLast(wxT(
' '));
00211
if (name.empty() || !
IsValidChecksum(sum))
00212
00213 {
00214 name = line.BeforeLast(wxT(
'\t'));
00215 sum = line.AfterLast(wxT(
'\t'));
00216 }
00217
if (name.empty() || !
IsValidChecksum(sum))
00218
00219 invalid++;
00220
else
00221 {
00222 valid++;
00223
00224 nameAbs.Assign(name, format);
00225
if (!nameAbs.IsAbsolute())
00226 nameAbs.MakeAbsolute(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00227 nameRel = nameAbs;
00228
if (!nameRel.IsRelative())
00229 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00230
00231 addChecksumData(
ChecksumData(nameRel, sum, ChecksumData::NotVerified));
00232 }
00233 }
00234
00235 line = text.ReadLine();
00236 }
00237
00238 valid -= ccomment;
00239
if ((invalid - valid <= MAX_INVALID && valid > 0) ||
00240 (valid == 0 && invalid == 0))
00241 {
00242 setFileName(fileName.GetFullPath());
00243 setModified(
false);
00244
return true;
00245 }
00246
00247
return false;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 bool SFVFile::write(
const wxFileName& fileName)
00265 {
00266 wxLogNull logNo;
00267 wxString line;
00268 wxDateTime d;
00269 wxFileName nameRel;
00270 wxFileName nameAbs;
00271
wxCOff_t length;
00272 wxPathFormat format;
00273
00274 wxFileOutputStream output(fileName.GetFullPath());
00275
if (!output.Ok())
00276
return false;
00277 wxTextOutputStream text(output, static_cast<wxEOL>(AppPrefs::get()->readLong(prSFV_WRITE_EOL)));
00278
00279
00280 format = static_cast<wxPathFormat>(
AppPrefs::get()->
readLong(prSFV_WRITE_PATH_SEPARATOR));
00281
00282
00283
if (
AppPrefs::get()->
readBool(prSFV_WRITE_GEN_AND_DATE))
00284 {
00285 d = wxDateTime::Now();
00286 wxString generator =
AppPrefs::get()->
readString(prSFV_IDENTIFY_AS);
00287
if (generator.IsEmpty())
00288 generator = ::getAppName();
00289 line.Printf(wxT(
"; Generated by %s on %s at %s\n"), generator.c_str(),
00290 d.Format(wxT(
"%Y-%m-%d")).c_str(), d.Format(wxT(
"%H:%M:%S")).c_str());
00291 text.WriteString(line);
00292 text.WriteString(wxT(
";\n"));
00293 }
00294
00295
00296
if (
AppPrefs::get()->
readBool(prSFV_WRITE_FILE_SIZE_AND_DATE))
00297 {
00298 MChecksumData::const_iterator it =
getChecksumDataBegin();
00299 MChecksumData::const_iterator end =
getChecksumDataEnd();
00300
00301
while (it != end)
00302 {
00303
const ChecksumData& cd = it->second;
00304 nameAbs = cd.
getFileName();
00305
if (!nameAbs.IsAbsolute())
00306 nameAbs.MakeAbsolute(wxFileName(this->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00307 nameRel = nameAbs;
00308
if (!nameRel.IsRelative())
00309 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00310
00311
if ((length =
wxCGetFileLength(nameAbs.GetFullPath())) != static_cast<wxCOff_t>(wxInvalidOffset))
00312 {
00313
#if defined(wxC_USE_LARGE_FILES)
00314
text.WriteString(wxString::Format(wxT(
"; %12" wxLongLongFmtSpec
"u "), length));
00315
#else
00316
text.WriteString(wxString::Format(wxT(
"; %12u "), length));
00317
#endif
00318
d = nameAbs.GetModificationTime();
00319 text << d.Format(wxT(
"%H:%M.%S")) << wxT(
" ") << d.Format(wxT(
"%Y-%m-%d"));
00320 text << wxT(
" ") << nameRel.GetFullPath(format) << wxT(
"\n");
00321 }
00322 it++;
00323 }
00324 }
00325
00326
00327 MChecksumData::const_iterator it =
getChecksumDataBegin();
00328 MChecksumData::const_iterator end =
getChecksumDataEnd();
00329
00330
while (it != end)
00331 {
00332
const ChecksumData& cd = it->second;
00333 nameAbs = cd.
getFileName();
00334
if (!nameAbs.IsAbsolute())
00335 nameAbs.MakeAbsolute(wxFileName(this->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00336 nameRel = nameAbs;
00337
if (!nameRel.IsRelative())
00338 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00339
00340 text << nameRel.GetFullPath(format) << wxT(
" ")
00341 << cd.
getChecksum().Upper() << wxT(
"\n");
00342 it++;
00343 }
00344
00345
if (output.IsOk())
00346 {
00347
00348 {
00349 MChecksumData::iterator it =
getChecksumDataBeginI();
00350 MChecksumData::iterator end =
getChecksumDataEndI();
00351
00352
while (it != end)
00353 {
00354
ChecksumData& cd = it->second;
00355 nameAbs = cd.
getFileName();
00356
if (!nameAbs.IsAbsolute())
00357 nameAbs.MakeAbsolute(wxFileName(this->getFileName()).GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00358 nameRel = nameAbs;
00359
if (!nameRel.IsRelative())
00360 nameRel.MakeRelativeTo(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
00361
00362 cd.
setFileName(nameRel);
00363 it++;
00364 }
00365 }
00366
00367 this->setFileName(fileName.GetFullPath());
00368 this->setModified(
false);
00369
return true;
00370 }
00371
else
00372
return false;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382 bool SFVFile::IsValidChecksum(
const wxString& checksum)
00383 {
00384
const wxString validCaracters = wxT(
"0123456789abcdefABCDEF");
00385 wxChar c;
00386 size_t i, j;
00387 size_t l = checksum.size();
00388 size_t s = validCaracters.size();
00389
bool OK, found;
00390
00391 i = 0;
00392 OK = (checksum.size() == 8);
00393
while (OK && i < l)
00394 {
00395 c = checksum[i];
00396 j = 0;
00397 found =
false;
00398
while (!found && j < s)
00399 {
00400
if (c == validCaracters[j])
00401 found =
true;
00402 j++;
00403 }
00404
00405
if (!found)
00406 OK =
false;
00407 i++;
00408 }
00409
00410
return OK;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 SumFile*
SFVFile::getNewInstance()
00424 {
00425
return new SFVFile();
00426 }
00427