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