0001"""
0002Represents the response header list as a dictionary-like object.
0003"""
0004
0005from webob.multidict import MultiDict
0006try:
0007    reversed
0008except NameError:
0009    from webob.util.reversed import reversed
0010
0011class HeaderDict(MultiDict):
0012
0013    """
0014    Like a MultiDict, this wraps a list.  Keys are normalized
0015    for case and whitespace.
0016    """
0017
0018    def normalize(self, key):
0019        return str(key).lower().strip()
0020
0021    def __getitem__(self, key):
0022        normalize = self.normalize
0023        key = normalize(key)
0024        for k, v in reversed(self._items):
0025            if normalize(k) == key:
0026                return v
0027        raise KeyError(key)
0028
0029    def getall(self, key):
0030        normalize = self.normalize
0031        key = normalize(key)
0032        result = []
0033        for k, v in self._items:
0034            if normalize(k) == key:
0035                result.append(v)
0036        return result
0037
0038    def mixed(self):
0039        result = {}
0040        multi = {}
0041        normalize = self.normalize
0042        for key, value in self.iteritems():
0043            key = normalize(key)
0044            if key in result:
0045                if key in multi:
0046                    result[key].append(value)
0047                else:
0048                    result[key] = [result[key], value]
0049                    multi[key] = None
0050            else:
0051                result[key] = value
0052        return result
0053
0054    def dict_of_lists(self):
0055        result = {}
0056        normalize = self.normalize
0057        for key, value in self.iteritems():
0058            key = normalize(key)
0059            if key in result:
0060                result[key].append(value)
0061            else:
0062                result[key] = [value]
0063        return result
0064
0065    def __delitem__(self, key):
0066        normalize = self.normalize
0067        key = normalize(key)
0068        items = self._items
0069        found = False
0070        for i in range(len(items)-1, -1, -1):
0071            if normalize(items[i][0]) == key:
0072                del items[i]
0073                found = True
0074        if not found:
0075            raise KeyError(key)
0076
0077    def __contains__(self, key):
0078        normalize = self.normalize
0079        key = normalize(key)
0080        for k, v in self._items:
0081            if normalize(k) == key:
0082                return True
0083        return False
0084
0085    has_key = __contains__
0086
0087    def setdefault(self, key, default=None):
0088        normalize = self.normalize
0089        c_key = normalize(key)
0090        for k, v in self._items:
0091            if normalize(k) == c_key:
0092                return v
0093        self._items.append((key, default))
0094        return default
0095
0096    def pop(self, key, *args):
0097        if len(args) > 1:
0098            raise TypeError, "pop expected at most 2 arguments, got "                                + repr(1 + len(args))
0100        key = self.normalize(key)
0101        for i in range(len(self._items)):
0102            if self.normalize(self._items[i][0]) == key:
0103                v = self._items[i][1]
0104                del self._items[i]
0105                return v
0106        if args:
0107            return args[0]
0108        else:
0109            raise KeyError(key)