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: