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 
30 // Open the file associated with the data block if is not already open
Open(void)31 bool DataBlock::Open(void)
32 {
33   if (diskfile == 0)
34     return false;
35 
36   if (diskfile->IsOpen())
37     return true;
38 
39   return diskfile->Open();
40 }
41 
42 // Read some data at a specified position within a data block
43 // into a buffer in memory
44 
ReadData(u64 position,size_t size,void * buffer)45 bool DataBlock::ReadData(u64    position, // Position within the block
46                          size_t size,     // Size of the memory buffer
47                          void  *buffer)   // Pointer to memory buffer
48 {
49   assert(diskfile != 0);
50 
51   // Check to see if the position from which data is to be read
52   // is within the bounds of the data block
53   if (length > position)
54   {
55     // Compute the file offset and how much data to physically read from disk
56     u64    fileoffset = offset + position;
57     size_t want       = (size_t)min((u64)size, length - position);
58 
59     // Read the data from the file into the buffer
60     if (!diskfile->Read(fileoffset, buffer, want))
61       return false;
62 
63     // If the read extends beyond the end of the data block,
64     // then the rest of the buffer is zeroed.
65     if (want < size)
66     {
67       memset(&((u8*)buffer)[want], 0, size-want);
68     }
69   }
70   else
71   {
72     // Zero the whole buffer
73     memset(buffer, 0, size);
74   }
75 
76   return true;
77 }
78 
79 // Write some data at a specified position within a datablock
80 // from memory to disk
81 
WriteData(u64 position,size_t size,const void * buffer,size_t & wrote)82 bool DataBlock::WriteData(u64         position, // Position within the block
83                           size_t      size,     // Size of the memory buffer
84                           const void *buffer,   // Pointer to memory buffer
85                           size_t     &wrote)    // Amount actually written
86 {
87   assert(diskfile != 0);
88 
89   wrote = 0;
90 
91   // Check to see if the position from which data is to be written
92   // is within the bounds of the data block
93   if (length > position)
94   {
95     // Compute the file offset and how much data to physically write to disk
96     u64    fileoffset = offset + position;
97     size_t have       = (size_t)min((u64)size, length - position);
98 
99     // Write the data from the buffer to disk
100     if (!diskfile->Write(fileoffset, buffer, have))
101       return false;
102 
103     wrote = have;
104   }
105 
106   return true;
107 }
108