|
5 | 5 |
|
6 | 6 | class Bit:
|
7 | 7 | def __init__(self, value):
|
8 |
| - if isinstance(value, str): |
9 |
| - self._value = self.from_text(value)._value |
10 |
| - elif isinstance(value, bytes): |
11 |
| - self._value = np.unpackbits(np.frombuffer(value, dtype=np.uint8)).astype(bool) |
| 8 | + if isinstance(value, bytes): |
| 9 | + self._len = 8 * len(value) |
| 10 | + self._data = value |
12 | 11 | else:
|
13 |
| - value = np.asarray(value) |
| 12 | + if isinstance(value, str): |
| 13 | + value = [v != '0' for v in value] |
| 14 | + else: |
| 15 | + value = np.asarray(value) |
14 | 16 |
|
15 |
| - if value.dtype != np.bool: |
16 |
| - warn('expected elements to be boolean', stacklevel=2) |
17 |
| - value = value.astype(bool) |
| 17 | + if value.dtype != np.bool: |
| 18 | + warn('expected elements to be boolean', stacklevel=2) |
| 19 | + value = value.astype(bool) |
18 | 20 |
|
19 |
| - if value.ndim != 1: |
20 |
| - raise ValueError('expected ndim to be 1') |
| 21 | + if value.ndim != 1: |
| 22 | + raise ValueError('expected ndim to be 1') |
21 | 23 |
|
22 |
| - self._value = value |
| 24 | + self._len = len(value) |
| 25 | + self._data = np.packbits(value).tobytes() |
23 | 26 |
|
24 | 27 | def __repr__(self):
|
25 | 28 | return f'Bit({self.to_text()})'
|
26 | 29 |
|
27 | 30 | def __eq__(self, other):
|
28 | 31 | if isinstance(other, self.__class__):
|
29 |
| - return np.array_equal(self.to_numpy(), other.to_numpy()) |
| 32 | + return self._len == other._len and self._data == other._data |
30 | 33 | return False
|
31 | 34 |
|
32 | 35 | def to_list(self):
|
33 |
| - return self._value.tolist() |
| 36 | + return self.to_numpy().tolist() |
34 | 37 |
|
35 | 38 | def to_numpy(self):
|
36 |
| - return self._value |
| 39 | + return np.unpackbits(np.frombuffer(self._data, dtype=np.uint8), count=self._len).astype(bool) |
37 | 40 |
|
38 | 41 | def to_text(self):
|
39 |
| - return ''.join(self._value.astype(np.uint8).astype(str)) |
| 42 | + return ''.join(format(v, '08b') for v in self._data)[:self._len] |
40 | 43 |
|
41 | 44 | def to_binary(self):
|
42 |
| - return pack('>i', len(self._value)) + np.packbits(self._value).tobytes() |
| 45 | + return pack('>i', self._len) + self._data |
43 | 46 |
|
44 | 47 | @classmethod
|
45 | 48 | def from_text(cls, value):
|
46 |
| - return cls(np.asarray([v != '0' for v in value], dtype=bool)) |
| 49 | + return cls(str(value)) |
47 | 50 |
|
48 | 51 | @classmethod
|
49 | 52 | def from_binary(cls, value):
|
50 |
| - count = unpack_from('>i', value)[0] |
51 |
| - buf = np.frombuffer(value, dtype=np.uint8, offset=4) |
52 |
| - return cls(np.unpackbits(buf, count=count).astype(bool)) |
| 53 | + if not isinstance(value, bytes): |
| 54 | + raise ValueError('expected bytes') |
| 55 | + |
| 56 | + bit = cls.__new__(cls) |
| 57 | + bit._len = unpack_from('>i', value)[0] |
| 58 | + bit._data = value[4:] |
| 59 | + return bit |
53 | 60 |
|
54 | 61 | @classmethod
|
55 | 62 | def _to_db(cls, value):
|
|
0 commit comments