Class: Omnizip::Formats::Rar::Compression::LZ77Huffman::SlidingWindow
- Inherits:
-
Object
- Object
- Omnizip::Formats::Rar::Compression::LZ77Huffman::SlidingWindow
- Defined in:
- lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb
Overview
Sliding window buffer for LZ77 compression
Provides a circular buffer that stores previously decoded bytes for LZ77 match copying. The window allows looking back at previously decoded data to resolve distance-length match pairs.
Responsibilities:
- ONE responsibility: Window buffer management
- Store decoded bytes in circular buffer
- Copy matches from window offset
- Handle window wrap-around
- Efficient lookback for match resolution
RAR LZ77 Window Sizes:
- RAR3: 32KB (32 * 1024 bytes)
- RAR4: 64KB (64 * 1024 bytes)
- RAR5: Up to 1GB (dynamic)
Constant Summary collapse
- DEFAULT_SIZE =
Default window size (64KB for RAR4)
64 * 1024
Instance Method Summary collapse
-
#add_byte(byte) ⇒ void
Add a single byte to the window.
-
#copy_match(distance, length) ⇒ Array<Integer>
Copy a match from the window.
-
#get_byte_at_offset(offset) ⇒ Integer
Get byte at specific offset from current position.
-
#initialize(size = DEFAULT_SIZE) ⇒ SlidingWindow
constructor
Initialize a new sliding window.
-
#position ⇒ Integer
Get current window position.
-
#reset ⇒ void
Reset window to initial state.
-
#size ⇒ Integer
Get window size.
Constructor Details
#initialize(size = DEFAULT_SIZE) ⇒ SlidingWindow
Initialize a new sliding window
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 52 def initialize(size = DEFAULT_SIZE) unless size.positive? raise ArgumentError, "Window size must be positive" end @size = size @buffer = Array.new(size, 0) @position = 0 end |
Instance Method Details
#add_byte(byte) ⇒ void
This method returns an undefined value.
Add a single byte to the window
Stores the byte at the current position and advances. When position reaches window size, it wraps around to 0.
70 71 72 73 74 75 76 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 70 def add_byte(byte) raise ArgumentError, "Byte must be 0-255" unless byte.between?(0, 255) @buffer[@position] = byte @position = (@position + 1) % @size end |
#copy_match(distance, length) ⇒ Array<Integer>
Copy a match from the window
Copies bytes from a backward offset (distance) and returns them as an array. This is used to resolve LZ77 match pairs.
The match can overlap with the current position (e.g., when distance < length), which is handled byte-by-byte.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 89 def copy_match(distance, length) validate_match_params(distance, length) result = [] start_pos = (@position - distance) % @size length.times do |i| copy_pos = (start_pos + i) % @size byte = @buffer[copy_pos] result << byte add_byte(byte) # Add to window as we copy end result end |
#get_byte_at_offset(offset) ⇒ Integer
Get byte at specific offset from current position
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 123 def get_byte_at_offset(offset) unless offset.between?( 1, @size ) raise ArgumentError, "Offset must be 1 to #{@size}" end pos = (@position - offset) % @size @buffer[pos] end |
#position ⇒ Integer
Get current window position
108 109 110 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 108 def position @position end |
#reset ⇒ void
This method returns an undefined value.
Reset window to initial state
138 139 140 141 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 138 def reset @buffer.fill(0) @position = 0 end |
#size ⇒ Integer
Get window size
115 116 117 |
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 115 def size @size end |