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

Source Code for Module dns.namedict

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