Class: Protobuf::Message

Inherits:
Object
  • Object
show all
Extended by:
Protoable
Defined in:
lib/protobuf/message/message.rb

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Protoable

defined_filenames, defined_in, proto_contents, proto_filenames, retrieve_header

Constructor Details

- (Message) initialize(values = {})



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/protobuf/message/message.rb', line 101

def initialize(values={})
  @values = {}

  self.class.fields.dup.each do |tag, field|
    unless field.ready?
      field = field.setup
      self.class.fields[tag] = field
      self.class.__send__(:clear_field_cache)
    end
    if field.repeated?
      @values[field.name] = Field::FieldArray.new(field)
    end
  end

  values.each {|name, val| self.__send__("#{name}=", val)}
end

Class Method Details

+ (Object) define_field(rule, type, fname, tag, options)

Define a field. Don't use this method directly.



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/protobuf/message/message.rb', line 37

def define_field(rule, type, fname, tag, options)
  if options[:extension] && ! extension_tag?(tag)
    raise RangeError, "#{tag} is not in #{@extension_tag}"
  end

  if fields.include?(tag)
    raise TagCollisionError, "Field tag #{tag} has already been used in #{self.name}."
  end
  fields[tag] = Field.build(self, rule, type, fname, tag, options)
  clear_field_cache
end

+ (Object) descriptor



96
97
98
# File 'lib/protobuf/message/message.rb', line 96

def descriptor
  @descriptor ||= Descriptor::Descriptor.new(self)
end

+ (Boolean) extension_tag?(tag)



49
50
51
# File 'lib/protobuf/message/message.rb', line 49

def extension_tag?(tag)
  @extension_tag.include?(tag)
end

+ (Object) extensions(range)

Reserve field numbers for extensions. Don't use this method directly.



17
18
19
# File 'lib/protobuf/message/message.rb', line 17

def extensions(range)
  @extension_tag = range
end

+ (Object) fields

A collection of field object.



54
55
56
# File 'lib/protobuf/message/message.rb', line 54

def fields
  @fields ||= {}
end

+ (Object) get_field(tag_or_name)

Find a field object by tag_or_name.



84
85
86
87
88
89
90
91
# File 'lib/protobuf/message/message.rb', line 84

def get_field(tag_or_name)
  case tag_or_name
  when Integer, String, Symbol
    field_dictionary[tag_or_name]
  else
    raise TypeError, tag_or_name.class
  end
end

+ (Object) get_field_by_name

Find a field object by tag_or_name. for compatibility for compatibility



94
95
96
97
98
99
100
101
# File 'lib/protobuf/message/message.rb', line 94

def get_field(tag_or_name)
  case tag_or_name
  when Integer, String, Symbol
    field_dictionary[tag_or_name]
  else
    raise TypeError, tag_or_name.class
  end
end

+ (Object) get_field_by_tag

Find a field object by tag_or_name.



93
94
95
96
97
98
99
100
# File 'lib/protobuf/message/message.rb', line 93

def get_field(tag_or_name)
  case tag_or_name
  when Integer, String, Symbol
    field_dictionary[tag_or_name]
  else
    raise TypeError, tag_or_name.class
  end
end

+ (Object) optional(type, name, tag, options = {})

Define a optional field. Don't use this method directly.



27
28
29
# File 'lib/protobuf/message/message.rb', line 27

def optional(type, name, tag, options={})
  define_field(:optional, type, name, tag, options)
end

+ (Object) repeated(type, name, tag, options = {})

Define a repeated field. Don't use this method directly.



32
33
34
# File 'lib/protobuf/message/message.rb', line 32

def repeated(type, name, tag, options={})
  define_field(:repeated, type, name, tag, options)
end

+ (Object) required(type, name, tag, options = {})

Define a required field. Don't use this method directly.



22
23
24
# File 'lib/protobuf/message/message.rb', line 22

def required(type, name, tag, options={})
  define_field(:required, type, name, tag, options)
end

Instance Method Details

- (Object) ==(obj)



128
129
130
131
132
133
134
# File 'lib/protobuf/message/message.rb', line 128

def ==(obj)
  return false unless obj.is_a?(self.class)
  each_field do |field, value|
    return false unless value == obj.__send__(field.name)
  end
  true
end

- (Object) [](tag_or_name)



259
260
261
262
263
264
265
# File 'lib/protobuf/message/message.rb', line 259

def [](tag_or_name)
  if field = get_field(tag_or_name)
    __send__(field.name)
  else
    raise NoMethodError, "No such field: #{tag_or_name.inspect}"
  end
end

- (Object) []=(tag_or_name, value)



267
268
269
270
271
272
273
# File 'lib/protobuf/message/message.rb', line 267

def []=(tag_or_name, value)
  if field = get_field(tag_or_name)
    __send__("#{field.name}=", value)
  else
    raise NoMethodError, "No such field: #{tag_or_name.inspect}"
  end
end

- (Object) clear!



136
137
138
139
140
141
142
143
144
145
146
# File 'lib/protobuf/message/message.rb', line 136

def clear!
  @values.delete_if do |_, value|
    if value.is_a?(Field::FieldArray)
      value.clear
      false
    else
      true
    end
  end
  self
end

- (Object) clone



152
153
154
# File 'lib/protobuf/message/message.rb', line 152

def clone
  copy_to(super, :clone)
end

- (Object) dup



148
149
150
# File 'lib/protobuf/message/message.rb', line 148

def dup
  copy_to(super, :dup)
end

- (Object) each_field

Iterate over a field collection.

message.each_field do |field_object, value|
  # do something
end


299
300
301
302
303
304
# File 'lib/protobuf/message/message.rb', line 299

def each_field
  self.class.__send__(:sorted_fields).each do |_, field|
    value = __send__(field.name)
    yield(field, value)
  end
end

- (Object) fields

Returns a hash; which key is a tag number, and value is a field object.



276
277
278
# File 'lib/protobuf/message/message.rb', line 276

def fields
  self.class.fields
end

- (Object) get_field(tag_or_name)

Returns field object or nil.



291
292
293
# File 'lib/protobuf/message/message.rb', line 291

def get_field(tag_or_name)
  self.class.get_field(tag_or_name)
end

- (Object) get_field_by_name(name)

Returns field object or nil.



281
282
283
# File 'lib/protobuf/message/message.rb', line 281

def get_field_by_name(name)
  self.class.get_field_by_name(name)
end

- (Object) get_field_by_tag(tag)

Returns field object or nil.



286
287
288
# File 'lib/protobuf/message/message.rb', line 286

def get_field_by_tag(tag)
  self.class.get_field_by_tag(tag)
end

- (Boolean) has_field?(tag_or_name)

Raises:

  • (ArgumentError)


122
123
124
125
126
# File 'lib/protobuf/message/message.rb', line 122

def has_field?(tag_or_name)
  field = get_field(tag_or_name)
  raise ArgumentError, "unknown field: #{tag_or_name.inspect}" unless field
  @values.has_key?(field.name)
end

- (Boolean) initialized?



118
119
120
# File 'lib/protobuf/message/message.rb', line 118

def initialized?
  fields.all? {|tag, field| field.initialized?(self) }
end

- (Object) inspect(indent = 0)



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/protobuf/message/message.rb', line 176

def inspect(indent=0)
  result = []
  i = '  ' * indent
  field_value_to_string = lambda {|field, value|
    result << \
      if field.optional? && ! @values.has_key?(field.name)
        ''
      else
        case field
        when Field::MessageField
          if value.nil?
            "#{i}#{field.name} {}\n"
          else
            "#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
          end
        when Field::EnumField
          if value.is_a?(EnumValue)
            "#{i}#{field.name}: #{value.name}\n"
          else
            "#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
          end
        else
          "#{i}#{field.name}: #{value.inspect}\n"
        end
      end
  }
  each_field do |field, value|
    if field.repeated?
      value.each do |v|
        field_value_to_string.call(field, v)
      end
    else
      field_value_to_string.call(field, value)
    end
  end
  result.join
end

- (Object) merge_from(message)



255
256
257
# File 'lib/protobuf/message/message.rb', line 255

def merge_from(message)
  fields.each {|tag, field| field.merge(self, message.__send__(field.name))}
end

- (Object) parse_from(stream)



228
229
230
# File 'lib/protobuf/message/message.rb', line 228

def parse_from(stream)
  Decoder.decode(stream, self)
end

- (Object) parse_from_file(filename)



218
219
220
221
222
223
224
225
226
# File 'lib/protobuf/message/message.rb', line 218

def parse_from_file(filename)
  if filename.is_a?(File)
    parse_from(filename)
  else
    File.open(filename, 'rb') do |f|
      parse_from(f)
    end
  end
end

- (Object) parse_from_string(string)



214
215
216
# File 'lib/protobuf/message/message.rb', line 214

def parse_from_string(string)
  parse_from(StringIO.new(string))
end

- (Object) serialize_to(stream)



251
252
253
# File 'lib/protobuf/message/message.rb', line 251

def serialize_to(stream)
  Encoder.encode(stream, self)
end

- (Object) serialize_to_file(filename)



241
242
243
244
245
246
247
248
249
# File 'lib/protobuf/message/message.rb', line 241

def serialize_to_file(filename)
  if filename.is_a?(File)
    serialize_to(filename)
  else
    File.open(filename, 'wb') do |f|
      serialize_to(f)
    end
  end
end

- (Object) serialize_to_string(string = '') Also known as: to_s



232
233
234
235
236
237
238
# File 'lib/protobuf/message/message.rb', line 232

def serialize_to_string(string='')
  io = StringIO.new(string)
  serialize_to(io)
  result = io.string
  result.force_encoding(Encoding::BINARY) if result.respond_to?(:force_encoding)
  result
end

- (Object) to_hash



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/protobuf/message/message.rb', line 306

def to_hash
  hash = {}
  each_field do |field, value|
    next unless @values.has_key?(field.name)
    case value
    when Array
      next if value.empty?
      hash[field.name] = value.map {|val| val.is_a?(Message) ? val.to_hash : val}
    when Message
      hash[field.name] = value.to_hash
    when EnumValue
      hash[field.name] = value.name
    else
      hash[field.name] = value
    end
  end
  hash
end