Class: Protojson::Codec::JsonIndexed

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

Class Method Summary collapse

Methods included from CodecInterface

decode, encode

Class Method Details

.decode(message, data) ⇒ Object



17
18
19
20
21
22
# File 'lib/protojson/codec/json_indexed.rb', line 17

def decode(message, data)
  data.is_a?(String) and data = ActiveSupport::JSON.decode(data)

  values = parse_indexed_to_hash(message.new, data)
  Protojson::Codec::Hash.decode(message, values, :tag)
end

.encode(message) ⇒ Object



12
13
14
15
# File 'lib/protojson/codec/json_indexed.rb', line 12

def encode(message)
  data = Protojson::Codec::Hash.encode(message, :tag)
  serialize_hash_to_indexed(data)
end

.parse_indexed_to_hash(message, data) ⇒ Object

This method parses a INDEXED encoded message to a hash using message message as model. We need to know the specific message to decode to differenciate between vectors and message fields



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/protojson/codec/json_indexed.rb', line 59

def parse_indexed_to_hash(message, data)
  values = {}
  index = data.shift
  index.each_codepoint { |tag|
    tag = tag-48
    field = message.get_field_by_tag(tag)
    val = data.shift

    if val.is_a?(Array) && field.is_a?(Protobuf::Field::MessageField)
      if field.repeated?
        val.map! { |v|
          v = parse_indexed_to_hash(field.type, v)
        }
      else
        val = parse_indexed_to_hash(field.type, val)
      end
    end
    values[tag.to_s] = val
  }
  values
end

.serialize_hash_to_indexed(value) ⇒ Object

This class method serializes a Hash



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
# File 'lib/protojson/codec/json_indexed.rb', line 25

def serialize_hash_to_indexed(value)
  !value.is_a?(::Hash) and raise ArgumentError, "value must be a hash"

  # index value
  index = ""
  index.respond_to?(:force_encoding) and index.force_encoding("UTF-8") # 1.9.2
  # field values
  result = []
  value.each_pair { |key, value|
    index << key.to_i+48 # ASCII integer. 1 => 49, ...
    # recursive call if value is a Hash
    if value.is_a?(::Hash)
      value = serialize_hash_to_indexed(value)
      # array => serializes each element
    elsif value.is_a?(Array)
      value.map! { |val|
        if val.is_a?(::Hash)
          serialize_hash_to_indexed(val)
        else
          val
        end
      }
    end
    # insert encoded value in Array
    result.push value
  }
  # include index as first element
  result.unshift(index)
end