module Binascii::Hqx

Constants

A2B_TABLE
B2A_TABLE
CRC_TABLE
RLE_RUN_CHAR

Public Instance Methods

a2b_hqx(str) click to toggle source
# File lib/binascii/hqx.rb, line 84
def a2b_hqx(str)
  result = String.new('', encoding: 'ASCII-8BIT')
  bits = 0
  buffer = 0
  pos = 0
  done = 0

  str.each_byte do |byte|
    ch = A2B_TABLE[byte]

    if ch == :fail
      raise DecodeError, "Illegal character at position #{pos}"
    elsif ch == :done
      done = 1
      break
    end

    buffer = (buffer << 6) | ch
    bits += 6

    if bits >= 8
      bits -= 8
      result << ((buffer >> bits) & 0xFF)
      buffer &= ((1 << bits) - 1)
    end

    pos += 1
  end

  if bits > 0 && done == 0
    raise DecodeError, 'String has incomplete number of bytes'
  end

  [result, done]
end
b2a_hqx(data) click to toggle source
# File lib/binascii/hqx.rb, line 120
def b2a_hqx(data)
  String.new('', encoding: 'ASCII-8BIT').tap do |result|
    bits = 0
    buffer = 0

    data.each_byte do |byte|
      buffer = (buffer << 8) | byte
      bits += 8

      while bits >= 6
        ch = (buffer >> (bits - 6)) & 0x3F
        result << B2A_TABLE[ch]
        bits -= 6
      end
    end

    if bits > 0
      buffer <<= (6 - bits)
      result << B2A_TABLE[buffer & 0x3F]
    end
  end
end
crc_hqx(data, crc = 0) click to toggle source
# File lib/binascii/hqx.rb, line 215
def crc_hqx(data, crc = 0)
  crc &= 0xFFFF
  len = data.bytesize

  data.each_byte do |byte|
    crc = ((crc << 8) & 0xFF00) ^ CRC_TABLE[(crc >> 8) ^ byte]
  end

  crc
end
rlecode_hqx(data) click to toggle source
# File lib/binascii/hqx.rb, line 143
def rlecode_hqx(data)
  String.new('', encoding: 'ASCII-8BIT').tap do |result|
    len = data.bytesize
    pos = 0

    while pos < len
      byte = data.getbyte(pos)

      if byte == RLE_RUN_CHAR
        result << RLE_RUN_CHAR
        result << 0
      else
        count = 0
        (len - pos).times do |i|
          break if count >= 255
          break if data.getbyte(pos + i) != byte
          count += 1
        end

        result << byte

        if count > 3
          result << RLE_RUN_CHAR
          result << count
          pos += count - 1
        end
      end

      pos += 1
    end
  end
end
rledecode_hqx(data) click to toggle source
# File lib/binascii/hqx.rb, line 176
def rledecode_hqx(data)
  String.new('', encoding: 'ASCII-8BIT').tap do |result|
    len = data.bytesize
    last_byte = data.getbyte(0)

    if last_byte == RLE_RUN_CHAR
      raise DecodeError, 'Orphaned RLE code at start'
    end

    result << last_byte
    pos = 1

    while pos < len
      byte = data.getbyte(pos)

      if byte == RLE_RUN_CHAR
        count = data.getbyte(pos + 1)

        if count == 0
          # indicates an escaped RLE_RUN_CHAR, so output it
          result << RLE_RUN_CHAR
        else
          # one less than count because we have already outputted the
          # character once during the previous iteration
          result << (last_byte.chr * (count - 1))
        end

        # skip count
        pos += 1
      else
        result << byte
      end

      last_byte = byte
      pos += 1
    end
  end
end