Class: Omnizip::Formats::Rar::Compression::LZ77Huffman::SlidingWindow

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

Constructor Details

#initialize(size = DEFAULT_SIZE) ⇒ SlidingWindow

Initialize a new sliding window

Parameters:

  • size (Integer) (defaults to: DEFAULT_SIZE)

    Window size in bytes



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.

Parameters:

  • byte (Integer)

    Byte value (0-255)

Raises:

  • (ArgumentError)


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.

Parameters:

  • distance (Integer)

    Backward offset (1 to window_size)

  • length (Integer)

    Number of bytes to copy (1+)

Returns:

  • (Array<Integer>)

    Copied bytes



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

Parameters:

  • offset (Integer)

    Backward offset (1 to window_size)

Returns:

  • (Integer)

    Byte value at offset



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

#positionInteger

Get current window position

Returns:

  • (Integer)

    Current position (0 to size-1)



108
109
110
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 108

def position
  @position
end

#resetvoid

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

#sizeInteger

Get window size

Returns:

  • (Integer)

    Window size in bytes



115
116
117
# File 'lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb', line 115

def size
  @size
end