| # Copyright 2014 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| class ContentsCaseSensitivityManager(object): |
| """ |
| 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 = dict( |
| (k.lower(), v) for k, v in self.getcontents().items()) |
| self._reverse_key_map = dict( |
| (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__ |