Mercurial > cgi-bin > hgweb.cgi > curlyq
comparison runes.py @ 13:6acda841a690
Add support for shared substrings.
author | David Barts <n5jrn@me.com> |
---|---|
date | Fri, 27 Dec 2019 13:23:07 -0800 |
parents | ab7d6e908034 |
children | 152f6aa87d62 |
comparison
equal
deleted
inserted
replaced
12:ab7d6e908034 | 13:6acda841a690 |
---|---|
23 # The most efficient 16-bit one on this platform | 23 # The most efficient 16-bit one on this platform |
24 encoding = "UTF-16" + sys.byteorder[0].upper() + "E" | 24 encoding = "UTF-16" + sys.byteorder[0].upper() + "E" |
25 codec = codecs.lookup(encoding) | 25 codec = codecs.lookup(encoding) |
26 | 26 |
27 def __init__(self, based_on=None): | 27 def __init__(self, based_on=None): |
28 if isinstance(based_on, array.array): | 28 if isinstance(based_on, (array.array, memoryview)): |
29 if based_on.typecode == 'H': | 29 format = based_on.typecode if isinstance(based_on, array.array) else based_on.format |
30 if format == 'H': | |
30 self.buffer = based_on | 31 self.buffer = based_on |
31 else: | 32 else: |
32 self.buffer = array.array('H', based_on) | 33 self.buffer = array.array('H', based_on) |
33 elif isinstance(based_on, str): | 34 elif isinstance(based_on, str): |
34 # A string should always be able to encode to runes. | 35 # A string should always be able to encode to runes. |
71 | 72 |
72 def __ne__(self, other): | 73 def __ne__(self, other): |
73 return self.buffer != other.buffer | 74 return self.buffer != other.buffer |
74 | 75 |
75 def __hash__(self): | 76 def __hash__(self): |
76 return hash(self.buffer) | 77 raise TypeError("unhashable type") |
77 | 78 |
78 def __bool__(self): | 79 def __bool__(self): |
79 return bool(self.buffer) | 80 return bool(self.buffer) |
80 | 81 |
81 def __getitem__(self, key): | 82 def __getitem__(self, key): |
96 else: | 97 else: |
97 raise TypeError("runes required") | 98 raise TypeError("runes required") |
98 | 99 |
99 def __delitem__(self, key): | 100 def __delitem__(self, key): |
100 del self.buffer[key] | 101 del self.buffer[key] |
102 | |
103 def __del__(self): | |
104 # Paranoid | |
105 if isinstance(self.buffer, memoryview): | |
106 self.buffer.release() | |
101 | 107 |
102 def clear(self): | 108 def clear(self): |
103 del self[:] | 109 del self[:] |
104 | 110 |
105 def __iter__(self): | 111 def __iter__(self): |
144 Runes.__setitem__(self, key, Runes(value)) | 150 Runes.__setitem__(self, key, Runes(value)) |
145 else: | 151 else: |
146 Runes.__setitem__(self, key, value) | 152 Runes.__setitem__(self, key, value) |
147 | 153 |
148 def __getitem__(self, key): | 154 def __getitem__(self, key): |
155 view = memoryview(self.buffer) | |
149 try: | 156 try: |
150 ret = Runes.__getitem__(self, key) | 157 ret = view[key] |
151 if isinstance (ret, int): | 158 if isinstance (ret, int): |
152 return chr(ret) | 159 return chr(ret) |
153 elif isinstance(ret, Runes): | 160 elif isinstance(ret, memoryview): |
154 return str(ret) | 161 return self.codec.decode(ret, 'replace')[0] |
155 else: | 162 else: |
156 raise AssertionError("this shouldn't happen") | 163 raise AssertionError("this shouldn't happen") |
157 except IndexError: | 164 except IndexError: |
158 return "" | 165 return "" |
166 finally: | |
167 view.release() | |
159 | 168 |
160 def append(self, value): | 169 def append(self, value): |
161 if isinstance(value, str): | 170 if isinstance(value, str): |
162 Runes.append(self, Runes(value)) | 171 Runes.append(self, Runes(value)) |
163 else: | 172 else: |