Class: Omnizip::Parity::Models::IfscPacket
- Inherits:
-
Packet
- Object
- Lutaml::Model::Serializable
- Packet
- Omnizip::Parity::Models::IfscPacket
- Defined in:
- lib/omnizip/parity/models/ifsc_packet.rb
Overview
PAR2 IFSC (Input File Slice Checksum) packet
Contains checksums for individual data blocks of a file. One IFSC packet contains checksums for ALL blocks of a file.
Body structure:
- file_id (16 bytes): File identifier
- For each block:
- block_hash (16 bytes): MD5 hash of block data
- block_crc32 (4 bytes, L<): CRC32 of block data
Constant Summary collapse
- PACKET_TYPE =
Packet type identifier
"PAR 2.0\x00IFSC\x00\x00\x00\x00"
Constants inherited from Packet
Instance Attribute Summary
Attributes inherited from Packet
Instance Method Summary collapse
-
#build_body ⇒ String
Build body data from attributes.
-
#initialize(**attributes) ⇒ IfscPacket
constructor
Initialize IFSC 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) ⇒ IfscPacket
Initialize IFSC packet
32 33 34 35 36 37 |
# File 'lib/omnizip/parity/models/ifsc_packet.rb', line 32 def initialize(**attributes) super self.type = PACKET_TYPE self.block_hashes = [] if block_hashes.nil? self.block_crc32s = [] if block_crc32s.nil? end |
Instance Method Details
#build_body ⇒ String
Build body data from attributes
Constructs binary body data
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/omnizip/parity/models/ifsc_packet.rb', line 79 def build_body data = +"" # Validate file_id is 16 bytes if file_id.bytesize != 16 raise ArgumentError, "file_id must be 16 bytes, got #{file_id.bytesize}" end # Write file_id data << file_id # Write all blocks block_hashes.each_with_index do |block_hash, i| # Validate block_hash is 16 bytes if block_hash.bytesize != 16 raise ArgumentError, "block_hash must be 16 bytes, got #{block_hash.bytesize}" end # Write block_hash data << block_hash # Write block_crc32 (4 bytes, little-endian) data << [block_crc32s[i]].pack("L<") end self.body_data = data end |
#parse_body ⇒ Object
Parse body data into attributes
Body format:
- file_id: 16 bytes
- For each block:
- block_hash: 16 bytes
- block_crc32: 4 bytes (L<)
46 47 48 49 50 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/parity/models/ifsc_packet.rb', line 46 def parse_body return if body_data.nil? || body_data.empty? return if body_data.bytesize < 16 pos = 0 # Read file_id (16 bytes) self.file_id = body_data[pos, 16] pos += 16 # Read all blocks (each is 16 bytes hash + 4 bytes CRC = 20 bytes) self.block_hashes = [] self.block_crc32s = [] while pos + 20 <= body_data.bytesize # Read block_hash (16 bytes) block_hash = body_data[pos, 16] pos += 16 # Read block_crc32 (4 bytes, little-endian unsigned 32-bit) block_crc32 = body_data[pos, 4].unpack1("L<") pos += 4 block_hashes << block_hash block_crc32s << block_crc32 end end |