source: branches/nzdl/gsinstaller/fileCopier.cpp@ 13703

Last change on this file since 13703 was 1397, checked in by cs025, 24 years ago

Initial revision

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