Class: Omnizip::Algorithms::Zstandard::Frame::Header
- Inherits:
-
Object
- Object
- Omnizip::Algorithms::Zstandard::Frame::Header
- Includes:
- Constants
- Defined in:
- lib/omnizip/algorithms/zstandard/frame/header.rb
Overview
Zstandard frame header parser (RFC 8878 Section 3.1.1.1)
Frame_Header structure:
- Frame_Header_Descriptor: 1 byte
- Window_Descriptor: 0-1 byte (optional)
- Dictionary_ID: 0-4 bytes (optional)
- Frame_Content_Size: 0-8 bytes (optional)
Constant Summary
Constants included from Constants
Constants::BLOCK_HEADER_SIZE, Constants::BLOCK_MAX_SIZE, Constants::BLOCK_TYPE_COMPRESSED, Constants::BLOCK_TYPE_RAW, Constants::BLOCK_TYPE_RESERVED, Constants::BLOCK_TYPE_RLE, Constants::BUFFER_SIZE, Constants::DEFAULT_LEVEL, Constants::DEFAULT_REPEAT_OFFSETS, Constants::FSE_MAX_ACCURACY_LOG, Constants::FSE_MIN_ACCURACY_LOG, Constants::HUFFMAN_MAX_BITS, Constants::HUFFMAN_MAX_CODE_LENGTH, Constants::HUFFMAN_MAX_LOG, Constants::HUFFMAN_STANDARD_TABLE_SIZE, Constants::LITERALS_BLOCK_COMPRESSED, Constants::LITERALS_BLOCK_RAW, Constants::LITERALS_BLOCK_RLE, Constants::LITERALS_BLOCK_TREELESS, Constants::LITERALS_LENGTH_ACCURACY_LOG, Constants::LITERAL_LENGTH_TABLE, Constants::MAGIC_BYTES, Constants::MAGIC_NUMBER, Constants::MATCH_LENGTH_ACCURACY_LOG, Constants::MATCH_LENGTH_TABLE, Constants::MAX_LEVEL, Constants::MIN_LEVEL, Constants::MODE_FSE, Constants::MODE_PREDEFINED, Constants::MODE_REPEAT, Constants::MODE_RLE, Constants::OFFSET_ACCURACY_LOG, Constants::PREDEFINED_LL_DISTRIBUTION, Constants::PREDEFINED_ML_DISTRIBUTION, Constants::PREDEFINED_OFFSET_DISTRIBUTION, Constants::REPEAT_OFFSET_1, Constants::REPEAT_OFFSET_2, Constants::REPEAT_OFFSET_3, Constants::SKIPPABLE_MAGIC_BASE, Constants::SKIPPABLE_MAGIC_MASK, Constants::WINDOW_LOG_MAX, Constants::WINDOW_LOG_MIN
Instance Attribute Summary collapse
-
#checksum_flag ⇒ Integer
readonly
Content checksum flag (bit 2).
-
#content_size ⇒ Integer?
readonly
Frame content size.
-
#content_size_flag ⇒ Integer
readonly
Frame content size flag (bits 6-7).
-
#dictionary_id ⇒ Integer?
readonly
Dictionary ID.
-
#dictionary_id_flag ⇒ Integer
readonly
Dictionary ID flag (bits 0-1).
-
#header_size ⇒ Integer
readonly
Total header size in bytes.
-
#single_segment ⇒ Boolean
readonly
Single segment flag (bit 5).
-
#window_log ⇒ Integer?
readonly
Window log value.
Class Method Summary collapse
-
.parse(input) ⇒ Header
Parse frame header from input.
Instance Method Summary collapse
-
#content_checksum? ⇒ Boolean
Check if content checksum is present.
-
#content_size? ⇒ Boolean
Check if content size is present.
-
#content_size_size ⇒ Integer
Get the size of content size field.
-
#dictionary_id? ⇒ Boolean
Check if dictionary ID is present.
-
#dictionary_id_size ⇒ Integer
Get the size of dictionary ID field.
-
#initialize(descriptor) ⇒ Header
constructor
Initialize with descriptor byte.
-
#parse_content_size(input) ⇒ Object
Parse content size (variable size).
-
#parse_dictionary_id(input) ⇒ Object
Parse dictionary ID (variable size).
-
#parse_window_descriptor(input) ⇒ Object
Parse window descriptor byte.
-
#window_descriptor? ⇒ Boolean
Check if window descriptor is present.
-
#window_size ⇒ Integer?
Get window size.
Constructor Details
#initialize(descriptor) ⇒ Header
Initialize with descriptor byte
89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 89 def initialize(descriptor) @descriptor = descriptor # Extract flags from descriptor byte @content_size_flag = (descriptor >> 6) & 0x03 @single_segment = (descriptor >> 5).allbits?(0x01) @checksum_flag = (descriptor >> 2) & 0x01 @dictionary_id_flag = descriptor & 0x03 @window_log = nil @dictionary_id = nil @content_size = nil @header_size = 1 end |
Instance Attribute Details
#checksum_flag ⇒ Integer (readonly)
Returns Content checksum flag (bit 2).
44 45 46 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 44 def checksum_flag @checksum_flag end |
#content_size ⇒ Integer? (readonly)
Returns Frame content size.
56 57 58 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 56 def content_size @content_size end |
#content_size_flag ⇒ Integer (readonly)
Returns Frame content size flag (bits 6-7).
38 39 40 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 38 def content_size_flag @content_size_flag end |
#dictionary_id ⇒ Integer? (readonly)
Returns Dictionary ID.
53 54 55 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 53 def dictionary_id @dictionary_id end |
#dictionary_id_flag ⇒ Integer (readonly)
Returns Dictionary ID flag (bits 0-1).
47 48 49 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 47 def dictionary_id_flag @dictionary_id_flag end |
#header_size ⇒ Integer (readonly)
Returns Total header size in bytes.
59 60 61 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 59 def header_size @header_size end |
#single_segment ⇒ Boolean (readonly)
Returns Single segment flag (bit 5).
41 42 43 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 41 def single_segment @single_segment end |
#window_log ⇒ Integer? (readonly)
Returns Window log value.
50 51 52 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 50 def window_log @window_log end |
Class Method Details
.parse(input) ⇒ Header
Parse frame header from input
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 65 def self.parse(input) descriptor = input.read(1).ord header = new(descriptor) # Parse optional fields based on descriptor bits if header.window_descriptor? header.parse_window_descriptor(input) end if header.dictionary_id? header.parse_dictionary_id(input) end if header.content_size? header.parse_content_size(input) end header end |
Instance Method Details
#content_checksum? ⇒ Boolean
Check if content checksum is present
128 129 130 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 128 def content_checksum? @checksum_flag == 1 end |
#content_size? ⇒ Boolean
Check if content size is present
121 122 123 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 121 def content_size? @content_size_flag != 0 || @single_segment end |
#content_size_size ⇒ Integer
Get the size of content size field
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 147 def content_size_size if @single_segment # For single segment, FCS size depends on content_size_flag case @content_size_flag when 0 then 1 when 1 then 2 when 2 then 4 when 3 then 8 end else case @content_size_flag when 0 then 0 when 1 then 2 when 2 then 4 when 3 then 8 end end end |
#dictionary_id? ⇒ Boolean
Check if dictionary ID is present
114 115 116 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 114 def dictionary_id? @dictionary_id_flag != 0 end |
#dictionary_id_size ⇒ Integer
Get the size of dictionary ID field
135 136 137 138 139 140 141 142 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 135 def dictionary_id_size case @dictionary_id_flag when 0 then 0 when 1 then 1 when 2 then 2 when 3 then 4 end end |
#parse_content_size(input) ⇒ Object
Parse content size (variable size)
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 201 def parse_content_size(input) size = content_size_size bytes = input.read(size) @content_size = case size when 1 then bytes.ord when 2 then bytes.unpack1("v") when 4 then bytes.unpack1("V") when 8 low, high = bytes.unpack("VV") low + (high << 32) end @header_size += size end |
#parse_dictionary_id(input) ⇒ Object
Parse dictionary ID (variable size)
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 187 def parse_dictionary_id(input) size = dictionary_id_size bytes = input.read(size) @dictionary_id = case size when 1 then bytes.ord when 2 then bytes.unpack1("v") when 4 then bytes.unpack1("V") end @header_size += size end |
#parse_window_descriptor(input) ⇒ Object
Parse window descriptor byte
178 179 180 181 182 183 184 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 178 def parse_window_descriptor(input) byte = input.read(1).ord exponent = (byte >> 3) & 0x1F byte & 0x07 @window_log = 10 + exponent @header_size += 1 end |
#window_descriptor? ⇒ Boolean
Check if window descriptor is present
107 108 109 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 107 def window_descriptor? !@single_segment end |
#window_size ⇒ Integer?
Get window size
169 170 171 172 173 174 175 |
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 169 def window_size return nil unless @window_log @window_log - 10 mantissa = @window_log < 22 ? (@window_log - 10) : (@window_log - 11) (1 << @window_log) + (mantissa << (@window_log - 4)) end |