1 //  This file is part of par2cmdline (a PAR 2.0 compatible file verification and
2 //  repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
3 //
4 //  Copyright (c) 2003 Peter Brian Clements
5 //
6 //  par2cmdline is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 2 of the License, or
9 //  (at your option) any later version.
10 //
11 //  par2cmdline is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19 
20 #include "par2cmdline.h"
21 
22 #ifdef _MSC_VER
23 #ifdef _DEBUG
24 #undef THIS_FILE
25 static char THIS_FILE[]=__FILE__;
26 #define new DEBUG_NEW
27 #endif
28 #endif
29 
Par2RepairerSourceFile(DescriptionPacket * _descriptionpacket,VerificationPacket * _verificationpacket)30 Par2RepairerSourceFile::Par2RepairerSourceFile(DescriptionPacket *_descriptionpacket,
31                                                VerificationPacket *_verificationpacket)
32 {
33   firstblocknumber = 0;
34 
35   descriptionpacket = _descriptionpacket;
36   verificationpacket = _verificationpacket;
37 
38 //  verificationhashtable = 0;
39 
40   targetexists = false;
41   targetfile = 0;
42   completefile = 0;
43 }
44 
~Par2RepairerSourceFile(void)45 Par2RepairerSourceFile::~Par2RepairerSourceFile(void)
46 {
47   delete descriptionpacket;
48   delete verificationpacket;
49 
50 //  delete verificationhashtable;
51 }
52 
53 
SetDescriptionPacket(DescriptionPacket * _descriptionpacket)54 void Par2RepairerSourceFile::SetDescriptionPacket(DescriptionPacket *_descriptionpacket)
55 {
56   descriptionpacket = _descriptionpacket;
57 }
58 
SetVerificationPacket(VerificationPacket * _verificationpacket)59 void Par2RepairerSourceFile::SetVerificationPacket(VerificationPacket *_verificationpacket)
60 {
61   verificationpacket = _verificationpacket;
62 }
63 
ComputeTargetFileName(string path)64 void Par2RepairerSourceFile::ComputeTargetFileName(string path)
65 {
66   // Get a version of the filename compatible with the OS
67   string filename = DiskFile::TranslateFilename(descriptionpacket->FileName());
68 
69   // Strip the path from the filename
70   string::size_type where;
71   if (string::npos != (where = filename.find_last_of('\\'))
72       || string::npos != (where = filename.find_last_of('/'))
73 #ifdef WIN32
74       || string::npos != (where = filename.find_last_of(':'))
75 #endif
76      )
77   {
78     filename = filename.substr(where+1);
79   }
80 
81   targetfilename = path + filename;
82 }
83 
TargetFileName(void) const84 string Par2RepairerSourceFile::TargetFileName(void) const
85 {
86   return targetfilename;
87 }
88 
SetTargetFile(DiskFile * diskfile)89 void Par2RepairerSourceFile::SetTargetFile(DiskFile *diskfile)
90 {
91   targetfile = diskfile;
92 }
93 
GetTargetFile(void) const94 DiskFile* Par2RepairerSourceFile::GetTargetFile(void) const
95 {
96   return targetfile;
97 }
98 
SetTargetExists(bool exists)99 void Par2RepairerSourceFile::SetTargetExists(bool exists)
100 {
101   targetexists = exists;
102 }
103 
GetTargetExists(void) const104 bool Par2RepairerSourceFile::GetTargetExists(void) const
105 {
106   return targetexists;
107 }
108 
SetCompleteFile(DiskFile * diskfile)109 void Par2RepairerSourceFile::SetCompleteFile(DiskFile *diskfile)
110 {
111   completefile = diskfile;
112 }
113 
GetCompleteFile(void) const114 DiskFile* Par2RepairerSourceFile::GetCompleteFile(void) const
115 {
116   return completefile;
117 }
118 
119 // Remember which source and target blocks will be used by this file
120 // and set their lengths appropriately
SetBlocks(u32 _blocknumber,u32 _blockcount,vector<DataBlock>::iterator _sourceblocks,vector<DataBlock>::iterator _targetblocks,u64 blocksize)121 void Par2RepairerSourceFile::SetBlocks(u32 _blocknumber,
122                                        u32 _blockcount,
123                                        vector<DataBlock>::iterator _sourceblocks,
124                                        vector<DataBlock>::iterator _targetblocks,
125                                        u64 blocksize)
126 {
127   firstblocknumber = _blocknumber;
128   blockcount = _blockcount;
129   sourceblocks = _sourceblocks;
130   targetblocks = _targetblocks;
131 
132   if (blockcount > 0)
133   {
134     u64 filesize = descriptionpacket->FileSize();
135 
136     vector<DataBlock>::iterator sb = sourceblocks;
137     for (u32 blocknumber=0; blocknumber<blockcount; ++blocknumber, ++sb)
138     {
139       DataBlock &datablock = *sb;
140 
141       u64 blocklength = min(blocksize, filesize-(u64)blocknumber*blocksize);
142 
143       datablock.SetLength(blocklength);
144     }
145   }
146 }
147 
148 // Determine the block count from the file size and block size.
SetBlockCount(u64 blocksize)149 void Par2RepairerSourceFile::SetBlockCount(u64 blocksize)
150 {
151   if (descriptionpacket)
152   {
153     blockcount = (u32)((descriptionpacket->FileSize() + blocksize-1) / blocksize);
154   }
155   else
156   {
157     blockcount = 0;
158   }
159 }
160