Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/bitstring/bitstream.py: 43%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import bitstring
4from bitstring.bits import Bits, BitsType
5from bitstring.dtypes import Dtype
6from typing import Union, List, Any, Optional, overload, TypeVar, Tuple
7import copy
8import numbers
10common_helpers = bitstring.bitstore_common_helpers
12TConstBitStream = TypeVar("TConstBitStream", bound='ConstBitStream')
15class ConstBitStream(Bits):
16 """A container or stream holding an immutable sequence of bits.
18 For a mutable container use the BitStream class instead.
20 Methods inherited from Bits:
22 all() -- Check if all specified bits are set to 1 or 0.
23 any() -- Check if any of specified bits are set to 1 or 0.
24 copy() -- Return a copy of the bitstring.
25 count() -- Count the number of bits set to 1 or 0.
26 cut() -- Create generator of constant sized chunks.
27 endswith() -- Return whether the bitstring ends with a sub-string.
28 find() -- Find a sub-bitstring in the current bitstring.
29 findall() -- Find all occurrences of a sub-bitstring in the current bitstring.
30 fromstring() -- Create a bitstring from a formatted string.
31 join() -- Join bitstrings together using current bitstring.
32 pp() -- Pretty print the bitstring.
33 rfind() -- Seek backwards to find a sub-bitstring.
34 split() -- Create generator of chunks split by a delimiter.
35 startswith() -- Return whether the bitstring starts with a sub-bitstring.
36 tobitarray() -- Return bitstring as a bitarray from the bitarray package.
37 tobytes() -- Return bitstring as bytes, padding if needed.
38 tofile() -- Write bitstring to file, padding if needed.
39 unpack() -- Interpret bits using format string.
41 Other methods:
43 bytealign() -- Align to next byte boundary.
44 peek() -- Peek at and interpret next bits as a single item.
45 peeklist() -- Peek at and interpret next bits as a list of items.
46 read() -- Read and interpret next bits as a single item.
47 readlist() -- Read and interpret next bits as a list of items.
48 readto() -- Read up to and including next occurrence of a bitstring.
50 Special methods:
52 Also available are the operators [], ==, !=, +, *, ~, <<, >>, &, |, ^.
54 Properties:
56 [GENERATED_PROPERTY_DESCRIPTIONS]
58 len -- Length of the bitstring in bits.
59 pos -- The current bit position in the bitstring.
60 """
62 __slots__ = ('_pos',)
64 def __init__(self, auto: Optional[Union[BitsType, int]] = None, /, length: Optional[int] = None,
65 offset: Optional[int] = None, pos: int = 0, **kwargs) -> None:
66 """Either specify an 'auto' initialiser:
67 A string of comma separated tokens, an integer, a file object,
68 a bytearray, a boolean iterable or another bitstring.
70 Or initialise via **kwargs with one (and only one) of:
71 bin -- binary string representation, e.g. '0b001010'.
72 hex -- hexadecimal string representation, e.g. '0x2ef'
73 oct -- octal string representation, e.g. '0o777'.
74 bytes -- raw data as a bytes object, for example read from a binary file.
75 int -- a signed integer.
76 uint -- an unsigned integer.
77 float / floatbe -- a big-endian floating point number.
78 bool -- a boolean (True or False).
79 se -- a signed exponential-Golomb code.
80 ue -- an unsigned exponential-Golomb code.
81 sie -- a signed interleaved exponential-Golomb code.
82 uie -- an unsigned interleaved exponential-Golomb code.
83 floatle -- a little-endian floating point number.
84 floatne -- a native-endian floating point number.
85 bfloat / bfloatbe - a big-endian bfloat format 16-bit floating point number.
86 bfloatle -- a little-endian bfloat format 16-bit floating point number.
87 bfloatne -- a native-endian bfloat format 16-bit floating point number.
88 intbe -- a signed big-endian whole byte integer.
89 intle -- a signed little-endian whole byte integer.
90 intne -- a signed native-endian whole byte integer.
91 uintbe -- an unsigned big-endian whole byte integer.
92 uintle -- an unsigned little-endian whole byte integer.
93 uintne -- an unsigned native-endian whole byte integer.
94 filename -- the path of a file which will be opened in binary read-only mode.
96 Other keyword arguments:
97 length -- length of the bitstring in bits, if needed and appropriate.
98 It must be supplied for all integer and float initialisers.
99 offset -- bit offset to the data. These offset bits are
100 ignored and this is mainly intended for use when
101 initialising using 'bytes' or 'filename'.
102 pos -- Initial bit position, defaults to 0.
104 """
105 pass
107 def __new__(cls, auto: Optional[Union[BitsType, int]] = None, /, length: Optional[int] = None,
108 offset: Optional[int] = None, pos: int = 0, **kwargs) -> TConstBitStream:
109 x = super().__new__(cls, auto, length, offset, **kwargs)
110 if pos < 0:
111 pos += len(x._bitstore)
112 if pos < 0 or pos > len(x._bitstore):
113 raise bitstring.CreationError(f"Cannot set pos to {pos} when length is {len(x._bitstore)}.")
114 x._pos = pos
115 return x
117 def _setbytepos(self, bytepos: int) -> None:
118 """Move to absolute byte-aligned position in stream."""
119 self._setbitpos(bytepos * 8)
121 def _getbytepos(self) -> int:
122 """Return the current position in the stream in bytes. Must be byte aligned."""
123 if self._pos % 8:
124 raise bitstring.ByteAlignError("Not byte aligned when using bytepos property.")
125 return self._pos // 8
127 def _setbitpos(self, pos: int) -> None:
128 """Move to absolute position bit in bitstream."""
129 if pos < 0:
130 raise ValueError("Bit position cannot be negative.")
131 if pos > len(self):
132 raise ValueError("Cannot seek past the end of the data.")
133 self._pos = pos
135 def _getbitpos(self) -> int:
136 """Return the current position in the stream in bits."""
137 return self._pos
139 def _clear(self) -> None:
140 Bits._clear(self)
141 self._pos = 0
143 def __copy__(self: TConstBitStream) -> TConstBitStream:
144 """Return a new copy of the ConstBitStream for the copy module."""
145 # Note that if you want a new copy (different ID), use _copy instead.
146 # The copy can use the same datastore as it's immutable.
147 s = self.__class__()
148 s._bitstore = self._bitstore
149 # Reset the bit position, don't copy it.
150 s._pos = 0
151 return s
153 def __and__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
154 """Bit-wise 'and' between two bitstrings. Returns new bitstring.
156 bs -- The bitstring to '&' with.
158 Raises ValueError if the two bitstrings have differing lengths.
160 """
161 s = Bits.__and__(self, bs)
162 s._pos = 0
163 return s
165 def __or__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
166 """Bit-wise 'or' between two bitstrings. Returns new bitstring.
168 bs -- The bitstring to '|' with.
170 Raises ValueError if the two bitstrings have differing lengths.
172 """
173 s = Bits.__or__(self, bs)
174 s._pos = 0
175 return s
177 def __xor__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
178 """Bit-wise 'xor' between two bitstrings. Returns new bitstring.
180 bs -- The bitstring to '^' with.
182 Raises ValueError if the two bitstrings have differing lengths.
184 """
185 s = Bits.__xor__(self, bs)
186 s._pos = 0
187 return s
189 def __add__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
190 """Concatenate bitstrings and return new bitstring.
192 bs -- the bitstring to append.
194 """
195 s = Bits.__add__(self, bs)
196 s._pos = 0
197 return s
199 def append(self, bs: BitsType, /) -> None:
200 """Append a bitstring to the current bitstring.
202 bs -- The bitstring to append.
204 The current bit position will be moved to the end of the BitStream.
206 """
207 self._append(bs)
208 self._pos = len(self)
210 def __repr__(self) -> str:
211 """Return representation that could be used to recreate the bitstring.
213 If the returned string is too long it will be truncated. See __str__().
215 """
216 return self._repr(self.__class__.__name__, len(self), self._pos)
218 def overwrite(self, bs: BitsType, /, pos: Optional[int] = None) -> None:
219 """Overwrite with bitstring at bit position pos.
221 bs -- The bitstring to overwrite with.
222 pos -- The bit position to begin overwriting from.
224 The current bit position will be moved to the end of the overwritten section.
225 Raises ValueError if pos < 0 or pos > len(self).
227 """
228 bs = Bits._create_from_bitstype(bs)
229 if len(bs) == 0:
230 return
231 if pos is None:
232 pos = self._pos
233 if pos < 0:
234 pos += len(self)
235 if pos < 0 or pos > len(self):
236 raise ValueError("Overwrite starts outside boundary of bitstring.")
237 self._overwrite(bs, pos)
238 self._pos = pos + len(bs)
240 def find(self, bs: BitsType, /, start: Optional[int] = None, end: Optional[int] = None,
241 bytealigned: Optional[bool] = None) -> Union[Tuple[int], Tuple[()]]:
242 """Find first occurrence of substring bs.
244 Returns a single item tuple with the bit position if found, or an
245 empty tuple if not found. The bit position (pos property) will
246 also be set to the start of the substring if it is found.
248 bs -- The bitstring to find.
249 start -- The bit position to start the search. Defaults to 0.
250 end -- The bit position one past the last bit to search.
251 Defaults to len(self).
252 bytealigned -- If True the bitstring will only be
253 found on byte boundaries.
255 Raises ValueError if bs is empty, if start < 0, if end > len(self) or
256 if end < start.
258 >>> BitStream('0xc3e').find('0b1111')
259 (6,)
261 """
263 p = super().find(bs, start, end, bytealigned)
264 if p:
265 self._pos = p[0]
266 return p
268 def rfind(self, bs: BitsType, /, start: Optional[int] = None, end: Optional[int] = None,
269 bytealigned: Optional[bool] = None) -> Union[Tuple[int], Tuple[()]]:
270 """Find final occurrence of substring bs.
272 Returns a single item tuple with the bit position if found, or an
273 empty tuple if not found. The bit position (pos property) will
274 also be set to the start of the substring if it is found.
276 bs -- The bitstring to find.
277 start -- The bit position to end the reverse search. Defaults to 0.
278 end -- The bit position one past the first bit to reverse search.
279 Defaults to len(self).
280 bytealigned -- If True the bitstring will only be found on byte
281 boundaries.
283 Raises ValueError if bs is empty, if start < 0, if end > len(self) or
284 if end < start.
286 """
287 p = super().rfind(bs, start, end, bytealigned)
288 if p:
289 self._pos = p[0]
290 return p
292 @overload
293 def read(self, fmt: int) -> Bits:
294 ...
296 @overload
297 def read(self, fmt: str) -> Any:
298 ...
300 def read(self, fmt: Union[int, str, Dtype]) -> Union[int, float, str, Bits, bool, bytes, None]:
301 """Interpret next bits according to the format string and return result.
303 fmt -- Token string describing how to interpret the next bits.
305 Token examples: 'int:12' : 12 bits as a signed integer
306 'uint:8' : 8 bits as an unsigned integer
307 'float:64' : 8 bytes as a big-endian float
308 'intbe:16' : 2 bytes as a big-endian signed integer
309 'uintbe:16' : 2 bytes as a big-endian unsigned integer
310 'intle:32' : 4 bytes as a little-endian signed integer
311 'uintle:32' : 4 bytes as a little-endian unsigned integer
312 'floatle:64': 8 bytes as a little-endian float
313 'intne:24' : 3 bytes as a native-endian signed integer
314 'uintne:24' : 3 bytes as a native-endian unsigned integer
315 'floatne:32': 4 bytes as a native-endian float
316 'hex:80' : 80 bits as a hex string
317 'oct:9' : 9 bits as an octal string
318 'bin:1' : single bit binary string
319 'ue' : next bits as unsigned exp-Golomb code
320 'se' : next bits as signed exp-Golomb code
321 'uie' : next bits as unsigned interleaved exp-Golomb code
322 'sie' : next bits as signed interleaved exp-Golomb code
323 'bits:5' : 5 bits as a bitstring
324 'bytes:10' : 10 bytes as a bytes object
325 'bool' : 1 bit as a bool
326 'pad:3' : 3 bits of padding to ignore - returns None
328 fmt may also be an integer, which will be treated like the 'bits' token.
330 The position in the bitstring is advanced to after the read items.
332 Raises ReadError if not enough bits are available.
333 Raises ValueError if the format is not understood.
335 """
336 p = self._pos
337 if isinstance(fmt, numbers.Integral):
338 if fmt < 0:
339 raise ValueError("Cannot read negative amount.")
340 if fmt > len(self) - self._pos:
341 raise bitstring.ReadError(f"Cannot read {fmt} bits, only {len(self) - self._pos} available.")
342 bs = self._slice(self._pos, self._pos + fmt)
343 self._pos += fmt
344 return bs
345 dtype = bitstring.dtypes.Dtype(fmt)
346 if dtype.bitlength is None and not dtype.variable_length:
347 # No length specified? Try again, but read to end.
348 bitlength = len(self) - self._pos
349 items, remainder = divmod(bitlength, dtype.bits_per_item)
350 if remainder != 0:
351 raise ValueError(
352 f"The '{dtype.name}' type must have a bit length that is a multiple of {dtype.bits_per_item}"
353 f" so cannot be read from the {bitlength} bits that are available.")
354 dtype = bitstring.dtypes.Dtype(fmt, items)
355 if dtype.bitlength is not None:
356 val = dtype.read_fn(self, self._pos)
357 self._pos += dtype.bitlength
358 else:
359 val, self._pos = dtype.read_fn(self, self._pos)
361 if self._pos > len(self):
362 self._pos = p
363 raise bitstring.ReadError(f"Reading off end of bitstring with fmt '{fmt}'. Only {len(self) - p} bits available.")
364 return val
366 def readlist(self, fmt: Union[str, List[Union[int, str, Dtype]]], **kwargs) \
367 -> List[Union[int, float, str, Bits, bool, bytes, None]]:
368 """Interpret next bits according to format string(s) and return list.
370 fmt -- A single string or list of strings with comma separated tokens
371 describing how to interpret the next bits in the bitstring. Items
372 can also be integers, for reading new bitstring of the given length.
373 kwargs -- A dictionary or keyword-value pairs - the keywords used in the
374 format string will be replaced with their given value.
376 The position in the bitstring is advanced to after the read items.
378 Raises ReadError is not enough bits are available.
379 Raises ValueError if the format is not understood.
381 See the docstring for 'read' for token examples. 'pad' tokens are skipped
382 and not added to the returned list.
384 >>> h, b1, b2 = s.readlist('hex:20, bin:5, bin:3')
385 >>> i, bs1, bs2 = s.readlist(['uint:12', 10, 10])
387 """
388 value, self._pos = self._readlist(fmt, self._pos, **kwargs)
389 return value
391 def readto(self: TConstBitStream, bs: BitsType, /, bytealigned: Optional[bool] = None) -> TConstBitStream:
392 """Read up to and including next occurrence of bs and return result.
394 bs -- The bitstring to find.
395 bytealigned -- If True the bitstring will only be
396 found on byte boundaries.
398 Raises ValueError if bs is empty.
399 Raises ReadError if bs is not found.
401 """
402 if isinstance(bs, numbers.Integral):
403 raise ValueError("Integers cannot be searched for")
404 bs = Bits._create_from_bitstype(bs)
405 oldpos = self._pos
406 p = self.find(bs, self._pos, bytealigned=bytealigned)
407 if not p:
408 raise bitstring.ReadError("Substring not found")
409 self._pos += len(bs)
410 return self._slice(oldpos, self._pos)
412 @overload
413 def peek(self: TConstBitStream, fmt: int) -> TConstBitStream:
414 ...
416 @overload
417 def peek(self, fmt: str) -> Union[int, float, str, TConstBitStream, bool, bytes, None]:
418 ...
420 def peek(self: TConstBitStream, fmt: Union[int, str]) -> Union[int, float, str, TConstBitStream, bool, bytes, None]:
421 """Interpret next bits according to format string and return result.
423 fmt -- Token string describing how to interpret the next bits.
425 The position in the bitstring is not changed. If not enough bits are
426 available then all bits to the end of the bitstring will be used.
428 Raises ReadError if not enough bits are available.
429 Raises ValueError if the format is not understood.
431 See the docstring for 'read' for token examples.
433 """
434 pos_before = self._pos
435 value = self.read(fmt)
436 self._pos = pos_before
437 return value
439 def peeklist(self, fmt: Union[str, List[Union[int, str]]], **kwargs) \
440 -> List[Union[int, float, str, Bits, None]]:
441 """Interpret next bits according to format string(s) and return list.
443 fmt -- One or more integers or strings with comma separated tokens describing
444 how to interpret the next bits in the bitstring.
445 kwargs -- A dictionary or keyword-value pairs - the keywords used in the
446 format string will be replaced with their given value.
448 The position in the bitstring is not changed. If not enough bits are
449 available then all bits to the end of the bitstring will be used.
451 Raises ReadError if not enough bits are available.
452 Raises ValueError if the format is not understood.
454 See the docstring for 'read' for token examples.
456 """
457 pos = self._pos
458 return_values = self.readlist(fmt, **kwargs)
459 self._pos = pos
460 return return_values
462 def bytealign(self) -> int:
463 """Align to next byte and return number of skipped bits.
465 Raises ValueError if the end of the bitstring is reached before
466 aligning to the next byte.
468 """
469 skipped = (8 - (self._pos % 8)) % 8
470 self.pos += skipped
471 return skipped
473 @classmethod
474 def fromstring(cls: TBits, s: str, /) -> TBits:
475 x = super().__new__(cls)
476 x._bitstore = common_helpers.str_to_bitstore(s)
477 x._pos = 0
478 return x
480 @overload
481 def __getitem__(self: TBits, key: slice, /) -> TBits:
482 ...
484 @overload
485 def __getitem__(self: TBits, key: int, /) -> bool:
486 ...
488 def __getitem__(self: TBits, key: Union[slice, int], /) -> Union[TBits, bool]:
489 """Return a new bitstring representing a slice of the current bitstring."""
490 if isinstance(key, numbers.Integral):
491 return bool(self._bitstore.getindex(key))
492 bs = super().__new__(self.__class__)
493 bs._bitstore = self._bitstore.getslice_withstep(key)
494 bs._pos = 0
495 return bs
497 pos = property(_getbitpos, _setbitpos,
498 doc="""The position in the bitstring in bits. Read and write.
499 """)
500 bitpos = property(_getbitpos, _setbitpos,
501 doc="""The position in the bitstring in bits. Read and write.
502 """)
503 bytepos = property(_getbytepos, _setbytepos,
504 doc="""The position in the bitstring in bytes. Read and write.
505 """)
508class BitStream(ConstBitStream, bitstring.BitArray):
509 """A container or stream holding a mutable sequence of bits
511 Subclass of the ConstBitStream and BitArray classes. Inherits all of
512 their methods.
514 Methods:
516 all() -- Check if all specified bits are set to 1 or 0.
517 any() -- Check if any of specified bits are set to 1 or 0.
518 append() -- Append a bitstring.
519 bytealign() -- Align to next byte boundary.
520 byteswap() -- Change byte endianness in-place.
521 clear() -- Remove all bits from the bitstring.
522 copy() -- Return a copy of the bitstring.
523 count() -- Count the number of bits set to 1 or 0.
524 cut() -- Create generator of constant sized chunks.
525 endswith() -- Return whether the bitstring ends with a sub-string.
526 find() -- Find a sub-bitstring in the current bitstring.
527 findall() -- Find all occurrences of a sub-bitstring in the current bitstring.
528 fromstring() -- Create a bitstring from a formatted string.
529 insert() -- Insert a bitstring.
530 invert() -- Flip bit(s) between one and zero.
531 join() -- Join bitstrings together using current bitstring.
532 overwrite() -- Overwrite a section with a new bitstring.
533 peek() -- Peek at and interpret next bits as a single item.
534 peeklist() -- Peek at and interpret next bits as a list of items.
535 pp() -- Pretty print the bitstring.
536 prepend() -- Prepend a bitstring.
537 read() -- Read and interpret next bits as a single item.
538 readlist() -- Read and interpret next bits as a list of items.
539 readto() -- Read up to and including next occurrence of a bitstring.
540 replace() -- Replace occurrences of one bitstring with another.
541 reverse() -- Reverse bits in-place.
542 rfind() -- Seek backwards to find a sub-bitstring.
543 rol() -- Rotate bits to the left.
544 ror() -- Rotate bits to the right.
545 set() -- Set bit(s) to 1 or 0.
546 split() -- Create generator of chunks split by a delimiter.
547 startswith() -- Return whether the bitstring starts with a sub-bitstring.
548 tobitarray() -- Return bitstring as a bitarray from the bitarray package.
549 tobytes() -- Return bitstring as bytes, padding if needed.
550 tofile() -- Write bitstring to file, padding if needed.
551 unpack() -- Interpret bits using format string.
553 Special methods:
555 Mutating operators are available: [], <<=, >>=, +=, *=, &=, |= and ^=
556 in addition to [], ==, !=, +, *, ~, <<, >>, &, | and ^.
558 Properties:
560 [GENERATED_PROPERTY_DESCRIPTIONS]
562 len -- Length of the bitstring in bits.
563 pos -- The current bit position in the bitstring.
564 """
566 __slots__ = ()
568 def __init__(self, auto: Optional[Union[BitsType, int]] = None, /, length: Optional[int] = None,
569 offset: Optional[int] = None, pos: int = 0, **kwargs) -> None:
570 """Either specify an 'auto' initialiser:
571 A string of comma separated tokens, an integer, a file object,
572 a bytearray, a boolean iterable or another bitstring.
574 Or initialise via **kwargs with one (and only one) of:
575 bin -- binary string representation, e.g. '0b001010'.
576 hex -- hexadecimal string representation, e.g. '0x2ef'
577 oct -- octal string representation, e.g. '0o777'.
578 bytes -- raw data as a bytes object, for example read from a binary file.
579 int -- a signed integer.
580 uint -- an unsigned integer.
581 float / floatbe -- a big-endian floating point number.
582 bool -- a boolean (True or False).
583 se -- a signed exponential-Golomb code.
584 ue -- an unsigned exponential-Golomb code.
585 sie -- a signed interleaved exponential-Golomb code.
586 uie -- an unsigned interleaved exponential-Golomb code.
587 floatle -- a little-endian floating point number.
588 floatne -- a native-endian floating point number.
589 bfloat / bfloatbe - a big-endian bfloat format 16-bit floating point number.
590 bfloatle -- a little-endian bfloat format 16-bit floating point number.
591 bfloatne -- a native-endian bfloat format 16-bit floating point number.
592 intbe -- a signed big-endian whole byte integer.
593 intle -- a signed little-endian whole byte integer.
594 intne -- a signed native-endian whole byte integer.
595 uintbe -- an unsigned big-endian whole byte integer.
596 uintle -- an unsigned little-endian whole byte integer.
597 uintne -- an unsigned native-endian whole byte integer.
598 filename -- the path of a file which will be opened in binary read-only mode.
600 Other keyword arguments:
601 length -- length of the bitstring in bits, if needed and appropriate.
602 It must be supplied for all integer and float initialisers.
603 offset -- bit offset to the data. These offset bits are
604 ignored and this is intended for use when
605 initialising using 'bytes' or 'filename'.
606 pos -- Initial bit position, defaults to 0.
608 """
609 ConstBitStream.__init__(self, auto, length, offset, pos, **kwargs)
611 @classmethod
612 def fromstring(cls: TBits, s: str, /) -> TBits:
613 x = super().__new__(cls)
614 b = common_helpers.str_to_bitstore(s)
615 x._bitstore = b._mutable_copy()
616 x._pos = 0
617 return x
619 def __copy__(self) -> BitStream:
620 """Return a new copy of the BitStream."""
621 s_copy = object.__new__(BitStream)
622 s_copy._pos = 0
623 s_copy._bitstore = self._bitstore.copy()
624 return s_copy
626 def __iadd__(self, bs: BitsType, /) -> BitStream:
627 """Append to current bitstring. Return self.
629 bs -- the bitstring to append.
631 The current bit position will be moved to the end of the BitStream.
632 """
633 self._append(bs)
634 self._pos = len(self)
635 return self
637 def prepend(self, bs: BitsType, /) -> None:
638 """Prepend a bitstring to the current bitstring.
640 bs -- The bitstring to prepend.
642 """
643 bs = Bits._create_from_bitstype(bs)
644 super().prepend(bs)
645 self._pos = 0
647 def __setitem__(self, /, key: Union[slice, int], value: BitsType) -> None:
648 length_before = len(self)
649 super().__setitem__(key, value)
650 if len(self) != length_before:
651 self._pos = 0
652 return
654 def __delitem__(self, /, key: Union[slice, int]) -> None:
655 """Delete item or range.
657 >>> a = BitStream('0x001122')
658 >>> del a[8:16]
659 >>> print a
660 0x0022
662 """
663 length_before = len(self)
664 self._bitstore.__delitem__(key)
665 if len(self) != length_before:
666 self._pos = 0
668 def insert(self, bs: BitsType, /, pos: Optional[int] = None) -> None:
669 """Insert bitstring at bit position pos.
671 bs -- The bitstring to insert.
672 pos -- The bit position to insert at.
674 The current bit position will be moved to the end of the inserted section.
675 Raises ValueError if pos < 0 or pos > len(self).
677 """
678 bs = Bits._create_from_bitstype(bs)
679 if len(bs) == 0:
680 return
681 if bs is self:
682 bs = self._copy()
683 if pos is None:
684 pos = self._pos
685 if pos < 0:
686 pos += len(self)
687 if not 0 <= pos <= len(self):
688 raise ValueError("Invalid insert position.")
689 self._insert(bs, pos)
690 self._pos = pos + len(bs)
692 def replace(self, old: BitsType, new: BitsType, start: Optional[int] = None, end: Optional[int] = None,
693 count: Optional[int] = None, bytealigned: Optional[bool] = None) -> int:
694 """Replace all occurrences of old with new in place.
696 Returns number of replacements made.
698 old -- The bitstring to replace.
699 new -- The replacement bitstring.
700 start -- Any occurrences that start before this will not be replaced.
701 Defaults to 0.
702 end -- Any occurrences that finish after this will not be replaced.
703 Defaults to len(self).
704 count -- The maximum number of replacements to make. Defaults to
705 replace all occurrences.
706 bytealigned -- If True replacements will only be made on byte
707 boundaries.
709 Raises ValueError if old is empty or if start or end are
710 out of range.
712 """
713 if count == 0:
714 return 0
715 if len(old := Bits._create_from_bitstype(old)) == 0:
716 raise ValueError("Empty bitstring cannot be replaced.")
717 start, end = self._validate_slice(start, end)
718 new = Bits._create_from_bitstype(new)
719 if new is self:
720 # Prevent self assignment woes
721 new = copy.copy(self)
722 length_before = len(self)
723 replacement_count = self._replace(old, new, start, end, 0 if count is None else count, bytealigned)
724 if len(self) != length_before:
725 self._pos = 0
726 return replacement_count