aboutsummaryrefslogtreecommitdiff
blob: c479ec971b9946e83b6b0cbdf439e242652ba764 (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
# 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__