Class: Protojson::Codec::Hash

Inherits:
Object
  • Object
show all
Extended by:
CodecInterface
Defined in:
lib/protojson/codec/hash.rb

Class Method Summary collapse

Methods included from CodecInterface

decode, encode

Class Method Details

.decode(message, data, decoding_key = :name) ⇒ Object

This method parses a JSON encoded message to the message object



80
81
82
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
109
110
111
112
113
114
115
116
117
# File 'lib/protojson/codec/hash.rb', line 80

def decode(message, data, decoding_key = :name)

  message = message.new

  # per each hash element:
  data.each_pair { |key, value|
    key = decoding_key.eql?(:tag) ? key.to_i : key.to_s

    #  get the field object using the key (field tag)
    #field = message.get_field_by_tag(key.to_i)
    field = message.send("get_field_by_#{decoding_key}".to_sym, key)

    if field.nil?
      # ignore unknown field
    elsif field.repeated?
      # create the element
      array = message.__send__(field.name)
      value.each { |val|
      # if value is a complex field, create the object and parse the content
        if field.is_a?(Protobuf::Field::MessageField)
          instance = field.type
          val = decode(instance, val, decoding_key)
        end
        # include each element in the parent element field
        array.push(val)
      }
    else
      # if value is a complex field, create the object and parse the content
      if field.is_a?(Protobuf::Field::MessageField)
        instance = field.type
        value = decode(instance, value, decoding_key)
      end
      # set the message field
      message.__send__("#{field.name}=", value)
    end
  }
  message
end

.encode(message, encoding_key = :name) ⇒ Hash

Encode the message to a hash object defined as a collection for key/values where each element has:

  • key: field tag

  • value:

  • if field.is_a? message_field => field.value.serialized_to_hash

  • if field.is_a? enum_field => field.value.value

  • else => field.value

Returns:

  • (Hash)

    a specific Message encoded in an Hash object

Raises:

  • (NotInitializedError)


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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/protojson/codec/hash.rb', line 21

def encode(message, encoding_key = :name)
  raise NotInitializedError unless message.initialized?
  # var to store the encoded message fields
  result = {}

  # lambda function that extract the field tag and value
  # it's called recursively if value is a MessageField
  field_value_to_string = lambda { |field, value|
    field_value = \
  if field.optional? && !message.has_field?(field.name)
                              ''
  else
    case field
      when Protobuf::Field::MessageField
        if value.nil?
          nil
        else
          encode(value, encoding_key)
        end
      when Protobuf::Field::EnumField
        if value.is_a?(Protobuf::EnumValue)
          value.value
        else
          value.to_i
        end
      else
        value
    end
  end
    return field.send(encoding_key), field_value
  }

  # per each message field create a new element in result var with
  # key = field.tag and value = field.value
  message.each_field do |field, value|
    # create a vector if field is repeated
    if field.repeated? && !value.empty?
      key_value = []
      key = nil
      value.each do |v|
        key, val = field_value_to_string.call(field, v) # always return the same key
        key_value.push val
      end
      # field is not repeated but is not empty
    elsif !field.repeated?
      key, key_value = field_value_to_string.call(field, value)
      # empty field, discard
    else
      next
    end
    # new element in result Hash
    unless key_value.nil? or (key_value.respond_to?(:empty?) and key_value.empty?)
      result[key.to_s] = key_value
    end
  end
  result
end