Class: Omnizip::Parity::Models::FileDescriptionPacket
- Inherits:
-
Packet
- Object
- Lutaml::Model::Serializable
- Packet
- Omnizip::Parity::Models::FileDescriptionPacket
- Defined in:
- lib/omnizip/parity/models/file_description_packet.rb
Overview
PAR2 File Description packet
Contains metadata about a protected file including hashes and filename.
Body structure:
- file_id (16 bytes): MD5 hash identifying the file
- file_hash (16 bytes): MD5 hash of complete file content
- file_hash_16k (16 bytes): MD5 hash of first 16KB
- length (8 bytes, Q<): File size in bytes
- filename (variable): Null-terminated filename, padded to multiple of 4
Constant Summary collapse
- PACKET_TYPE =
Packet type identifier
"PAR 2.0\x00FileDesc"
Constants inherited from Packet
Instance Attribute Summary
Attributes inherited from Packet
Instance Method Summary collapse
-
#basename ⇒ String
Get basename of file.
-
#build_body ⇒ String
Build body data from attributes.
-
#initialize(**attributes) ⇒ FileDescriptionPacket
constructor
Initialize file description packet.
-
#parse_body ⇒ Object
Parse body data into attributes.
Methods inherited from Packet
#calculate_hash, #packet_type, read_from, #valid_hash?, #write_to
Constructor Details
#initialize(**attributes) ⇒ FileDescriptionPacket
Initialize file description packet
38 39 40 41 |
# File 'lib/omnizip/parity/models/file_description_packet.rb', line 38 def initialize(**attributes) super self.type = PACKET_TYPE end |
Instance Method Details
#basename ⇒ String
Get basename of file
125 126 127 |
# File 'lib/omnizip/parity/models/file_description_packet.rb', line 125 def basename File.basename(filename) end |
#build_body ⇒ String
Build body data from attributes
Constructs binary body data with proper padding
91 92 93 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 |
# File 'lib/omnizip/parity/models/file_description_packet.rb', line 91 def build_body data = +"" # Validate file_id, file_hash, file_hash_16k are 16 bytes [file_id, file_hash, file_hash_16k].each_with_index do |hash, idx| field_name = %w[file_id file_hash file_hash_16k][idx] if hash.bytesize != 16 raise ArgumentError, "#{field_name} must be 16 bytes, got #{hash.bytesize}" end end # Write hashes data << file_id data << file_hash data << file_hash_16k # Write length (8 bytes, little-endian) data << [length].pack("Q<") # Write filename (null-terminated, padded to multiple of 4) data << filename data << "\x00" # Add padding to make total length multiple of 4 padding = (4 - ((filename.bytesize + 1) % 4)) % 4 data << ("\x00" * padding) if padding.positive? self.body_data = data end |
#parse_body ⇒ Object
Parse body data into attributes
Body format:
- file_id: 16 bytes
- file_hash: 16 bytes
- file_hash_16k: 16 bytes
- length: 8 bytes (Q<)
- filename: null-terminated, padded to multiple of 4
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/omnizip/parity/models/file_description_packet.rb', line 51 def parse_body return if body_data.nil? || body_data.empty? # Validate minimum size (16+16+16+8 = 56 bytes minimum) if body_data.bytesize < 56 warn "FileDescriptionPacket body too short: #{body_data.bytesize} bytes" return end pos = 0 # Read file_id (16 bytes) self.file_id = body_data[pos, 16] pos += 16 # Read file_hash (16 bytes) self.file_hash = body_data[pos, 16] pos += 16 # Read file_hash_16k (16 bytes) self.file_hash_16k = body_data[pos, 16] pos += 16 # Read length (8 bytes, little-endian unsigned 64-bit) length_data = body_data[pos, 8] return if length_data.nil? || length_data.bytesize < 8 self.length = length_data.unpack1("Q<") pos += 8 # Read filename (null-terminated, remaining bytes) filename_data = body_data[pos..] self.filename = filename_data&.unpack1("Z*") || "" end |