diff options
author | Martin Ashby <martin@ashbysoft.com> | 2023-09-14 19:39:17 +0100 |
---|---|---|
committer | Martin Ashby <martin@ashbysoft.com> | 2023-09-14 19:39:17 +0100 |
commit | e865ded59cd6ad32aff6b7e58fd7e62aea8cf087 (patch) | |
tree | 8a4c6bcb73526525a56c20816286aceb3941e94b /src | |
parent | 710f88225a69da941d8374dc29f91da42ca58091 (diff) | |
download | zip-zig-e865ded59cd6ad32aff6b7e58fd7e62aea8cf087.tar.gz zip-zig-e865ded59cd6ad32aff6b7e58fd7e62aea8cf087.tar.bz2 zip-zig-e865ded59cd6ad32aff6b7e58fd7e62aea8cf087.tar.xz zip-zig-e865ded59cd6ad32aff6b7e58fd7e62aea8cf087.zip |
foo
Diffstat (limited to 'src')
-rw-r--r-- | src/main.zig | 101 |
1 files changed, 62 insertions, 39 deletions
diff --git a/src/main.zig b/src/main.zig index d5345f0..ed52f53 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,8 @@ const std = @import("std"); const testing = std.testing; +// https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.10.TXT + const ZipFile = struct { // [local file header 1] // [encryption header 1] @@ -144,61 +146,82 @@ const Zip64EndOfCentralDirectoryLocator = struct { const EndOfCentralDirectoryRecord = packed struct { const SIG: u32 = 0x06054b50; - // end of central dir signature 4 bytes (0x06054b50) - sig: u32 = SIG, + // // end of central dir signa SIG: u32 = 0x06054b50;ure 4 bytes (0x06054b50) + sig: u32 = SIG, // 504b0506 // number of this disk 2 bytes - disk_number_this: u16, + disk_number_this: u16, // 0000 // number of the disk with the // start of the central directory 2 bytes - disk_number_central_dir_start: u16, + disk_number_central_dir_start: u16, // 0000 // total number of entries in the // central directory on this disk 2 bytes - total_central_dir_entries_on_this_disk: u16, + total_central_dir_entries_on_this_disk: u16, // 0100 // total number of entries in // the central directory 2 bytes - total_central_dir_entries: u16, + total_central_dir_entries: u16, // 0100 // size of the central directory 4 bytes - size_of_central_dir: u32, + size_of_central_dir: u32, // 4f000000 // offset of start of central // directory with respect to // the starting disk number 4 bytes - central_dir_offset: u32, + central_dir_offset: u32, // 4e000000 // .ZIP file comment length 2 bytes - comment_length: u16, + comment_length: u16, // 0000 // .ZIP file comment (variable size) // comment: [*]u8, - // fn comment_slice(self: EndOfCentralDirectoryRecord) []u8 { - // return self.comment[0..self.comment_length]; - // } + fn from(bytes: []const u8) !EndOfCentralDirectoryRecord { + var fbs = std.io.fixedBufferStream(bytes); + var rr = fbs.reader(); + return EndOfCentralDirectoryRecord{ + .sig = try rr.readIntLittle(u32), + .disk_number_this = try rr.readIntLittle(u16), + .disk_number_central_dir_start = try rr.readIntLittle(u16), + .total_central_dir_entries_on_this_disk = try rr.readIntLittle(u16), + .total_central_dir_entries = try rr.readIntLittle(u16), + .size_of_central_dir = try rr.readIntLittle(u32), + .central_dir_offset = try rr.readIntLittle(u32), + .comment_length = try rr.readIntLittle(u16), + // .comment = rr.read() + }; + } }; test "foo" { - var mapped_mem: ?[]align(std.mem.page_size) u8 = null; - { - var file = try std.fs.cwd().openFile("src/hello.zip", .{}); - errdefer file.close(); - const file_len = std.math.cast(usize, try file.getEndPos()) orelse std.math.maxInt(usize); - mapped_mem = try std.os.mmap( - null, - file_len, - std.os.PROT.READ, - std.os.MAP.SHARED, - file.handle, - 0, - ); - file.close(); - } - var mm = mapped_mem orelse return error.MMapFailed; - defer std.os.munmap(mm); - const cdr_search_start = if (mm.len < 64_000) 0 else mm.len - 64_000; - const needle: [4]u8 = @bitCast(CentralDirectoryHeader.SIG); - const eocdr_start = std.mem.indexOf(u8, mm[cdr_search_start..], &needle) orelse return error.EocdrNotFound; - const eocdr: *EndOfCentralDirectoryRecord = @ptrCast(@alignCast(mm[eocdr_start .. eocdr_start + @sizeOf(EndOfCentralDirectoryRecord)])); - std.log.err("needle: {} eocdr_start {} comment_length {}", .{ std.fmt.fmtSliceHexLower(&needle), eocdr_start, eocdr.comment_length }); - - const hh_p: *u32 = @ptrCast(mm[0..4].ptr); - const hh = hh_p.*; - try std.testing.expectEqual(LocalFileHeader.SIG, hh); - // std.log.err("mapped_mem len {} first 5 bytes {}", .{mm.len, std.fmt.fmtSliceHexUpper(mm[0..5])}); + const test_zip = @embedFile("hello.zip"); + var fbs = std.io.fixedBufferStream(test_zip); + + const eocdr_search_width_max: usize = 64_000; + var eocdr_search_buf: [eocdr_search_width_max]u8 = undefined; + + const epos = try fbs.getEndPos(); + const eocdr_search_width: usize = @min(epos, eocdr_search_width_max); + const eocdr_seek_start: usize = epos - eocdr_search_width; + + std.log.err("epos {}", .{epos}); + std.log.err("eocdr_search_width {}", .{eocdr_search_width}); + std.log.err("eocdr_seek_start {}", .{eocdr_seek_start}); + + try fbs.seekTo(eocdr_seek_start); + const eocdr_did_read = try fbs.read(&eocdr_search_buf); + std.log.err("eocdr_did_read {}", .{eocdr_did_read}); + const needle: [4]u8 = @bitCast(EndOfCentralDirectoryRecord.SIG); + const eocdr_start = std.mem.indexOf(u8, eocdr_search_buf[0..eocdr_search_width], &needle) orelse return error.NoEndOfCentralDirectoryRecord; + std.log.err("eocdr_start {}", .{eocdr_start}); + try fbs.seekTo(eocdr_start); + const eocdr_pos = try fbs.getPos(); + std.log.err("eocdr_pos {}", .{eocdr_pos}); + + // const eocdr = try fbs.reader().readStruct(EndOfCentralDirectoryRecord); + // _ = eocdr; + // _ = eocdr; + var rr = fbs.reader(); + const eocdrb = try rr.readAllAlloc(std.testing.allocator, 10_000_000); + defer std.testing.allocator.free(eocdrb); + const eocdr = try EndOfCentralDirectoryRecord.from(eocdrb); + _ = eocdr; + // const comment = try rr.readAllAlloc(std.testing.allocator, eocdr.comment_length); + // defer std.testing.allocator.free(comment); + std.log.err("eocdrb {} len {}", .{ std.fmt.fmtSliceHexLower(eocdrb), eocdrb.len }); + std.log.err("sz {}", .{@sizeOf(EndOfCentralDirectoryRecord)}); } |