class AMQ::Protocol::Basic

def self.decode_properties(data)

def self.decode_properties(data)
  offset, data_length, properties = 0, data.bytesize, {}
  compressed_index = data[offset, 2].unpack(PACK_UINT16)[0]
  offset += 2
  while data_length > offset
    DECODE_PROPERTIES_KEYS.each do |key|
      next unless compressed_index >= key
      compressed_index -= key
      name = DECODE_PROPERTIES[key] || raise(RuntimeError.new("No property found for index #{index.inspect}!"))
      case DECODE_PROPERTIES_TYPE[key]
      when :shortstr
        size = data[offset, 1].unpack(PACK_CHAR)[0]
        offset += 1
        result = data[offset, size]
      when :octet
        size = 1
        result = data[offset, size].unpack(PACK_CHAR).first
      when :timestamp
        size = 8
        result = Time.at(data[offset, size].unpack(PACK_UINT64_BE).last)
      when :table
        size = 4 + data[offset, 4].unpack(PACK_UINT32)[0]
        result = Table.decode(data[offset, size])
      end
      properties[name] = result
      offset += size
    end
  end
  properties
end

def self.encode_app_id(value)

1 << 3
def self.encode_app_id(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [12, 0x0008, buffer]
end

def self.encode_cluster_id(value)

1 << 2
def self.encode_cluster_id(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [13, 0x0004, buffer]
end

def self.encode_content_encoding(value)

1 << 14
def self.encode_content_encoding(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [1, 0x4000, buffer]
end

def self.encode_content_type(value)

1 << 15
def self.encode_content_type(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [0, 0x8000, buffer]
end

def self.encode_correlation_id(value)

1 << 10
def self.encode_correlation_id(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [5, 0x0400, buffer]
end

def self.encode_delivery_mode(value)

1 << 12
def self.encode_delivery_mode(value)
  buffer = +''
  buffer << [value].pack(PACK_CHAR)
  [3, 0x1000, buffer]
end

def self.encode_expiration(value)

1 << 8
def self.encode_expiration(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [7, 0x0100, buffer]
end

def self.encode_headers(value)

1 << 13
def self.encode_headers(value)
  buffer = +''
  buffer << AMQ::Protocol::Table.encode(value)
  [2, 0x2000, buffer]
end

def self.encode_message_id(value)

1 << 7
def self.encode_message_id(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [8, 0x0080, buffer]
end

def self.encode_priority(value)

1 << 11
def self.encode_priority(value)
  buffer = +''
  buffer << [value].pack(PACK_CHAR)
  [4, 0x0800, buffer]
end

def self.encode_properties(body_size, properties)

def self.encode_properties(body_size, properties)
  pieces, flags = [], 0
  properties.reject {|key, value| value.nil?}.each do |key, value|
    i, f, result = self.__send__(:"encode_#{key}", value)
    flags |= f
    pieces[i] = result
  end
  # result = [60, 0, body_size, flags].pack('n2Qn')
  result = [60, 0].pack(PACK_UINT16_X2)
  result += AMQ::Pack.pack_uint64_big_endian(body_size)
  result += [flags].pack(PACK_UINT16)
  pieces_joined = pieces.join(EMPTY_STRING)
  result.force_encoding(pieces_joined.encoding) + pieces_joined
end

def self.encode_reply_to(value)

1 << 9
def self.encode_reply_to(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [6, 0x0200, buffer]
end

def self.encode_timestamp(value)

1 << 6
def self.encode_timestamp(value)
  buffer = +''
  buffer << AMQ::Pack.pack_uint64_big_endian(value)
  [9, 0x0040, buffer]
end

def self.encode_type(value)

1 << 5
def self.encode_type(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [10, 0x0020, buffer]
end

def self.encode_user_id(value)

1 << 4
def self.encode_user_id(value)
  buffer = +''
  buffer << value.to_s.bytesize.chr
  buffer << value.to_s
  [11, 0x0010, buffer]
end