'Reader for the MaxMind DB file format
Arguments:
database -- A path to a valid MaxMind DB file such as a GeoIP2
database file.
mode -- mode to open the database with. Valid mode are:
* MODE_MMAP - read from memory map.
* MODE_FILE - read database as standard file.
* MODE_MEMORY - load database into memory.
* MODE_AUTO - tries MODE_MMAP and then MODE_FILE. Default.'

def __init__(self, database, mode=MODE_AUTO):

    if (((mode == MODE_AUTO) and mmap) or (mode == MODE_MMAP)):
        with open(database, u'rb') as db_file:
            self._buffer = mmap.mmap(db_file.fileno(), 0, access=mmap.ACCESS_READ)
            self._buffer_size = self._buffer.size()
    elif (mode in (MODE_AUTO, MODE_FILE)):
        self._buffer = FileBuffer(database)
        self._buffer_size = self._buffer.size()
    elif (mode == MODE_MEMORY):
        with open(database, u'rb') as db_file:
            self._buffer = db_file.read()
            self._buffer_size = len(self._buffer)
    else:
        raise ValueError(u'Unsupported    open    mode    ({0}).    Only    MODE_AUTO,        MODE_FILE,    and    MODE_MEMORY    are    support    by    the    pure    Python    Reader'.format(mode))
    metadata_start = self._buffer.rfind(self._METADATA_START_MARKER, max(0, (self._buffer_size - (128 * 1024))))
    if (metadata_start == (-1)):
        self.close()
        raise InvalidDatabaseError(u'Error    opening    database    file    ({0}).    Is    this    a    valid    MaxMind    DB    file?'.format(database))
    metadata_start += len(self._METADATA_START_MARKER)
    metadata_decoder = Decoder(self._buffer, metadata_start)
    (metadata, _) = metadata_decoder.decode(metadata_start)
    self._metadata = Metadata(**metadata)
    self._decoder = Decoder(self._buffer, (self._metadata.search_tree_size + self._DATA_SECTION_SEPARATOR_SIZE))
