Class: MaxMindDB::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/maxminddb.rb

Constant Summary collapse

METADATA_BEGIN_MARKER =
([0xAB, 0xCD, 0xEF].pack('C*') + 'MaxMind.com').encode('ascii-8bit', 'ascii-8bit')
DATA_SECTION_SEPARATOR_SIZE =
16
SIZE_BASE_VALUES =
[0, 29, 285, 65821]
POINTER_BASE_VALUES =
[0, 0, 2048, 526336]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Client

Returns a new instance of Client.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/maxminddb.rb', line 19

def initialize(path)
  @path = path
  @data = File.binread(path)

  pos = @data.rindex(METADATA_BEGIN_MARKER)
  raise 'invalid file format' unless pos
  pos += METADATA_BEGIN_MARKER.size
  @metadata = decode(pos, 0)[1]

  @ip_version = @metadata['ip_version']
  @node_count = @metadata['node_count']
  @node_byte_size = @metadata['record_size'] * 2 / 8
  @search_tree_size = @node_count * @node_byte_size
end

Instance Attribute Details

#metadataObject (readonly)

Returns the value of attribute metadata.



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

def 
  @metadata
end

Instance Method Details

#inspectObject



34
35
36
# File 'lib/maxminddb.rb', line 34

def inspect
  "#<MaxMindDB::Client: DBPath:'#{@path}'>"
end

#lookup(ip) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/maxminddb.rb', line 38

def lookup(ip)
  node_no = 0
  addr = addr_from_ip(ip)
  start_idx = @ip_version == 4 ? 96 : 0
  for i in start_idx ... 128
    flag = (addr >> (127 - i)) & 1
    next_node_no = read_record(node_no, flag)
    if next_node_no == 0
      raise 'invalid file format'
    elsif next_node_no >= @node_count
      data_section_start = @search_tree_size + DATA_SECTION_SEPARATOR_SIZE
      pos = (next_node_no - @node_count) - DATA_SECTION_SEPARATOR_SIZE
      return MaxMindDB::Result.new(decode(pos, data_section_start)[1])
    else
      node_no = next_node_no
    end
  end
  raise 'invalid file format'
end