Class: Omnizip::Formats::Rar::RecoveryRecord

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/formats/rar/recovery_record.rb

Overview

RAR recovery record handling Parses and manages recovery records for error correction

Constant Summary collapse

TYPE_INTEGRATED =

Recovery record types

:integrated
TYPE_EXTERNAL =

Inside archive

:external

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(version) ⇒ RecoveryRecord

Initialize recovery record

Parameters:

  • version (Integer)

    RAR version (4 or 5)



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 20

def initialize(version)
  @version = version
  @type = TYPE_INTEGRATED
  @protection_percent = 0
  @block_size = 0
  @recovery_blocks = 0
  @protected_size = 0
  @recovery_size = 0
  @reed_solomon_params = {}
  @external_files = []
end

Instance Attribute Details

#block_sizeObject (readonly)

Returns the value of attribute block_size.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def block_size
  @block_size
end

#external_filesObject (readonly)

Returns the value of attribute external_files.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def external_files
  @external_files
end

#protected_sizeObject (readonly)

Returns the value of attribute protected_size.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def protected_size
  @protected_size
end

#protection_percentObject (readonly)

Returns the value of attribute protection_percent.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def protection_percent
  @protection_percent
end

#recovery_blocksObject (readonly)

Returns the value of attribute recovery_blocks.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def recovery_blocks
  @recovery_blocks
end

#recovery_sizeObject (readonly)

Returns the value of attribute recovery_size.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def recovery_size
  @recovery_size
end

#reed_solomon_paramsObject (readonly)

Returns the value of attribute reed_solomon_params.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def reed_solomon_params
  @reed_solomon_params
end

#typeObject (readonly)

Returns the value of attribute type.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def type
  @type
end

#versionObject (readonly)

Returns the value of attribute version.



9
10
11
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 9

def version
  @version
end

Instance Method Details

#available?Boolean

Check if recovery records are available

Returns:

  • (Boolean)

    true if recovery available



35
36
37
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 35

def available?
  @recovery_blocks.positive? || @external_files.any?
end

#detect_external_files(archive_path) ⇒ Array<String>

Detect external .rev files

Parameters:

  • archive_path (String)

    Path to main archive

Returns:

  • (Array<String>)

    Paths to .rev files



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 65

def detect_external_files(archive_path)
  dir = File.dirname(archive_path)
  basename = File.basename(archive_path, ".*")

  # Check for RAR5 naming (.part01.rar.rev)
  if archive_path.match?(/\.part\d+\.rar$/i)
    detect_rar5_rev_files(dir, archive_path)
  else
    # RAR4 naming (.r00.rev, .r01.rev)
    detect_rar4_rev_files(dir, basename)
  end
end

#external?Boolean

Check if using external .rev files

Returns:

  • (Boolean)

    true if external recovery



42
43
44
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 42

def external?
  @type == TYPE_EXTERNAL
end

#load_external_files(rev_files) ⇒ Object

Load external recovery files

Parameters:

  • rev_files (Array<String>)

    Paths to .rev files



81
82
83
84
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 81

def load_external_files(rev_files)
  @external_files = rev_files.select { |f| File.exist?(f) }
  @type = TYPE_EXTERNAL if @external_files.any?
end

#parse_from_archive(io, flags) ⇒ Boolean

Parse recovery record from archive

Parameters:

  • io (IO)

    Input stream

  • flags (Integer)

    Archive flags

Returns:

  • (Boolean)

    true if recovery record found



51
52
53
54
55
56
57
58
59
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 51

def parse_from_archive(io, flags)
  return false unless recovery_flag_set?(flags)

  if @version == 5
    parse_rar5_recovery(io)
  else
    parse_rar4_recovery(io)
  end
end

#protection_levelFloat

Calculate protection level

Returns:

  • (Float)

    Protection percentage



100
101
102
103
104
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 100

def protection_level
  return 0.0 if @protected_size.zero?

  (@recovery_size.to_f / @protected_size * 100).round(2)
end

#total_recovery_sizeInteger

Get total recovery data size

Returns:

  • (Integer)

    Total recovery bytes



89
90
91
92
93
94
95
# File 'lib/omnizip/formats/rar/recovery_record.rb', line 89

def total_recovery_size
  if external?
    @external_files.sum { |f| File.size(f) }
  else
    @recovery_size
  end
end