Class: Omnizip::Formats::Rar::Reader

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/rar/reader.rb

Overview

RAR archive reader Provides read-only access to RAR archives (single and multi-volume)

Constant Summary

Constants included from Constants

Constants::ARCHIVE_AUTH_INFO, Constants::ARCHIVE_COMMENT, Constants::ARCHIVE_ENCRYPTED, Constants::ARCHIVE_FIRST_VOLUME, Constants::ARCHIVE_LOCKED, Constants::ARCHIVE_NEW_NAMING, Constants::ARCHIVE_RECOVERY, Constants::ARCHIVE_SOLID, Constants::ARCHIVE_VOLUME, Constants::BLOCK_ARCHIVE, Constants::BLOCK_COMMENT, Constants::BLOCK_ENDARC, Constants::BLOCK_FILE, Constants::BLOCK_MARKER, Constants::BLOCK_OLD_AUTH, Constants::BLOCK_OLD_EXTRA, Constants::BLOCK_OLD_RECOVERY, Constants::BLOCK_OLD_SUBBLOCK, Constants::BLOCK_SUBBLOCK, Constants::FILE_COMMENT, Constants::FILE_DIRECTORY, Constants::FILE_ENCRYPTED, Constants::FILE_EXT_TIME, Constants::FILE_LARGE, Constants::FILE_SALT, Constants::FILE_SOLID, Constants::FILE_SPLIT_AFTER, Constants::FILE_SPLIT_BEFORE, Constants::FILE_UNICODE, Constants::FILE_VERSION, Constants::METHOD_BEST, Constants::METHOD_FAST, Constants::METHOD_FASTEST, Constants::METHOD_GOOD, Constants::METHOD_NORMAL, Constants::METHOD_STORE, Constants::OS_BEOS, Constants::OS_MACOS, Constants::OS_MSDOS, Constants::OS_OS2, Constants::OS_UNIX, Constants::OS_WIN32, Constants::RAR4_SIGNATURE, Constants::RAR5_FLAG_CHILD_BLOCKS, Constants::RAR5_FLAG_DATA_AREA, Constants::RAR5_FLAG_DATA_INHERITED, Constants::RAR5_FLAG_EXTRA_AREA, Constants::RAR5_FLAG_IS_DIR, Constants::RAR5_FLAG_MULTI_VOLUME, Constants::RAR5_FLAG_UNKNOWN_BLOCKS, Constants::RAR5_HEADER_ENCRYPTION, Constants::RAR5_HEADER_END, Constants::RAR5_HEADER_FILE, Constants::RAR5_HEADER_MAIN, Constants::RAR5_HEADER_SERVICE, Constants::RAR5_SIGNATURE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_path) ⇒ Reader

Initialize reader with file path

Parameters:

  • file_path (String)

    Path to RAR file



19
20
21
22
23
24
25
26
# File 'lib/omnizip/formats/rar/reader.rb', line 19

def initialize(file_path)
  @file_path = file_path
  @header = nil
  @entries = []
  @archive_info = Models::RarArchive.new(file_path)
  @volume_manager = VolumeManager.new(file_path)
  @use_native = true # Prefer native decompression
end

Instance Attribute Details

#archive_infoObject (readonly)

Returns the value of attribute archive_info.



13
14
15
# File 'lib/omnizip/formats/rar/reader.rb', line 13

def archive_info
  @archive_info
end

#entriesObject (readonly)

Returns the value of attribute entries.



13
14
15
# File 'lib/omnizip/formats/rar/reader.rb', line 13

def entries
  @entries
end

#file_pathObject (readonly)

Returns the value of attribute file_path.



13
14
15
# File 'lib/omnizip/formats/rar/reader.rb', line 13

def file_path
  @file_path
end

#headerObject (readonly)

Returns the value of attribute header.



13
14
15
# File 'lib/omnizip/formats/rar/reader.rb', line 13

def header
  @header
end

#volume_managerObject (readonly)

Returns the value of attribute volume_manager.



13
14
15
# File 'lib/omnizip/formats/rar/reader.rb', line 13

def volume_manager
  @volume_manager
end

Instance Method Details

#extract_all(output_dir, password: nil) ⇒ Object

Extract all files to directory

Parameters:

  • output_dir (String)

    Destination directory

  • password (String, nil) (defaults to: nil)

    Optional password

Raises:

  • (RuntimeError)

    on extraction error



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/omnizip/formats/rar/reader.rb', line 79

def extract_all(output_dir, password: nil)
  FileUtils.mkdir_p(output_dir)

  # Use decompressor to extract all
  base_path = @volume_manager.first_volume&.path || @file_path
  Decompressor.extract(base_path, output_dir, password: password)

  # Set timestamps for extracted files
  @entries.each do |entry|
    next unless entry.mtime

    output_path = File.join(output_dir, entry.name)
    next unless File.exist?(output_path)

    File.utime(entry.mtime, entry.mtime, output_path)
  end
end

#extract_entry(entry_name, output_path, password: nil) ⇒ Object

Extract file to output path

Parameters:

  • entry_name (String)

    File name to extract

  • output_path (String)

    Destination path

  • password (String, nil) (defaults to: nil)

    Optional password

Raises:

  • (RuntimeError)

    if entry not found or extraction fails



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/omnizip/formats/rar/reader.rb', line 51

def extract_entry(entry_name, output_path, password: nil)
  entry = @entries.find { |e| e.name == entry_name }
  raise "Entry not found: #{entry_name}" unless entry

  # Create directory if needed
  FileUtils.mkdir_p(File.dirname(output_path))

  # Extract file
  if entry.directory?
    FileUtils.mkdir_p(output_path)
  else
    # Try native decompression first, fall back to external
    if @use_native && native_decompression_available?(entry)
      extract_entry_native(entry, output_path)
    else
      extract_entry_external(entry_name, output_path, password)
    end

    # Set timestamp if available
    File.utime(entry.mtime, entry.mtime, output_path) if entry.mtime
  end
end

#list_filesArray<Models::RarEntry>

List all files in archive

Returns:



41
42
43
# File 'lib/omnizip/formats/rar/reader.rb', line 41

def list_files
  @entries
end

#multi_volume?Boolean

Check if multi-volume archive

Returns:

  • (Boolean)

    true if multi-volume



121
122
123
# File 'lib/omnizip/formats/rar/reader.rb', line 121

def multi_volume?
  @volume_manager.multi_volume? || @header&.is_multi_volume
end

#openObject

Open and parse RAR archive

Raises:

  • (RuntimeError)

    if file cannot be opened or parsed



31
32
33
34
35
36
# File 'lib/omnizip/formats/rar/reader.rb', line 31

def open
  File.open(@file_path, "rb") do |io|
    parse_archive(io)
  end
  self
end

#total_volumesInteger

Get total number of volumes

Returns:

  • (Integer)

    Number of volumes



114
115
116
# File 'lib/omnizip/formats/rar/reader.rb', line 114

def total_volumes
  @volume_manager.volume_count
end

#valid?Boolean

Check if archive is valid RAR format

Returns:

  • (Boolean)

    true if valid



100
101
102
# File 'lib/omnizip/formats/rar/reader.rb', line 100

def valid?
  !@header.nil? && @header.valid?
end

#volumesArray<String>

Get volumes in multi-volume archive

Returns:

  • (Array<String>)

    Volume paths



107
108
109
# File 'lib/omnizip/formats/rar/reader.rb', line 107

def volumes
  @volume_manager.volume_paths
end