started working on the bit walker

This commit is contained in:
Andre Henriques 2023-05-26 23:22:20 +01:00
parent e3f4b3bdd0
commit 2a07d725bf

View File

@ -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;
} }