Module: Beefcake::Message::Encode

Defined in:
lib/beefcake.rb

Instance Method Summary collapse

Instance Method Details

#encode(buf = Buffer.new) ⇒ Object


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/beefcake.rb', line 83

def encode(buf = Buffer.new)
  validate!

  if ! buf.respond_to?(:<<)
    raise ArgumentError, "buf doesn't respond to `<<`"
  end

  if ! buf.is_a?(Buffer)
    buf = Buffer.new(buf)
  end

  # TODO: Error if any required fields at nil

  __beefcake_fields__.values.sort.each do |fld|
    if fld.opts[:packed]
      bytes = encode!(Buffer.new, fld, 0)
      buf.append_info(fld.fn, Buffer.wire_for(fld.type))
      buf.append_uint64(bytes.length)
      buf << bytes
    else
      encode!(buf, fld, fld.fn)
    end
  end

  buf
end

#encode!(buf, fld, fn) ⇒ Object


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/beefcake.rb', line 110

def encode!(buf, fld, fn)
  v = self[fld.name]
  v = v.is_a?(Array) ? v : [v]

  v.compact.each do |val|
    case fld.type
    when Class # encodable
      # TODO: raise error if type != val.class
      buf.append(:string, val.encode, fn)
    when Module # enum
      if ! valid_enum?(fld.type, val)
        raise InvalidValueError.new(fld.name, val)
      end

      buf.append(:int32, val, fn)
    else
      buf.append(fld.type, val, fn)
    end
  end

  buf
end

#name_for(mod, val) ⇒ Object


151
152
153
154
155
156
157
158
# File 'lib/beefcake.rb', line 151

def name_for(mod, val)
  mod.constants.each do |name|
    if mod.const_get(name) == val
      return name
    end
  end
  nil
end

#valid_enum?(mod, val) ⇒ Boolean

Returns:

  • (Boolean)

147
148
149
# File 'lib/beefcake.rb', line 147

def valid_enum?(mod, val)
  !!name_for(mod, val)
end

#validate!Object


160
161
162
163
164
165
166
# File 'lib/beefcake.rb', line 160

def validate!
  __beefcake_fields__.values.each do |fld|
    if fld.rule == :required && self[fld.name].nil?
      raise RequiredFieldNotSetError, fld.name
    end
  end
end

#write_delimited(buf = Buffer.new) ⇒ Object


133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/beefcake.rb', line 133

def write_delimited(buf = Buffer.new)
  if ! buf.respond_to?(:<<)
    raise ArgumentError, "buf doesn't respond to `<<`"
  end

  if ! buf.is_a?(Buffer)
    buf = Buffer.new(buf)
  end

  buf.append_bytes(encode)

  buf
end