Merge lp:~timo-wingender/widelands/fix-loading-zipfiles into lp:widelands

Proposed by Timowi
Status: Merged
Merged at revision: 5576
Proposed branch: lp:~timo-wingender/widelands/fix-loading-zipfiles
Merge into: lp:widelands
Diff against target: 247 lines (+53/-41)
3 files modified
ChangeLog (+3/-0)
src/io/filesystem/zip_filesystem.cc (+46/-41)
src/io/filesystem/zip_filesystem.h (+4/-0)
To merge this branch: bzr merge lp:~timo-wingender/widelands/fix-loading-zipfiles
Reviewer Review Type Date Requested Status
SirVer Approve
Nasenbaer Approve
Review via email: mp+37439@code.launchpad.net

Description of the change

change zipFilesystem code.
Data files now are written to the root of the zip file and not place in an extra directory inside the zip file. The loading code accepts both the old and the new zip file layout.

This will break compatibility with old versions.

To post a comment you must log in.
Revision history for this message
Nasenbaer (nasenbaer) wrote :

Looks good to me :)!
Thanks for fixing this Timowi :)!

review: Approve
Revision history for this message
SirVer (sirver) wrote :

I am all for merging this, but due to network constraints, I cannot do this at the moment. Could someone please sub for me?

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2010-09-25 12:49:34 +0000
+++ ChangeLog 2010-10-04 09:18:51 +0000
@@ -1,4 +1,7 @@
1### Build 16 (until now)1### Build 16 (until now)
2- Changed the way compressed files are generated (maps, savegames) and read.
3 Now it is possible to rename maps and savegames but it is not possible
4 to load maps from version after this change with versions before this change
2- Improved and added a lot new animations for workers!5- Improved and added a lot new animations for workers!
3- Implemented teamview for allied players6- Implemented teamview for allied players
4- Implemented shared kingdom mode, where two or more players play the same7- Implemented shared kingdom mode, where two or more players play the same
58
=== modified file 'src/io/filesystem/zip_filesystem.cc'
--- src/io/filesystem/zip_filesystem.cc 2010-06-13 16:44:59 +0000
+++ src/io/filesystem/zip_filesystem.cc 2010-10-04 09:18:51 +0000
@@ -38,6 +38,7 @@
38m_state (STATE_IDLE),38m_state (STATE_IDLE),
39m_zipfile (0),39m_zipfile (0),
40m_unzipfile (0),40m_unzipfile (0),
41m_oldzip (false),
41m_zipfilename(zipfile),42m_zipfilename(zipfile),
42m_basename (FS_Filename(zipfile.c_str()))43m_basename (FS_Filename(zipfile.c_str()))
43{44{
@@ -82,9 +83,7 @@
8283
83 std::string path;84 std::string path;
84 assert(path_in.size()); // prevent invalid read below85 assert(path_in.size()); // prevent invalid read below
85 if (path_in[0] != '/')86 path = path_in;
86 path = '/';
87 path += path_in;
88 if (*path.rbegin() != '/')87 if (*path.rbegin() != '/')
89 path += '/';88 path += '/';
9089
@@ -98,7 +97,7 @@
98 (m_unzipfile, &file_info, filename_inzip, sizeof(filename_inzip),97 (m_unzipfile, &file_info, filename_inzip, sizeof(filename_inzip),
99 0, 0, 0, 0);98 0, 0, 0, 0);
10099
101 std::string complete_filename = &filename_inzip[m_basename.size()];100 std::string complete_filename = strip_basename(filename_inzip);
102 std::string filename = FS_Filename(complete_filename.c_str());101 std::string filename = FS_Filename(complete_filename.c_str());
103 std::string filepath =102 std::string filepath =
104 complete_filename.substr103 complete_filename.substr
@@ -107,13 +106,14 @@
107 // FIXME Something strange is going on with regard to the leading slash!106 // FIXME Something strange is going on with regard to the leading slash!
108 // FIXME This is just an ugly workaround and does not solve the real107 // FIXME This is just an ugly workaround and does not solve the real
109 // FIXME problem (which remains undiscovered)108 // FIXME problem (which remains undiscovered)
110 if (('/' + path == filepath || path == filepath) && filename.size())109 if
110 (('/' + path == filepath || path == filepath || path.length() == 1)
111 && filename.size())
111 results->insert(complete_filename);112 results->insert(complete_filename);
112113
113 if (unzGoToNextFile(m_unzipfile) == UNZ_END_OF_LIST_OF_FILE)114 if (unzGoToNextFile(m_unzipfile) == UNZ_END_OF_LIST_OF_FILE)
114 break;115 break;
115 }116 }
116
117 return results->size();117 return results->size();
118}118}
119119
@@ -127,46 +127,29 @@
127 } catch (...) {127 } catch (...) {
128 return false;128 return false;
129 }129 }
130
131 unzGoToFirstFile(m_unzipfile);130 unzGoToFirstFile(m_unzipfile);
132 unz_file_info file_info;131 unz_file_info file_info;
133 char filename_inzip[256];132 char filename_inzip[256];
134 memset(filename_inzip, ' ', 256);133 memset(filename_inzip, ' ', 256);
135134
136 std::string path;135 assert(path_in.size());
137 assert(path_in.size()); // prevent invalid read below
138 if (path_in[0] != '/')
139 path = '/';
140 path += path_in;
141136
142 for (;;) {137 for (;;) {
143 unzGetCurrentFileInfo138 unzGetCurrentFileInfo
144 (m_unzipfile, &file_info, filename_inzip, sizeof(filename_inzip),139 (m_unzipfile, &file_info, filename_inzip, sizeof(filename_inzip),
145 0, 0, 0, 0);140 0, 0, 0, 0);
146141
147 /* This is a short hack to try fixing Bug #593356.142 std::string complete_filename = strip_basename(filename_inzip);
148 * If the savename is copied m_basename might be longer than
149 * the original filename + the path and complete_filename is
150 * beyond the end of the string.
151 * In the function is also the cause for Bug #536189
152 *
153 * ToDo: This fuction should strip away the first element of the
154 * path instead just using the zip filename
155 */
156 if ( m_basename.size() >= strlen(filename_inzip))
157 break;
158143
159 std::string complete_filename = &filename_inzip[m_basename.size()];
160 if (*complete_filename.rbegin() == '/')144 if (*complete_filename.rbegin() == '/')
161 complete_filename.resize(complete_filename.size() - 1);145 complete_filename.resize(complete_filename.size() - 1);
162146
163 if (path == complete_filename)147 if (path_in == complete_filename)
164 return true;148 return true;
165149
166 if (unzGoToNextFile(m_unzipfile) == UNZ_END_OF_LIST_OF_FILE)150 if (unzGoToNextFile(m_unzipfile) == UNZ_END_OF_LIST_OF_FILE)
167 break;151 break;
168 }152 }
169
170 return false;153 return false;
171}154}
172155
@@ -201,7 +184,10 @@
201 m_Close();184 m_Close();
202185
203 ZipFilesystem & newfs = *new ZipFilesystem(m_zipfilename);186 ZipFilesystem & newfs = *new ZipFilesystem(m_zipfilename);
204 newfs.m_basename = m_basename + '/' + path;187 if (m_oldzip)
188 newfs.m_basename = m_basename + "/" + path;
189 else
190 newfs.m_basename = path;
205191
206 return newfs;192 return newfs;
207}193}
@@ -227,7 +213,10 @@
227 m_Close();213 m_Close();
228214
229 ZipFilesystem & newfs = *new ZipFilesystem(*this);215 ZipFilesystem & newfs = *new ZipFilesystem(*this);
230 newfs.m_basename = m_basename + '/' + path;216 if (m_oldzip)
217 newfs.m_basename = m_basename + "/" + path;
218 else
219 newfs.m_basename = path;
231220
232 return newfs;221 return newfs;
233}222}
@@ -273,17 +262,15 @@
273 zi.internal_fa = 0;262 zi.internal_fa = 0;
274 zi.external_fa = 0;263 zi.external_fa = 0;
275264
276 std::string complete_file = m_basename;
277 complete_file += '/';
278 complete_file += dirname;
279 assert(dirname.size());265 assert(dirname.size());
280 if (*complete_file.rbegin() != '/')266 std::string path = dirname;
281 complete_file += '/';267 if (*path.rbegin() != '/')
268 path += '/';
282269
283 switch270 switch
284 (zipOpenNewFileInZip3271 (zipOpenNewFileInZip3
285 (m_zipfile,272 (m_zipfile,
286 complete_file.c_str(),273 path.c_str(),
287 &zi,274 &zi,
288 0, 0, 0, 0, 0 /* comment*/,275 0, 0, 0, 0, 0 /* comment*/,
289 Z_DEFLATED,276 Z_DEFLATED,
@@ -299,10 +286,10 @@
299 break;286 break;
300 case ZIP_ERRNO:287 case ZIP_ERRNO:
301 throw File_error288 throw File_error
302 ("ZipFilesystem::MakeDirectory", complete_file, strerror(errno));289 ("ZipFilesystem::MakeDirectory", path, strerror(errno));
303 default:290 default:
304 throw File_error291 throw File_error
305 ("ZipFilesystem::MakeDirectory", complete_file);292 ("ZipFilesystem::MakeDirectory", path);
306 }293 }
307294
308 zipCloseFileInZip(m_zipfile);295 zipCloseFileInZip(m_zipfile);
@@ -382,10 +369,9 @@
382 zi.external_fa = 0;369 zi.external_fa = 0;
383370
384 // create file371 // create file
385 std::string const complete_file = m_basename + '/' + fname;
386 switch372 switch
387 (zipOpenNewFileInZip3373 (zipOpenNewFileInZip3
388 (m_zipfile, complete_file.c_str(), &zi,374 (m_zipfile, fname.c_str(), &zi,
389 0, 0, 0, 0, 0 /* comment*/,375 0, 0, 0, 0, 0 /* comment*/,
390 Z_DEFLATED,376 Z_DEFLATED,
391 Z_BEST_COMPRESSION, 0,377 Z_BEST_COMPRESSION, 0,
@@ -396,7 +382,7 @@
396 break;382 break;
397 default:383 default:
398 throw ZipOperation_error384 throw ZipOperation_error
399 ("ZipFilesystem::Write", complete_file, m_zipfilename);385 ("ZipFilesystem::Write", fname, m_zipfilename);
400 }386 }
401387
402 switch (zipWriteInFileInZip (m_zipfile, data, length)) {388 switch (zipWriteInFileInZip (m_zipfile, data, length)) {
@@ -404,10 +390,10 @@
404 break;390 break;
405 case ZIP_ERRNO:391 case ZIP_ERRNO:
406 throw File_error392 throw File_error
407 ("ZipFilesystem::Write", complete_file, strerror(errno));393 ("ZipFilesystem::Write", fname, strerror(errno));
408 default:394 default:
409 throw File_error395 throw File_error
410 ("ZipFilesystem::Write", complete_file);396 ("ZipFilesystem::Write", fname);
411 }397 }
412398
413 zipCloseFileInZip(m_zipfile);399 zipCloseFileInZip(m_zipfile);
@@ -481,3 +467,22 @@
481unsigned long long ZipFilesystem::DiskSpace() {467unsigned long long ZipFilesystem::DiskSpace() {
482 return 0; // FIXME468 return 0; // FIXME
483}469}
470
471std::string ZipFilesystem::strip_basename(std::string filename)
472{
473
474 if(filename.compare(0, m_basename.length(), m_basename) == 0)
475 {
476 // filename contains the name of the zip file as first element. This means
477 // this is an old zip file where all data were in a directory named as the
478 // file inside the zip file.
479 // return the filename without the first element
480 m_oldzip = true;
481 return filename.substr(m_basename.length() + 1);
482 }
483
484 // seems to be a new zipfile without directory or a old zipfile was renamed
485 m_oldzip = false;
486 return filename;
487}
488
484489
=== modified file 'src/io/filesystem/zip_filesystem.h'
--- src/io/filesystem/zip_filesystem.h 2010-03-16 20:18:53 +0000
+++ src/io/filesystem/zip_filesystem.h 2010-10-04 09:18:51 +0000
@@ -81,6 +81,7 @@
81 void m_OpenUnzip();81 void m_OpenUnzip();
82 void m_OpenZip();82 void m_OpenZip();
83 void m_Close();83 void m_Close();
84 std::string strip_basename(std::string);
8485
85private:86private:
86 enum State {87 enum State {
@@ -92,6 +93,9 @@
92 State m_state;93 State m_state;
93 zipFile m_zipfile;94 zipFile m_zipfile;
94 unzFile m_unzipfile;95 unzFile m_unzipfile;
96 /// if true data is in a directory named as the zipfile. This is set by
97 /// strip_basename()
98 bool m_oldzip;
95 std::string m_zipfilename;99 std::string m_zipfilename;
96 std::string m_basename;100 std::string m_basename;
97101

Subscribers

People subscribed via source and target branches

to status/vote changes: