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