Module: Protobuf::Decoder

Defined in:
lib/protobuf/message/decoder.rb

Constant Summary

READ_METHODS =
[
  :read_varint,           # 0: Varint
  :read_fixed64,          # 1: 64 bit
  :read_length_delimited, # 2: Length-delimited
  :read_start_group,      # 3: Start group
  :read_end_group,        # 4: End group
  :read_fixed32,          # 5: 32 bit
]

Instance Method Summary (collapse)

Instance Method Details

- (Object) decode(stream, message)

Read bytes from stream and pass to message object.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/protobuf/message/decoder.rb', line 20

def decode(stream, message)
  until stream.eof?
    tag, wire_type = read_key(stream)
    field = message.get_field_by_tag(tag)

    method = READ_METHODS[wire_type]
    raise InvalidWireType, "Unknown wire type: #{wire_type}" unless method
    value = send(method, stream)

    if field.nil?
      # ignore unknown field
    elsif field.repeated?
      array = message.__send__(field.name)
      if wire_type == WireType::LENGTH_DELIMITED && WireType::PACKABLE_TYPES.include?(field.wire_type)
        # packed
        s = StringIO.new(value)
        m = READ_METHODS[field.wire_type]
        until s.eof?
          array << field.decode(send(m, s))
        end
      else
        # non-packed
        array << field.decode(value)
      end
    else
      message.__send__("#{field.name}=", field.decode(value))
    end
  end
  message
end

- (Object) read_end_group(stream)

Not implemented.

Raises:

  • (NotImplementedError)


93
94
95
# File 'lib/protobuf/message/decoder.rb', line 93

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

- (Object) read_fixed32(stream)

Read 32-bit string value from stream.



72
73
74
# File 'lib/protobuf/message/decoder.rb', line 72

def read_fixed32(stream)
  stream.read(4)
end

- (Object) read_fixed64(stream)

Read 64-bit string value from stream.



77
78
79
# File 'lib/protobuf/message/decoder.rb', line 77

def read_fixed64(stream)
  stream.read(8)
end

- (Object) read_key(stream)

Read key pair (tag and wire-type) from stream.



52
53
54
55
56
57
# File 'lib/protobuf/message/decoder.rb', line 52

def read_key(stream)
  bits = read_varint(stream)
  wire_type = bits & 0x07
  tag = bits >> 3
  [tag, wire_type]
end

- (Object) read_length_delimited(stream)

Read length-delimited string value from stream.



82
83
84
85
# File 'lib/protobuf/message/decoder.rb', line 82

def read_length_delimited(stream)
  value_length = read_varint(stream)
  stream.read(value_length)
end

- (Object) read_start_group(stream)

Not implemented.

Raises:

  • (NotImplementedError)


88
89
90
# File 'lib/protobuf/message/decoder.rb', line 88

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

- (Object) read_varint(stream)

Read varint integer value from stream.



60
61
62
63
64
65
66
67
68
69
# File 'lib/protobuf/message/decoder.rb', line 60

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