source: trunk/gsinstaller/fileCopier.cpp@ 1537

Last change on this file since 1537 was 1536, checked in by sjboddie, 24 years ago

Changes to get compiling on VC++ and gcc

  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1#include "fileCopier.h"
2
3#include <stdlib.h>
4#include <stdio.h>
5//#include <dir.h>
6#include <direct.h>
7
8fileCopySet::fileCopySet()
9{
10 // do we need this - they're FilePath's, not pointers
11 // this->sourceDir = NULL;
12 // this->destDir = NULL;
13}
14
15fileCopySet::fileCopySet(FileVector files, FilePath &from, FilePath &to)
16{
17 this->fileList = files;
18 this->sourceDir = from;
19 this->destDir = to;
20 this->dataSize = 0;
21
22 FileVector::iterator here = files.begin();
23 FileVector::iterator end = files.end();
24
25 while (here != end)
26 {
27 this->dataSize += here->getFileSize();
28 here ++;
29 }
30}
31
32/**
33 * Get the destination file name for a given source file; source and destination
34 * directory locations are obtained from the object
35 */
36char *fileCopySet::destination(File *file)
37{
38 const char *oldname = file->getFileName();
39 char *newname = (char *) malloc(strlen(oldname) - strlen(this->sourceDir.cString()) + strlen(this->destDir.cString()) + 1);
40
41 if (newname != NULL)
42 {
43 strcpy(newname, this->destDir.cString());
44 strcat(newname, &oldname[strlen(this->sourceDir.cString())]);
45 }
46
47 return newname;
48}
49
50/**
51 * Copy a particular file to its destination
52 */
53bool fileCopySet::copyFile(File *file, fileCopyMonitor *monitor, copyProgressBar &progressBar)
54{
55 unsigned long copied = 0;
56 unsigned long bytes_read, bytes_written;
57 unsigned char buffer[65536];
58 FILE *read_handle, *write_handle;
59 char *destination;
60
61 // get destination as a char[] block; will free it later
62 destination = this->destination(file);
63
64 // get read and write file handles
65 read_handle = fopen(file->getFileName(), "rb");
66 if (read_handle == NULL)
67 {
68 return false;
69 }
70 write_handle = fopen(destination, "wb");
71 if (write_handle == NULL)
72 {
73 fclose(read_handle);
74 return false;
75 }
76
77 while (copied < file->getFileSize())
78 {
79 // TODO: lock
80 // read so many bytes
81 if (file->getFileSize() - copied < 65536)
82 {
83 bytes_read = file->getFileSize() - copied;
84 }
85 else
86 {
87 bytes_read = 65536;
88 }
89 bytes_read = fread((void *) buffer, 1, bytes_read, read_handle);
90
91 // write so many bytes
92 bytes_written = fwrite((void *) buffer, 1, bytes_read, write_handle);
93
94 // TODO: unlock
95
96 // note new bytes copied
97 copied += bytes_written;
98 this->dataSize += bytes_written;
99 }
100 fclose(read_handle);
101 fclose(write_handle);
102
103 // free destination filename text
104 if (monitor != NULL)
105 {
106 monitor->copied(file->getFileName(), destination, false);
107 }
108 delete destination;
109 return true;
110}
111
112/**
113 * Copy a file "object" (may be a directory or a "proper" file) to it's
114 * destination
115 */
116void fileCopySet::copy(File *file, fileCopyMonitor *monitor, copyProgressBar &progressBar)
117{
118 // just skip this file if it doesn't exist
119 if (file->exists() == false)
120 {
121 return;
122 }
123
124 // if a directory, scan it.
125 if (file->isDirectory())
126 {
127 // create directory
128 char *thisDestDir = this->destination(file);
129 _mkdir(thisDestDir);
130
131 // note amount of data copied
132 // this->copied += file->getRawFileSize();
133
134 // note for uninstall the action done
135 if (monitor != NULL)
136 {
137 monitor->copied(file->getFileName(), thisDestDir, true);
138 }
139
140 // copy children
141 vector<File>::iterator here = file->childBegin();
142 vector<File>::iterator end = file->childEnd();
143 while (here != end)
144 {
145 this->copy(here, monitor, progressBar);
146 here ++;
147 }
148
149 // delete constructed destination name
150 delete thisDestDir;
151 }
152
153 // not a directory; just copy the file
154 else
155 {
156 // copy file itself
157 this->copyFile(file, monitor, progressBar);
158 }
159
160 progressBar.done(file->getRawFileSize());
161}
162
163void fileCopySet::copy(fileCopyMonitor *monitor, copyProgressBar &progressBar)
164{
165 FileVector::iterator here = fileList.begin();
166 FileVector::iterator end = fileList.end();
167 while (here != end)
168 {
169 this->copy(here, monitor, progressBar);
170 here ++;
171 }
172}
173
174unsigned long fileCopySet::getCopiedSize(DiskSpace &space)
175{
176 // initialise counters for size
177 unsigned long copiedSize = 0;
178
179 // iterate through our list of files to obtain total space requirement
180 FileVector::iterator here = fileList.begin();
181 FileVector::iterator end = fileList.end();
182 while (here != end)
183 {
184 copiedSize += here->getDiskSpace(space);
185 here ++;
186 }
187 return copiedSize;
188}
189
190unsigned long fileCopySet::getOriginalSize()
191{
192 // initialise counters for size
193 return this->dataSize;
194}
195
196/**
197 * Perform a check on the total space available at the destination; if not
198 * enough then return false to indicate the error state
199 */
200bool fileCopier::checkSpace()
201{
202 fileCopySetList localSet = this->list;
203
204 do
205 {
206 unsigned int i = 0;
207
208 // get destination root and use it to obtain space check information
209 FilePath *destRoot = localSet[0].destDir.root();
210 DiskSpace space(destRoot->cString());
211
212 // check that diskspace checking is functional
213 if (space.initialisedOk() == false)
214 {
215 delete destRoot;
216 return false;
217 }
218
219 // get size of the first set
220 unsigned long copiedSize = localSet[0].getCopiedSize(space);
221
222 // dispose of the first set
223 localSet.erase(localSet.begin());
224
225 // get all remaining sets and in turn if they share the root with
226 // the first root, add their size to the count and remove them from
227 // the local list of sets; otherwise skip
228 while (i < localSet.size())
229 {
230 // get a new root object for this set's destination
231 FilePath *p = localSet[i].destDir.root();
232
233 if (*destRoot == *p)
234 {
235 copiedSize += localSet[i].getCopiedSize(space);
236 localSet.erase(localSet.begin() + i);
237 }
238 else
239 {
240 i ++;
241 }
242
243 // delete the constructed root
244 delete p;
245 }
246
247 // dispose of destination root
248 delete destRoot;
249
250 // return false if not enough space
251 if (space.totalFreeSpace() < copiedSize)
252 {
253 return false;
254 }
255
256 } while (localSet.size() != 0);
257
258
259 // record size and initialise the progressbar with the same
260 this->dataSize = 0;
261 for (unsigned int i = 0; i < this->list.size(); i ++)
262 {
263 this->dataSize += this->list[i].getOriginalSize();
264 }
265 this->progressBar.init(this->dataSize);
266
267 // return postive check
268 return true;
269}
270
271fileCopier::fileCopier(fileCopyMonitor *monitor, fileCopySetList &_list)
272{
273 this->list = _list;
274 this->dataSize = 0;
275 this->copied = 0;
276 this->monitor = monitor;
277}
278
279fileCopier::fileCopier(fileCopyMonitor *monitor)
280{
281 this->dataSize = 0;
282 this->copied = 0;
283 this->monitor = monitor;
284}
285
286void fileCopier::copy()
287{
288 fileCopySetList::iterator here = list.begin();
289 fileCopySetList::iterator end = list.end();
290
291 this->progressBar.show();
292 while (here != end)
293 {
294 here->copy(this->monitor, this->progressBar);
295 here ++;
296 }
297
298 this->progressBar.close();
299}
Note: See TracBrowser for help on using the repository browser.