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, file_reader = DEFAULT_FILE_READER) ⇒ Client

Returns a new instance of Client.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/maxminddb.rb', line 31

def initialize(path, file_reader = DEFAULT_FILE_READER)
  @path = path
  @data = file_reader.call(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

#local_ip_aliasObject

An IP that is used instead of local IPs



29
30
31
# File 'lib/maxminddb.rb', line 29

def local_ip_alias
  @local_ip_alias
end

#metadataObject (readonly)

Returns the value of attribute metadata.



26
27
28
# File 'lib/maxminddb.rb', line 26

def 
  @metadata
end

Instance Method Details

#inspectObject



46
47
48
# File 'lib/maxminddb.rb', line 46

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

#lookup(ip_or_hostname) ⇒ Object



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
# File 'lib/maxminddb.rb', line 50

def lookup(ip_or_hostname)
  if @local_ip_alias && is_local?(ip_or_hostname)
    ip_or_hostname = @local_ip_alias
  end

  node_no = 0
  addr = addr_from_ip(ip_or_hostname)
  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
      result            = decode(pos, data_section_start)[1]
      result['network'] = network_from_addr(addr, i) unless result.empty?
      return MaxMindDB::Result.new(result)
    else
      node_no = next_node_no
    end
  end
  raise 'invalid file format'
end