module Protobuf::Decoder

def decode(stream, message)

Read bytes from +stream+ and pass to +message+ object.
def decode(stream, message)
  until stream.eof?
    tag, wire_type = read_key(stream)
    bytes =
      case wire_type
      when WireType::VARINT then
        read_varint(stream)
      when WireType::FIXED64 then
        read_fixed64(stream)
      when WireType::LENGTH_DELIMITED then
        read_length_delimited(stream)
      when WireType::START_GROUP then
        read_start_group(stream)
      when WireType::END_GROUP then
        read_end_group(stream)
      when WireType::FIXED32 then
        read_fixed32(stream)
      else
        raise InvalidWireType, wire_type
      end
    message.set_field(tag, bytes)
  end
  message
end

def read_end_group(stream)

Not implemented.
def read_end_group(stream)
  raise NotImplementedError, 'Group is deprecated.'
end

def read_fixed32(stream)

Read 32-bit string value from +stream+.
def read_fixed32(stream)
  stream.read(4)
end

def read_fixed64(stream)

Read 64-bit string value from +stream+.
def read_fixed64(stream)
  stream.read(8)
end

def read_key(stream)

Read key pair (tag and wire-type) from +stream+.
def read_key(stream)
  bits = read_varint(stream)
  wire_type = bits & 0x07
  tag = bits >> 3
  [tag, wire_type]
end

def read_length_delimited(stream)

Read length-delimited string value from +stream+.
def read_length_delimited(stream)
  value_length = read_varint(stream)
  stream.read(value_length)
end

def read_start_group(stream)

Not implemented.
def read_start_group(stream)
  raise NotImplementedError, 'Group is deprecated.'
end

def read_varint(stream)

Read varint integer value from +stream+.
def read_varint(stream)
  read_method = stream.respond_to?(:readbyte) ? :readbyte : :readchar
  value = index = 0
  begin
    byte = stream.__send__(read_method)
    value |= (byte & 0x7f) << (7 * index)
    index += 1
  end while (byte & 0x80).nonzero?
  value
end