Class: Omnizip::Algorithms::Zstandard::Frame::Header

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(descriptor) ⇒ Header

Initialize with descriptor byte

Parameters:

  • descriptor (Integer)

    Frame header 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_flagInteger (readonly)

Returns Content checksum flag (bit 2).

Returns:

  • (Integer)

    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_sizeInteger? (readonly)

Returns Frame content size.

Returns:

  • (Integer, nil)

    Frame content size



56
57
58
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 56

def content_size
  @content_size
end

#content_size_flagInteger (readonly)

Returns Frame content size flag (bits 6-7).

Returns:

  • (Integer)

    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_idInteger? (readonly)

Returns Dictionary ID.

Returns:

  • (Integer, nil)

    Dictionary ID



53
54
55
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 53

def dictionary_id
  @dictionary_id
end

#dictionary_id_flagInteger (readonly)

Returns Dictionary ID flag (bits 0-1).

Returns:

  • (Integer)

    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_sizeInteger (readonly)

Returns Total header size in bytes.

Returns:

  • (Integer)

    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_segmentBoolean (readonly)

Returns Single segment flag (bit 5).

Returns:

  • (Boolean)

    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_logInteger? (readonly)

Returns Window log value.

Returns:

  • (Integer, nil)

    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

Parameters:

  • input (IO)

    Input stream positioned at frame header

Returns:



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

Returns:

  • (Boolean)


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

Returns:

  • (Boolean)


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_sizeInteger

Get the size of content size field

Returns:

  • (Integer)


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

Returns:

  • (Boolean)


114
115
116
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 114

def dictionary_id?
  @dictionary_id_flag != 0
end

#dictionary_id_sizeInteger

Get the size of dictionary ID field

Returns:

  • (Integer)


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

Returns:

  • (Boolean)


107
108
109
# File 'lib/omnizip/algorithms/zstandard/frame/header.rb', line 107

def window_descriptor?
  !@single_segment
end

#window_sizeInteger?

Get window size

Returns:

  • (Integer, nil)

    Window size or nil if not applicable



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