started working on the bit walker
This commit is contained in:
parent
e3f4b3bdd0
commit
2a07d725bf
95
src/main.zig
95
src/main.zig
@ -20,6 +20,74 @@ fn usage() void {
|
|||||||
exit("", .{}, 1);
|
exit("", .{}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BitWalker = struct {
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
data: *[]u8,
|
||||||
|
position: usize = 0,
|
||||||
|
in_byte_position: u3 = 0,
|
||||||
|
direction: bool = false,
|
||||||
|
|
||||||
|
fn init(data: *[]u8, direction: bool) Self {
|
||||||
|
return Self{
|
||||||
|
.data = data,
|
||||||
|
.direction = direction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO direction
|
||||||
|
fn walk(self: *Self, bits: u3) !u8 {
|
||||||
|
if (bits > 8 or bits == 0) return error.invalid_bit_number;
|
||||||
|
var byte = self.data.ptr[self.position];
|
||||||
|
|
||||||
|
// jumps over bytes
|
||||||
|
if (self.in_byte_position + @as(u4, bits) > 8) {
|
||||||
|
// Generate a mast that covers the last part of the old byte
|
||||||
|
var old_mask: u8 = 0;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < bits - self.in_byte_position) : (i += 1) {
|
||||||
|
old_mask = @shlExact(old_mask, 1) + 1;
|
||||||
|
}
|
||||||
|
old_mask = @shlExact(old_mask, self.in_byte_position);
|
||||||
|
|
||||||
|
var next_byte = self.data.ptr[self.position + 1];
|
||||||
|
var new_byte_pos: u3 = self.in_byte_position + bits % 8;
|
||||||
|
|
||||||
|
var new_mask: u8 = 0;
|
||||||
|
var j: usize = 0;
|
||||||
|
while (j < new_byte_pos) : (j += 1) {
|
||||||
|
new_mask = @shlExact(new_mask, 1) + 1;
|
||||||
|
}
|
||||||
|
print("{} mask: {b}, new_mask", .{ bits, old_mask, new_mask });
|
||||||
|
print("here {b} {b}", .{ byte, old_mask });
|
||||||
|
print("here_new {b} {b}", .{ next_byte, new_mask });
|
||||||
|
|
||||||
|
self.position += 1;
|
||||||
|
self.in_byte_position = new_byte_pos;
|
||||||
|
return byte & old_mask + next_byte & new_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a mast that covers the last part of the old byte
|
||||||
|
var old_mask: u8 = 0;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < bits) : (i += 1) {
|
||||||
|
old_mask = @shlExact(old_mask, 1) + 1;
|
||||||
|
}
|
||||||
|
old_mask = @shlExact(old_mask, self.in_byte_position);
|
||||||
|
|
||||||
|
if (self.in_byte_position + bits == 8) {
|
||||||
|
self.position += 1;
|
||||||
|
self.in_byte_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = @shrExact(byte & old_mask, self.in_byte_position);
|
||||||
|
|
||||||
|
self.in_byte_position += bits;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
||||||
const ZipFileHeader = struct {
|
const ZipFileHeader = struct {
|
||||||
version: u16,
|
version: u16,
|
||||||
@ -92,11 +160,26 @@ const ZipFileHeader = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.uncompressed_content = try self.allocator.alloc(u8, self.uncompressed_size);
|
self.uncompressed_content = try self.allocator.alloc(u8, self.uncompressed_size);
|
||||||
errdefer self.allocator.free(self.uncompressed_size);
|
errdefer self.allocator.free(self.uncompressed_content);
|
||||||
|
|
||||||
|
var bitw = BitWalker.init(&self.compressed_content, false);
|
||||||
|
|
||||||
|
var lastBlock1 = try bitw.walk(1);
|
||||||
|
var blockType1 = try bitw.walk(2);
|
||||||
|
var number_of_literal_codes1 = try bitw.walk(5);
|
||||||
|
var number_of_dist_codes1 = try bitw.walk(5);
|
||||||
|
|
||||||
|
print("{} {} {} {}", .{ lastBlock1, blockType1, number_of_literal_codes1, number_of_dist_codes1 });
|
||||||
|
|
||||||
var byte = self.compressed_content[0];
|
var byte = self.compressed_content[0];
|
||||||
var lastBlock = byte & 0b1000_0000 == 0b1000_0000;
|
var lastBlock = byte & 0b0000_0001 == 0b0000_0001;
|
||||||
var blockType = @shrExact(byte & 0b0110_0000, 5);
|
var blockType = @shrExact(byte & 0b0000_0110, 1);
|
||||||
|
var number_of_literal_codes = @shrExact(byte & 0b1111_1000, 3); // 256
|
||||||
|
byte = self.compressed_content[1];
|
||||||
|
var number_of_dist_codes = byte & 0b0001_1111;
|
||||||
|
var next_byte = self.compressed_content[2];
|
||||||
|
var number_of_length_codes = @shrExact(byte & 0b1110_0000, 5) + @shlExact(next_byte & 0b0000_0001, 3);
|
||||||
|
byte = next_byte;
|
||||||
|
|
||||||
if (lastBlock) {
|
if (lastBlock) {
|
||||||
print("last block", .{});
|
print("last block", .{});
|
||||||
@ -104,12 +187,16 @@ const ZipFileHeader = struct {
|
|||||||
print("not last block", .{});
|
print("not last block", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
print("blockType: {}", .{blockType});
|
print("block_type: {}", .{blockType});
|
||||||
|
|
||||||
if (blockType != 2) {
|
if (blockType != 2) {
|
||||||
return error.unsuported_block_type;
|
return error.unsuported_block_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("number of literal codes: {}", .{number_of_literal_codes});
|
||||||
|
print("number of dist codes: {}", .{number_of_dist_codes});
|
||||||
|
print("number_of_length_coes: {}", .{number_of_length_codes});
|
||||||
|
|
||||||
self.decompressed = true;
|
self.decompressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user