@@ -75,8 +75,9 @@ namespace cage
75
75
{
76
76
CAGE_ASSERT (src->mode ().read && !src->mode ().write && !src->mode ().append && !src->mode ().textual );
77
77
78
+ const uint64 srcSize = src->size ();
78
79
{ // read header
79
- if (src-> size () < sizeof (ArchiveHeader))
80
+ if (srcSize < sizeof (ArchiveHeader))
80
81
return ; // isCarch = false
81
82
src->seek (0 );
82
83
src->read (bufferView<char >(arch));
@@ -87,20 +88,20 @@ namespace cage
87
88
isCarch = true ;
88
89
}
89
90
90
- { // validate content size
91
- if (src-> size () < arch.contentStart + arch.contentSize )
91
+ { // validate sizes
92
+ if (srcSize < arch.contentStart + arch.contentSize )
92
93
{
93
94
CAGE_LOG_THROW (Stringizer () + " archive path: " + myPath);
94
95
CAGE_THROW_ERROR (Exception, " truncated cage archive (content)" );
95
96
}
96
- }
97
-
98
- { // read files list
99
- if (src->size () < arch.listStart + arch.listSize )
97
+ if (srcSize < arch.listStart + arch.listSize )
100
98
{
101
99
CAGE_LOG_THROW (Stringizer () + " archive path: " + myPath);
102
100
CAGE_THROW_ERROR (Exception, " truncated cage archive (list)" );
103
101
}
102
+ }
103
+
104
+ { // read files list
104
105
src->seek (arch.listStart );
105
106
const auto buff = src->read (arch.listSize );
106
107
Deserializer des (buff);
@@ -131,6 +132,20 @@ namespace cage
131
132
ArchiveCarch (ArchiveCarch &&z) = default ;
132
133
133
134
~ArchiveCarch ()
135
+ {
136
+ try
137
+ {
138
+ writeChanges ();
139
+ }
140
+ catch (...)
141
+ {
142
+ CAGE_LOG_THROW (Stringizer () + " error while writing changes to cage archive" );
143
+ CAGE_LOG_THROW (Stringizer () + " archive path: " + myPath);
144
+ throw ;
145
+ }
146
+ }
147
+
148
+ void writeChanges ()
134
149
{
135
150
if (!src)
136
151
return ; // already moved-from
@@ -207,18 +222,8 @@ namespace cage
207
222
src->write (it.second .newContent );
208
223
}
209
224
210
- { // fill the rest of the file with zeros
211
- static constexpr uint64 sz = 16 * 1024 ;
212
- static constexpr char zeros[sz] = {};
213
- uint64 r = src->size () - src->tell ();
214
- while (r > sz)
215
- {
216
- src->write (zeros);
217
- r -= sz;
218
- }
219
- if (r > 0 )
220
- src->write ({ zeros, zeros + sz });
221
- }
225
+ // fill the rest of the file with zeros
226
+ writeZeroes (+src, src->size () - src->tell ());
222
227
223
228
// ensure we wrote to the very end of the file
224
229
CAGE_ASSERT (src->tell () == src->size ());
@@ -271,7 +276,7 @@ namespace cage
271
276
{
272
277
CAGE_LOG_THROW (Stringizer () + " archive path: " + myPath);
273
278
CAGE_LOG_THROW (Stringizer () + " name: " + path);
274
- CAGE_THROW_ERROR (Exception, " cannot create directory inside carch , file already exists" );
279
+ CAGE_THROW_ERROR (Exception, " cannot create directory inside cage archive , file already exists" );
275
280
}
276
281
if (dirs.count (path))
277
282
return ; // directory already exists
@@ -318,7 +323,7 @@ namespace cage
318
323
{
319
324
CAGE_LOG_THROW (Stringizer () + " archive path: " + myPath);
320
325
CAGE_LOG_THROW (Stringizer () + " name: " + from);
321
- CAGE_THROW_ERROR (Exception, " source does not exist" );
326
+ CAGE_THROW_ERROR (Exception, " source file does not exist" );
322
327
}
323
328
if (!copying)
324
329
remove (from);
@@ -351,7 +356,7 @@ namespace cage
351
356
{
352
357
CAGE_ASSERT (!path.empty ());
353
358
CAGE_ASSERT (isPathValid (path));
354
- CAGE_THROW_CRITICAL (Exception, " reading last modification time of a file inside carch archive is not supported" );
359
+ CAGE_THROW_CRITICAL (Exception, " reading last modification time of a file inside cage archive is not supported" );
355
360
}
356
361
357
362
Holder<File> openFile (const String &path, const FileMode &mode) override ;
@@ -378,13 +383,13 @@ namespace cage
378
383
if (mode.write )
379
384
a->reopenForModification ();
380
385
if (a->dirs .count (name))
381
- CAGE_THROW_ERROR (Exception, " cannot open file in carch archive, the path is a directory" );
386
+ CAGE_THROW_ERROR (Exception, " cannot open file in cage archive, the path is a directory" );
382
387
if (a->files .count (name))
383
388
a->throwIfFileLocked (name);
384
389
else
385
390
{
386
391
if (mode.read )
387
- CAGE_THROW_ERROR (Exception, " cannot open file in carch archive, it does not exist" );
392
+ CAGE_THROW_ERROR (Exception, " cannot open file in cage archive, it does not exist" );
388
393
a->createDirectoriesNoLock (pathJoin (name, " .." ));
389
394
}
390
395
@@ -575,4 +580,17 @@ namespace cage
575
580
ArchiveCarch z (std::move (f));
576
581
return z.isCarch ? std::make_shared<ArchiveCarch>(std::move (z)) : std::shared_ptr<ArchiveAbstract>();
577
582
}
583
+
584
+ void writeZeroes (File *f, uint64 size)
585
+ {
586
+ static constexpr uint64 sz = 16 * 1024 ;
587
+ static constexpr char zeros[sz] = {};
588
+ while (size > sz)
589
+ {
590
+ f->write (zeros);
591
+ size -= sz;
592
+ }
593
+ if (size > 0 )
594
+ f->write ({ zeros, zeros + sz });
595
+ }
578
596
}
0 commit comments