Class: Omnizip::Parity::Par2Creator

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/parity/par2_creator.rb

Overview

PAR2 parity archive creator

Creates PAR2 recovery files using Reed-Solomon error correction. PAR2 files allow recovery of corrupted or missing data blocks.

Examples:

Create PAR2 files for an archive

creator = Par2Creator.new(redundancy: 10, block_size: 16384)
creator.add_file('important.zip')
creator.create('important')
# Creates: important.par2, important.vol00+01.par2, etc.

Multiple files with custom settings

creator = Par2Creator.new(
  redundancy: 5,
  block_size: 32768,
  progress: ->(pct) { puts "Progress: #{pct}%" }
)
creator.add_file('file1.dat')
creator.add_file('file2.dat')
creator.create('backup')

Defined Under Namespace

Classes: FileInfo

Constant Summary collapse

PACKET_SIGNATURE =

PAR2 packet signature

"PAR2\x00PKT".b.freeze
PACKET_TYPE_MAIN =

Packet type identifiers

"PAR 2.0\x00Main\x00\x00\x00\x00"
PACKET_TYPE_FILE_DESC =
"PAR 2.0\x00FileDesc"
PACKET_TYPE_IFSC =
"PAR 2.0\x00IFSC\x00\x00\x00\x00"
PACKET_TYPE_RECOVERY =
"PAR 2.0\x00RecvSlic"
DEFAULT_BLOCK_SIZE =

Default block size (16KB)

16384

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(redundancy: 5, block_size: DEFAULT_BLOCK_SIZE, progress: nil) ⇒ Par2Creator

Initialize PAR2 creator

Parameters:

  • redundancy (Integer) (defaults to: 5)

    Redundancy percentage (0-100)

  • block_size (Integer) (defaults to: DEFAULT_BLOCK_SIZE)

    Block size in bytes

  • progress (Proc, nil) (defaults to: nil)

    Progress callback proc



69
70
71
72
73
74
75
76
# File 'lib/omnizip/parity/par2_creator.rb', line 69

def initialize(redundancy: 5, block_size: DEFAULT_BLOCK_SIZE,
progress: nil)
  @redundancy = validate_redundancy(redundancy)
  @block_size = validate_block_size(block_size)
  @progress_callback = progress
  @files = []
  @set_id = generate_set_id
end

Instance Attribute Details

#block_sizeInteger (readonly)

Returns Block size in bytes.

Returns:

  • (Integer)

    Block size in bytes



42
43
44
# File 'lib/omnizip/parity/par2_creator.rb', line 42

def block_size
  @block_size
end

#filesArray<Hash> (readonly)

Returns Files to protect.

Returns:

  • (Array<Hash>)

    Files to protect



48
49
50
# File 'lib/omnizip/parity/par2_creator.rb', line 48

def files
  @files
end

#progress_callbackProc? (readonly)

Returns Progress callback.

Returns:

  • (Proc, nil)

    Progress callback



51
52
53
# File 'lib/omnizip/parity/par2_creator.rb', line 51

def progress_callback
  @progress_callback
end

#redundancyInteger (readonly)

Returns Redundancy percentage (0-100).

Returns:

  • (Integer)

    Redundancy percentage (0-100)



45
46
47
# File 'lib/omnizip/parity/par2_creator.rb', line 45

def redundancy
  @redundancy
end

Instance Method Details

#add_file(file_path) ⇒ Object

Add file to PAR2 set

Parameters:

  • file_path (String)

    Path to file

Raises:

  • (ArgumentError)

    if file doesn't exist



82
83
84
85
86
87
88
# File 'lib/omnizip/parity/par2_creator.rb', line 82

def add_file(file_path)
  raise ArgumentError, "File not found: #{file_path}" unless
    File.exist?(file_path)

  file_info = analyze_file(file_path)
  @files << file_info
end

#create(base_name) ⇒ Array<String>

Create PAR2 recovery files

Parameters:

  • base_name (String)

    Base name for PAR2 files

Returns:

  • (Array<String>)

    Paths to created PAR2 files



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/omnizip/parity/par2_creator.rb', line 94

def create(base_name)
  validate_files!

  # CRITICAL FIX: Sort files by file_id (MD5 hash) to match PAR2 spec
  # Par2cmdline creates recovery blocks with files sorted by file_id MD5.
  # The verifier also sorts by file_id, so ALL operations
  # (file descriptions, IFSC packets, recovery blocks) must use the same order.
  @files.sort_by!(&:file_id)

  # Calculate total blocks and recovery blocks needed
  total_blocks = calculate_total_blocks
  recovery_blocks = calculate_recovery_blocks(total_blocks)

  report_progress(0, "Initializing PAR2 creation")

  # Create main PAR2 index file
  index_file = create_index_file(base_name)

  # Create recovery volume files
  volume_files = create_recovery_volumes(
    base_name,
    recovery_blocks,
    total_blocks,
  )

  report_progress(100, "PAR2 creation complete")

  [index_file] + volume_files
end