source: gsdl/tags/bs/gsinstaller/fileCopier.cpp@ 18532

Last change on this file since 18532 was 1498, checked in by cs025, 24 years ago

Further changes for uninstaller

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