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
1=== modified file 'ChangeLog'
2--- ChangeLog 2010-09-25 12:49:34 +0000
3+++ ChangeLog 2010-10-04 09:18:51 +0000
4@@ -1,4 +1,7 @@
5 ### Build 16 (until now)
6+- Changed the way compressed files are generated (maps, savegames) and read.
7+ Now it is possible to rename maps and savegames but it is not possible
8+ to load maps from version after this change with versions before this change
9 - Improved and added a lot new animations for workers!
10 - Implemented teamview for allied players
11 - Implemented shared kingdom mode, where two or more players play the same
12
13=== modified file 'src/io/filesystem/zip_filesystem.cc'
14--- src/io/filesystem/zip_filesystem.cc 2010-06-13 16:44:59 +0000
15+++ src/io/filesystem/zip_filesystem.cc 2010-10-04 09:18:51 +0000
16@@ -38,6 +38,7 @@
17 m_state (STATE_IDLE),
18 m_zipfile (0),
19 m_unzipfile (0),
20+m_oldzip (false),
21 m_zipfilename(zipfile),
22 m_basename (FS_Filename(zipfile.c_str()))
23 {
24@@ -82,9 +83,7 @@
25
26 std::string path;
27 assert(path_in.size()); // prevent invalid read below
28- if (path_in[0] != '/')
29- path = '/';
30- path += path_in;
31+ path = path_in;
32 if (*path.rbegin() != '/')
33 path += '/';
34
35@@ -98,7 +97,7 @@
36 (m_unzipfile, &file_info, filename_inzip, sizeof(filename_inzip),
37 0, 0, 0, 0);
38
39- std::string complete_filename = &filename_inzip[m_basename.size()];
40+ std::string complete_filename = strip_basename(filename_inzip);
41 std::string filename = FS_Filename(complete_filename.c_str());
42 std::string filepath =
43 complete_filename.substr
44@@ -107,13 +106,14 @@
45 // FIXME Something strange is going on with regard to the leading slash!
46 // FIXME This is just an ugly workaround and does not solve the real
47 // FIXME problem (which remains undiscovered)
48- if (('/' + path == filepath || path == filepath) && filename.size())
49+ if
50+ (('/' + path == filepath || path == filepath || path.length() == 1)
51+ && filename.size())
52 results->insert(complete_filename);
53
54 if (unzGoToNextFile(m_unzipfile) == UNZ_END_OF_LIST_OF_FILE)
55 break;
56 }
57-
58 return results->size();
59 }
60
61@@ -127,46 +127,29 @@
62 } catch (...) {
63 return false;
64 }
65-
66 unzGoToFirstFile(m_unzipfile);
67 unz_file_info file_info;
68 char filename_inzip[256];
69 memset(filename_inzip, ' ', 256);
70
71- std::string path;
72- assert(path_in.size()); // prevent invalid read below
73- if (path_in[0] != '/')
74- path = '/';
75- path += path_in;
76+ assert(path_in.size());
77
78 for (;;) {
79 unzGetCurrentFileInfo
80 (m_unzipfile, &file_info, filename_inzip, sizeof(filename_inzip),
81 0, 0, 0, 0);
82
83- /* This is a short hack to try fixing Bug #593356.
84- * If the savename is copied m_basename might be longer than
85- * the original filename + the path and complete_filename is
86- * beyond the end of the string.
87- * In the function is also the cause for Bug #536189
88- *
89- * ToDo: This fuction should strip away the first element of the
90- * path instead just using the zip filename
91- */
92- if ( m_basename.size() >= strlen(filename_inzip))
93- break;
94+ std::string complete_filename = strip_basename(filename_inzip);
95
96- std::string complete_filename = &filename_inzip[m_basename.size()];
97 if (*complete_filename.rbegin() == '/')
98 complete_filename.resize(complete_filename.size() - 1);
99
100- if (path == complete_filename)
101+ if (path_in == complete_filename)
102 return true;
103
104 if (unzGoToNextFile(m_unzipfile) == UNZ_END_OF_LIST_OF_FILE)
105 break;
106 }
107-
108 return false;
109 }
110
111@@ -201,7 +184,10 @@
112 m_Close();
113
114 ZipFilesystem & newfs = *new ZipFilesystem(m_zipfilename);
115- newfs.m_basename = m_basename + '/' + path;
116+ if (m_oldzip)
117+ newfs.m_basename = m_basename + "/" + path;
118+ else
119+ newfs.m_basename = path;
120
121 return newfs;
122 }
123@@ -227,7 +213,10 @@
124 m_Close();
125
126 ZipFilesystem & newfs = *new ZipFilesystem(*this);
127- newfs.m_basename = m_basename + '/' + path;
128+ if (m_oldzip)
129+ newfs.m_basename = m_basename + "/" + path;
130+ else
131+ newfs.m_basename = path;
132
133 return newfs;
134 }
135@@ -273,17 +262,15 @@
136 zi.internal_fa = 0;
137 zi.external_fa = 0;
138
139- std::string complete_file = m_basename;
140- complete_file += '/';
141- complete_file += dirname;
142 assert(dirname.size());
143- if (*complete_file.rbegin() != '/')
144- complete_file += '/';
145+ std::string path = dirname;
146+ if (*path.rbegin() != '/')
147+ path += '/';
148
149 switch
150 (zipOpenNewFileInZip3
151 (m_zipfile,
152- complete_file.c_str(),
153+ path.c_str(),
154 &zi,
155 0, 0, 0, 0, 0 /* comment*/,
156 Z_DEFLATED,
157@@ -299,10 +286,10 @@
158 break;
159 case ZIP_ERRNO:
160 throw File_error
161- ("ZipFilesystem::MakeDirectory", complete_file, strerror(errno));
162+ ("ZipFilesystem::MakeDirectory", path, strerror(errno));
163 default:
164 throw File_error
165- ("ZipFilesystem::MakeDirectory", complete_file);
166+ ("ZipFilesystem::MakeDirectory", path);
167 }
168
169 zipCloseFileInZip(m_zipfile);
170@@ -382,10 +369,9 @@
171 zi.external_fa = 0;
172
173 // create file
174- std::string const complete_file = m_basename + '/' + fname;
175 switch
176 (zipOpenNewFileInZip3
177- (m_zipfile, complete_file.c_str(), &zi,
178+ (m_zipfile, fname.c_str(), &zi,
179 0, 0, 0, 0, 0 /* comment*/,
180 Z_DEFLATED,
181 Z_BEST_COMPRESSION, 0,
182@@ -396,7 +382,7 @@
183 break;
184 default:
185 throw ZipOperation_error
186- ("ZipFilesystem::Write", complete_file, m_zipfilename);
187+ ("ZipFilesystem::Write", fname, m_zipfilename);
188 }
189
190 switch (zipWriteInFileInZip (m_zipfile, data, length)) {
191@@ -404,10 +390,10 @@
192 break;
193 case ZIP_ERRNO:
194 throw File_error
195- ("ZipFilesystem::Write", complete_file, strerror(errno));
196+ ("ZipFilesystem::Write", fname, strerror(errno));
197 default:
198 throw File_error
199- ("ZipFilesystem::Write", complete_file);
200+ ("ZipFilesystem::Write", fname);
201 }
202
203 zipCloseFileInZip(m_zipfile);
204@@ -481,3 +467,22 @@
205 unsigned long long ZipFilesystem::DiskSpace() {
206 return 0; // FIXME
207 }
208+
209+std::string ZipFilesystem::strip_basename(std::string filename)
210+{
211+
212+ if(filename.compare(0, m_basename.length(), m_basename) == 0)
213+ {
214+ // filename contains the name of the zip file as first element. This means
215+ // this is an old zip file where all data were in a directory named as the
216+ // file inside the zip file.
217+ // return the filename without the first element
218+ m_oldzip = true;
219+ return filename.substr(m_basename.length() + 1);
220+ }
221+
222+ // seems to be a new zipfile without directory or a old zipfile was renamed
223+ m_oldzip = false;
224+ return filename;
225+}
226+
227
228=== modified file 'src/io/filesystem/zip_filesystem.h'
229--- src/io/filesystem/zip_filesystem.h 2010-03-16 20:18:53 +0000
230+++ src/io/filesystem/zip_filesystem.h 2010-10-04 09:18:51 +0000
231@@ -81,6 +81,7 @@
232 void m_OpenUnzip();
233 void m_OpenZip();
234 void m_Close();
235+ std::string strip_basename(std::string);
236
237 private:
238 enum State {
239@@ -92,6 +93,9 @@
240 State m_state;
241 zipFile m_zipfile;
242 unzFile m_unzipfile;
243+ /// if true data is in a directory named as the zipfile. This is set by
244+ /// strip_basename()
245+ bool m_oldzip;
246 std::string m_zipfilename;
247 std::string m_basename;
248

Subscribers

People subscribed via source and target branches

to status/vote changes: