aboutsummaryrefslogtreecommitdiff
blob: 63862ee4a137dc62fd88fb3dc57a37db34cbe909 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2


class ContentsCaseSensitivityManager:
    """
    Implicitly handles case transformations that are needed for
    case-insensitive support.
    """

    def __init__(self, db):
        """
        @param db: A dblink instance
        @type db: vartree.dblink
        """
        self.getcontents = db.getcontents

        if "case-insensitive-fs" in db.settings.features:
            self.unmap_key = self._unmap_key_case_insensitive
            self.contains = self._contains_case_insensitive
            self.keys = self._keys_case_insensitive

        self._contents_insensitive = None
        self._reverse_key_map = None

    def clear_cache(self):
        """
        Clear all cached contents data.
        """
        self._contents_insensitive = None
        self._reverse_key_map = None

    def keys(self):
        """
        Iterate over all contents keys, which are transformed to
        lowercase when appropriate, for use in case-insensitive
        comparisons.
        @rtype: iterator
        @return: An iterator over all the contents keys
        """
        return iter(self.getcontents())

    def contains(self, key):
        """
        Check if the given key is contained in the contents, using
        case-insensitive comparison when appropriate.
        @param key: A filesystem path (including ROOT and EPREFIX)
        @type key: str
        @rtype: bool
        @return: True if the given key is contained in the contents,
                False otherwise
        """
        return key in self.getcontents()

    def unmap_key(self, key):
        """
        Map a key (from the keys method) back to its case-preserved
        form.
        @param key: A filesystem path (including ROOT and EPREFIX)
        @type key: str
        @rtype: str
        @return: The case-preserved form of key
        """
        return key

    def _case_insensitive_init(self):
        """
        Initialize data structures for case-insensitive support.
        """
        self._contents_insensitive = {
            k.lower(): v for k, v in self.getcontents().items()
        }
        self._reverse_key_map = {k.lower(): k for k in self.getcontents()}

    def _keys_case_insensitive(self):
        if self._contents_insensitive is None:
            self._case_insensitive_init()
        return iter(self._contents_insensitive)

    _keys_case_insensitive.__doc__ = keys.__doc__

    def _contains_case_insensitive(self, key):
        if self._contents_insensitive is None:
            self._case_insensitive_init()
        return key.lower() in self._contents_insensitive

    _contains_case_insensitive.__doc__ = contains.__doc__

    def _unmap_key_case_insensitive(self, key):
        if self._reverse_key_map is None:
            self._case_insensitive_init()
        return self._reverse_key_map[key]

    _unmap_key_case_insensitive.__doc__ = unmap_key.__doc__