struct Header [src]

Fields

descriptor: Descriptor
window_descriptor: ?u8
dictionary_id: ?u32
content_size: ?u64

Members

Source

pub const Header = struct { descriptor: Descriptor, window_descriptor: ?u8, dictionary_id: ?u32, content_size: ?u64, pub const Descriptor = packed struct { dictionary_id_flag: u2, content_checksum_flag: bool, reserved: bool, unused: bool, single_segment_flag: bool, content_size_flag: u2, }; pub const DecodeError = Reader.Error || error{ReservedBitSet}; pub fn decode(in: *Reader) DecodeError!Header { const descriptor: Descriptor = @bitCast(try in.takeByte()); if (descriptor.reserved) return error.ReservedBitSet; const window_descriptor: ?u8 = if (descriptor.single_segment_flag) null else try in.takeByte(); const dictionary_id: ?u32 = if (descriptor.dictionary_id_flag > 0) d: { // if flag is 3 then field_size = 4, else field_size = flag const field_size = (@as(u4, 1) << descriptor.dictionary_id_flag) >> 1; break :d try in.takeVarInt(u32, .little, field_size); } else null; const content_size: ?u64 = if (descriptor.single_segment_flag or descriptor.content_size_flag > 0) c: { const field_size = @as(u4, 1) << descriptor.content_size_flag; const content_size = try in.takeVarInt(u64, .little, field_size); break :c if (field_size == 2) content_size + 256 else content_size; } else null; return .{ .descriptor = descriptor, .window_descriptor = window_descriptor, .dictionary_id = dictionary_id, .content_size = content_size, }; } /// Returns the window size required to decompress a frame, or `null` if it /// cannot be determined (which indicates a malformed frame header). pub fn windowSize(header: Header) ?u64 { if (header.window_descriptor) |descriptor| { const exponent = (descriptor & 0b11111000) >> 3; const mantissa = descriptor & 0b00000111; const window_log = 10 + exponent; const window_base = @as(u64, 1) << @as(u6, @intCast(window_log)); const window_add = (window_base / 8) * mantissa; return window_base + window_add; } else return header.content_size; } }