Class: MTProto::TL::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/mtproto/tl/schema.rb

Constant Summary collapse

PRIMITIVES =
{
  'int' => 4, 'long' => 8, 'double' => 8,
  'int128' => 16, 'int256' => 32
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Schema

Returns a new instance of Schema.



13
14
15
16
17
18
19
20
# File 'lib/mtproto/tl/schema.rb', line 13

def initialize(path)
  raw = JSON.parse(File.read(path))
  @constructors = {}
  raw['constructors'].each do |c|
    uid = c['id'].to_i & 0xFFFFFFFF
    @constructors[uid] = c['params']
  end
end

Instance Method Details

#skip(data, offset) ⇒ Object



22
23
24
25
26
# File 'lib/mtproto/tl/schema.rb', line 22

def skip(data, offset)
  constructor = data[offset, 4].unpack1('L<')
  offset += 4
  skip_params(data, offset, constructor)
end

#skip_params(data, offset, constructor) ⇒ Object



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
# File 'lib/mtproto/tl/schema.rb', line 36

def skip_params(data, offset, constructor)
  params = @constructors[constructor]
  raise "Unknown constructor: 0x#{constructor.to_s(16).rjust(8, '0')}" unless params

  flag_values = {}

  params.each do |param|
    type = param['type']

    if type == '#'
      flag_values[param['name']] = data[offset, 4].unpack1('L<')
      offset += 4
      next
    end

    if (m = type.match(/\A(\w+)\.(\d+)\?(.+)\z/))
      flag_name = m[1]
      bit = m[2].to_i
      inner_type = m[3]
      next if inner_type == 'true'
      next unless flag_values[flag_name]&.anybits?(1 << bit)

      offset = skip_type(data, offset, inner_type)
    else
      offset = skip_type(data, offset, type)
    end
  end
  offset
end

#skip_vector(data, offset, &block) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/mtproto/tl/schema.rb', line 28

def skip_vector(data, offset, &block)
  offset += 4 # vector constructor 0x1cb5c415
  count = data[offset, 4].unpack1('L<')
  offset += 4
  count.times { offset = block ? yield(data, offset) : skip(data, offset) }
  offset
end