ObjFW  Check-in [0bb835712a]

Overview
Comment:ofzip: Support for creating / appending ZIP files
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0bb835712a4781130b01c3fc939cd38424e0684a98864d16c26e540303c48554
User & Date: js on 2017-08-07 22:41:17
Other Links: manifest | tags
Context
2017-08-07
22:46
ofzip: Fix typo in lang/de.json check-in: a0a08492f7 user: js tags: trunk
22:41
ofzip: Support for creating / appending ZIP files check-in: 0bb835712a user: js tags: trunk
00:20
OFTarArchive: More efficient skipping check-in: 29ee511f56 user: js tags: trunk
Changes

Modified utils/ofzip/ZIPArchive.m from [8a0017fc41] to [7af801eda1].

27
28
29
30
31
32
33

34
35
36
37
38
39
40
#import "OFLocalization.h"

#import "ZIPArchive.h"
#import "OFZIP.h"

#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"


static OFZIP *app;

static void
setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS







>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#import "OFLocalization.h"

#import "ZIPArchive.h"
#import "OFZIP.h"

#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfRangeException.h"

static OFZIP *app;

static void
setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
367
368
369
370
371
372
373
















































































































374
				return;
			}
		}

		[stream close];
	}
}
















































































































@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
				return;
			}
		}

		[stream close];
	}
}

- (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files
{
	OFFileManager *fileManager = [OFFileManager defaultManager];

	if ([files count] < 1) {
		[of_stderr writeLine: OF_LOCALIZED(@"add_no_file_specified",
		    @"Need one or more files to add!")];
		app->_exitStatus = 1;
		return;
	}

	for (OFString *localFileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFArray OF_GENERIC (OFString *) *components;
		OFString *fileName;
		bool isDirectory = false;
		OFMutableZIPArchiveEntry *entry;
		of_offset_t size;
		OFStream *output;

		components = [localFileName pathComponents];
		fileName = [components componentsJoinedByString: @"/"];

		if ([fileManager directoryExistsAtPath: localFileName]) {
			isDirectory = true;
			fileName = [fileName stringByAppendingString: @"/"];
		}

		if (app->_outputLevel >= 0)
			[of_stdout writeString: OF_LOCALIZED(@"adding_file",
			    @"Adding %[file]...",
			    @"file", fileName)];

		entry = [OFMutableZIPArchiveEntry entryWithFileName: fileName];

		if (isDirectory)
			size = 0;
		else
			size = [fileManager sizeOfFileAtPath: localFileName];

		if (size > INT64_MAX)
			@throw [OFOutOfRangeException exception];

		[entry setCompressedSize: (int64_t)size];
		[entry setUncompressedSize: (int64_t)size];

		[entry setCompressionMethod:
		    OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE];
		[entry setModificationDate:
		    [fileManager modificationDateOfItemAtPath: localFileName]];

		[entry makeImmutable];

		output = [_archive streamForWritingEntry: entry];

		if (!isDirectory) {
			int64_t written = 0;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (![input isAtEndOfStream]) {
				ssize_t length = [app
				    copyBlockFromStream: input
					       toStream: output
					       fileName: fileName];

				if (length < 0) {
					app->_exitStatus = 1;
					goto outer_loop_end;
				}

				written += length;
				newPercent = (written == size
				    ? 100 : (int8_t)(written * 100 / size));

				if (app->_outputLevel >= 0 &&
				    percent != newPercent) {
					OFString *percentString;

					percent = newPercent;
					percentString = [OFString
					    stringWithFormat: @"%3u", percent];

					[of_stdout writeString: @"\r"];
					[of_stdout writeString: OF_LOCALIZED(
					    @"adding_file_percent",
					    @"Adding %[file]... %[percent]%",
					    @"file", fileName,
					    @"percent", percentString)];
				}
			}
		}

		if (app->_outputLevel >= 0) {
			[of_stdout writeString: @"\r"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"adding_file_done",
			    @"Adding %[file]... done",
			    @"file", fileName)];
		}

		[output close];

outer_loop_end:
		objc_autoreleasePoolPop(pool);
	}

	[_archive close];
}
@end