Package dns :: Module namedict |
[hide private]
[frames] | no frames]

# Source Code for Module dns.namedict

      1  # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
      2  # Copyright (C) 2016 Coresec Systems AB
      3  #
      4  # Permission to use, copy, modify, and distribute this software and its
      5  # documentation for any purpose with or without fee is hereby granted,
      6  # provided that the above copyright notice and this permission notice
      7  # appear in all copies.
      8  #
      9  # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
     10  # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11  # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
     12  # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
     15  # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16  #
     17  # THE SOFTWARE IS PROVIDED "AS IS" AND CORESEC SYSTEMS AB DISCLAIMS ALL
     18  # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
     19  # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CORESEC
     20  # SYSTEMS AB BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
     21  # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
     22  # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
     23  # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     24  # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     25
     26  """DNS name dictionary"""
     27
     28  import collections
     29  import dns.name
     30  from ._compat import xrange
     31
     32
     33 -class NameDict(collections.MutableMapping):
     34
     35      """A dictionary whose keys are dns.name.Name objects.
     36      @ivar max_depth: the maximum depth of the keys that have ever been
     37      added to the dictionary.
     38      @type max_depth: int
     39      @ivar max_depth_items: the number of items of maximum depth
     40      @type max_depth_items: int
     41      """
     42
     43      __slots__ = ["max_depth", "max_depth_items", "__store"]
     44
     45 -    def __init__(self, *args, **kwargs):
     46          self.__store = dict()
     47          self.max_depth = 0
     48          self.max_depth_items = 0
     49          self.update(dict(*args, **kwargs))
     50
     51 -    def __update_max_depth(self, key):
     52          if len(key) == self.max_depth:
     53              self.max_depth_items = self.max_depth_items + 1
     54          elif len(key) > self.max_depth:
     55              self.max_depth = len(key)
     56              self.max_depth_items = 1
     57
     58 -    def __getitem__(self, key):
     59          return self.__store[key]
     60
     61 -    def __setitem__(self, key, value):
     62          if not isinstance(key, dns.name.Name):
     63              raise ValueError('NameDict key must be a name')
     64          self.__store[key] = value
     65          self.__update_max_depth(key)
     66
     67 -    def __delitem__(self, key):
     68          value = self.__store.pop(key)
     69          if len(value) == self.max_depth:
     70              self.max_depth_items = self.max_depth_items - 1
     71          if self.max_depth_items == 0:
     72              self.max_depth = 0
     73              for k in self.__store:
     74                  self.__update_max_depth(k)
     75
     76 -    def __iter__(self):
     77          return iter(self.__store)
     78
     79 -    def __len__(self):
     80          return len(self.__store)
     81
     82 -    def has_key(self, key):
     83          return key in self.__store
     84
     85 -    def get_deepest_match(self, name):
     86          """Find the deepest match to I{name} in the dictionary.
     87
     88          The deepest match is the longest name in the dictionary which is
     89          a superdomain of I{name}.
     90
     91          @param name: the name
     92          @type name: dns.name.Name object
     93          @rtype: (key, value) tuple
     94          """
     95
     96          depth = len(name)
     97          if depth > self.max_depth:
     98              depth = self.max_depth
     99          for i in xrange(-depth, 0):
    100              n = dns.name.Name(name[i:])
    101              if n in self:
    102                  return (n, self[n])
    103          v = self[dns.name.empty]
    104          return (dns.name.empty, v)
    105