module Rencoder::Decoder

Rencode format decoder module

Constants

INTEGER_DECODING_MAP

Public Instance Methods

decode(buffer) click to toggle source
# File lib/rencoder/decoder.rb, line 13
def decode(buffer)
  buffer = StringIO.new(buffer) unless buffer.respond_to?(:read) # IO object

  type = buffer.readbyte

  case type
  when STR_HEADER, STR_FIXED
    decode_string(buffer, type)
  when CHR_INT, CHR_INT1, CHR_INT2, CHR_INT4, CHR_INT8, INT_POS_FIXED, INT_NEG_FIXED
    decode_integer(buffer, type)
  when CHR_FLOAT32, CHR_FLOAT64
    decode_float(buffer, type)
  when CHR_TRUE, CHR_FALSE
    decode_boolean(buffer, type)
  when CHR_NONE
    decode_nil(buffer, type)
  when CHR_LIST, LIST_FIXED
    decode_array(buffer, type)
  when CHR_DICT, DICT_FIXED
    decode_hash(buffer, type)
  when CHR_TERM
    :rencode_term
  else
    raise "Unknown type '#{type.inspect}'"
  end
end

Private Instance Methods

decode_array(buffer, type) click to toggle source
# File lib/rencoder/decoder.rb, line 81
def decode_array(buffer, type)
  case type
  when CHR_LIST
    result = []

    while (item = decode(buffer)) != :rencode_term
      result << item
    end

    result
  when LIST_FIXED
    size = type - LIST_FIXED_START

    size.times.map do |_i|
      decode(buffer)
    end
  end
end
decode_boolean(_buffer, type) click to toggle source
# File lib/rencoder/decoder.rb, line 77
def decode_boolean(_buffer, type)
  type == CHR_TRUE
end
decode_float(buffer, type) click to toggle source
# File lib/rencoder/decoder.rb, line 57
def decode_float(buffer, type)
  case type
  when CHR_FLOAT32
    buffer.read(4).unpack('g')
  when CHR_FLOAT64
    buffer.read(8).unpack('G')
  end.first
end
decode_hash(buffer, type) click to toggle source
# File lib/rencoder/decoder.rb, line 100
def decode_hash(buffer, type)
  case type
  when CHR_DICT
    result = {}

    while (key = decode(buffer)) != :rencode_term
      result[key] = decode(buffer)
    end

    result
  when DICT_FIXED
    size = type - DICT_FIXED_START

    Hash[size.times.map { [decode(buffer), decode(buffer)] }]
  end
end
decode_integer(buffer, type) click to toggle source
# File lib/rencoder/decoder.rb, line 42
def decode_integer(buffer, type)
  case type
  when CHR_INT
    read_till(buffer).to_i
  when CHR_INT1, CHR_INT2, CHR_INT4, CHR_INT8
    size, template = INTEGER_DECODING_MAP[type]

    buffer.read(size).unpack1(template)
  when INT_POS_FIXED
    type - INT_POS_FIXED_START
  when INT_NEG_FIXED
    -1 - (type - INT_NEG_FIXED_START)
  end
end
decode_nil(_buffer, _type) click to toggle source
# File lib/rencoder/decoder.rb, line 117
def decode_nil(_buffer, _type)
  nil
end
decode_string(buffer, type) click to toggle source
# File lib/rencoder/decoder.rb, line 66
def decode_string(buffer, type)
  case type
  when STR_FIXED
    buffer.read(type - STR_FIXED_START)
  when STR_HEADER
    length = type.chr + read_till(buffer, ':')

    buffer.read(length.to_i)
  end
end
read_till(buffer, separator = CHR_TERM.chr) click to toggle source
# File lib/rencoder/decoder.rb, line 121
def read_till(buffer, separator = CHR_TERM.chr)
  buffer.gets(separator).chomp(separator)
end