module BBS::Zmodem::Frames
Headers read out of the receiverโs bytes: hex headers and binary ones with a CRC-16 or a CRC-32, ZDLE escapes undone, the CRC checked.
Public Instance Methods
Source
# File lib/bbs/zmodem/frames.rb, line 72 def crc_ok?(bytes, crc_size) frame = bytes[0, HEADER_SIZE].pack('C*') crc = bytes[HEADER_SIZE, crc_size] return Zlib.crc32(frame) == crc.pack('C*').unpack1('V') if crc_size == CRC32_SIZE Zmodem.crc16(frame) == ((crc[0] << 8) | crc[1]) end
Whether the CRC of crc_size bytes after the header in bytes is right.
Source
# File lib/bbs/zmodem/frames.rb, line 81 def header_of(bytes) = Header.new(bytes[0], bytes[1, 4])
The Header of the first HEADER_SIZE bytes.
Source
# File lib/bbs/zmodem/frames.rb, line 14 def parse(buf) i = 0 i += 1 while buf[i] == ZPAD return [nil, nil] if i == buf.size return [nil, i] unless buf[i] == ZDLE return [nil, nil] if i + 1 >= buf.size parse_frame(buf, buf[i + 1], i + 2) end
Parses the header at the start of buf (an Array of byte Integers beginning with ZPAD). Returns [header, used]: the Header (nil for a broken one) and the bytes it took, or [nil, nil] when buf ends before the header does.
# File lib/bbs/zmodem/frames.rb, line 49 def parse_bin(buf, from, crc_size) bytes, used = unescape(buf, from, HEADER_SIZE + crc_size) return [nil, nil] unless bytes [(header_of(bytes) if crc_ok?(bytes, crc_size)), used] end
A binary header from from with a CRC of crc_size bytes; see parse.
# File lib/bbs/zmodem/frames.rb, line 26 def parse_frame(buf, kind, from) case kind when ZHEX then parse_hex(buf, from) when ZBIN then parse_bin(buf, from, CRC16_SIZE) when ZBIN32 then parse_bin(buf, from, CRC32_SIZE) else [nil, from - 1] end end
The header of kind kind (ZHEX, ZBIN, ZBIN32) whose bytes start at from; see parse.
Source
# File lib/bbs/zmodem/frames.rb, line 36 def parse_hex(buf, from) to = from + HEX_DIGITS return [nil, nil] if buf.size < to text = buf[from, HEX_DIGITS].pack('C*') return [nil, from] unless text.match?(HEX_HEADER_RE) bytes = [text].pack('H*').bytes [(header_of(bytes) if crc_ok?(bytes, CRC16_SIZE)), to] end
A hex header from from; see parse.
Source
# File lib/bbs/zmodem/frames.rb, line 58 def unescape(buf, from, count) bytes = [] while bytes.size < count step = buf[from] == ZDLE ? 2 : 1 return if from + step > buf.size bytes << (step == 2 ? ZDLE_VALUES.fetch(buf[from + 1]) { |c| c ^ ZDLE_XOR } : buf[from]) from += step end [bytes, from] end
The count bytes from from with the ZDLE escapes undone, and where they end; nil when buf ends first.