Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/bitstring/bitstream.py: 42%
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
10TConstBitStream = TypeVar("TConstBitStream", bound='ConstBitStream')
13class ConstBitStream(Bits):
14 """A container or stream holding an immutable sequence of bits.
16 For a mutable container use the BitStream class instead.
18 Methods inherited from Bits:
20 all() -- Check if all specified bits are set to 1 or 0.
21 any() -- Check if any of specified bits are set to 1 or 0.
22 copy() -- Return a copy of the bitstring.
23 count() -- Count the number of bits set to 1 or 0.
24 cut() -- Create generator of constant sized chunks.
25 endswith() -- Return whether the bitstring ends with a sub-string.
26 find() -- Find a sub-bitstring in the current bitstring.
27 findall() -- Find all occurrences of a sub-bitstring in the current bitstring.
28 fromstring() -- Create a bitstring from a formatted string.
29 join() -- Join bitstrings together using current bitstring.
30 pp() -- Pretty print the bitstring.
31 rfind() -- Seek backwards to find a sub-bitstring.
32 split() -- Create generator of chunks split by a delimiter.
33 startswith() -- Return whether the bitstring starts with a sub-bitstring.
34 tobitarray() -- Return bitstring as a bitarray from the bitarray package.
35 tobytes() -- Return bitstring as bytes, padding if needed.
36 tofile() -- Write bitstring to file, padding if needed.
37 unpack() -- Interpret bits using format string.
39 Other methods:
41 bytealign() -- Align to next byte boundary.
42 peek() -- Peek at and interpret next bits as a single item.
43 peeklist() -- Peek at and interpret next bits as a list of items.
44 read() -- Read and interpret next bits as a single item.
45 readlist() -- Read and interpret next bits as a list of items.
46 readto() -- Read up to and including next occurrence of a bitstring.
48 Special methods:
50 Also available are the operators [], ==, !=, +, *, ~, <<, >>, &, |, ^.
52 Properties:
54 [GENERATED_PROPERTY_DESCRIPTIONS]
56 len -- Length of the bitstring in bits.
57 pos -- The current bit position in the bitstring.
58 """
60 __slots__ = ('_pos')
62 def __init__(self, auto: Optional[Union[BitsType, int]] = None, /, length: Optional[int] = None,
63 offset: Optional[int] = None, pos: int = 0, **kwargs) -> None:
64 """Either specify an 'auto' initialiser:
65 A string of comma separated tokens, an integer, a file object,
66 a bytearray, a boolean iterable or another bitstring.
68 Or initialise via **kwargs with one (and only one) of:
69 bin -- binary string representation, e.g. '0b001010'.
70 hex -- hexadecimal string representation, e.g. '0x2ef'
71 oct -- octal string representation, e.g. '0o777'.
72 bytes -- raw data as a bytes object, for example read from a binary file.
73 int -- a signed integer.
74 uint -- an unsigned integer.
75 float / floatbe -- a big-endian floating point number.
76 bool -- a boolean (True or False).
77 se -- a signed exponential-Golomb code.
78 ue -- an unsigned exponential-Golomb code.
79 sie -- a signed interleaved exponential-Golomb code.
80 uie -- an unsigned interleaved exponential-Golomb code.
81 floatle -- a little-endian floating point number.
82 floatne -- a native-endian floating point number.
83 bfloat / bfloatbe - a big-endian bfloat format 16-bit floating point number.
84 bfloatle -- a little-endian bfloat format 16-bit floating point number.
85 bfloatne -- a native-endian bfloat format 16-bit floating point number.
86 intbe -- a signed big-endian whole byte integer.
87 intle -- a signed little-endian whole byte integer.
88 intne -- a signed native-endian whole byte integer.
89 uintbe -- an unsigned big-endian whole byte integer.
90 uintle -- an unsigned little-endian whole byte integer.
91 uintne -- an unsigned native-endian whole byte integer.
92 filename -- the path of a file which will be opened in binary read-only mode.
94 Other keyword arguments:
95 length -- length of the bitstring in bits, if needed and appropriate.
96 It must be supplied for all integer and float initialisers.
97 offset -- bit offset to the data. These offset bits are
98 ignored and this is mainly intended for use when
99 initialising using 'bytes' or 'filename'.
100 pos -- Initial bit position, defaults to 0.
102 """
103 if pos < 0:
104 pos += len(self._bitstore)
105 if pos < 0 or pos > len(self._bitstore):
106 raise bitstring.CreationError(f"Cannot set pos to {pos} when length is {len(self._bitstore)}.")
107 self._pos = pos
108 self._bitstore.immutable = True
110 def _setbytepos(self, bytepos: int) -> None:
111 """Move to absolute byte-aligned position in stream."""
112 self._setbitpos(bytepos * 8)
114 def _getbytepos(self) -> int:
115 """Return the current position in the stream in bytes. Must be byte aligned."""
116 if self._pos % 8:
117 raise bitstring.ByteAlignError("Not byte aligned when using bytepos property.")
118 return self._pos // 8
120 def _setbitpos(self, pos: int) -> None:
121 """Move to absolute position bit in bitstream."""
122 if pos < 0:
123 raise ValueError("Bit position cannot be negative.")
124 if pos > len(self):
125 raise ValueError("Cannot seek past the end of the data.")
126 self._pos = pos
128 def _getbitpos(self) -> int:
129 """Return the current position in the stream in bits."""
130 return self._pos
132 def _clear(self) -> None:
133 Bits._clear(self)
134 self._pos = 0
136 def __copy__(self: TConstBitStream) -> TConstBitStream:
137 """Return a new copy of the ConstBitStream for the copy module."""
138 # Note that if you want a new copy (different ID), use _copy instead.
139 # The copy can use the same datastore as it's immutable.
140 s = self.__class__()
141 s._bitstore = self._bitstore
142 # Reset the bit position, don't copy it.
143 s._pos = 0
144 return s
146 def __and__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
147 """Bit-wise 'and' between two bitstrings. Returns new bitstring.
149 bs -- The bitstring to '&' with.
151 Raises ValueError if the two bitstrings have differing lengths.
153 """
154 s = Bits.__and__(self, bs)
155 s._pos = 0
156 return s
158 def __or__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
159 """Bit-wise 'or' between two bitstrings. Returns new bitstring.
161 bs -- The bitstring to '|' with.
163 Raises ValueError if the two bitstrings have differing lengths.
165 """
166 s = Bits.__or__(self, bs)
167 s._pos = 0
168 return s
170 def __xor__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
171 """Bit-wise 'xor' between two bitstrings. Returns new bitstring.
173 bs -- The bitstring to '^' with.
175 Raises ValueError if the two bitstrings have differing lengths.
177 """
178 s = Bits.__xor__(self, bs)
179 s._pos = 0
180 return s
182 def __add__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream:
183 """Concatenate bitstrings and return new bitstring.
185 bs -- the bitstring to append.
187 """
188 s = Bits.__add__(self, bs)
189 s._pos = 0
190 return s
192 def append(self, bs: BitsType, /) -> None:
193 """Append a bitstring to the current bitstring.
195 bs -- The bitstring to append.
197 The current bit position will be moved to the end of the BitStream.
199 """
200 self._append(bs)
201 self._pos = len(self)
203 def __repr__(self) -> str:
204 """Return representation that could be used to recreate the bitstring.
206 If the returned string is too long it will be truncated. See __str__().
208 """
209 return self._repr(self.__class__.__name__, len(self), self._pos)
211 def overwrite(self, bs: BitsType, /, pos: Optional[int] = None) -> None:
212 """Overwrite with bitstring at bit position pos.
214 bs -- The bitstring to overwrite with.
215 pos -- The bit position to begin overwriting from.
217 The current bit position will be moved to the end of the overwritten section.
218 Raises ValueError if pos < 0 or pos > len(self).
220 """
221 bs = Bits._create_from_bitstype(bs)
222 if len(bs) == 0:
223 return
224 if pos is None:
225 pos = self._pos
226 if pos < 0:
227 pos += len(self)
228 if pos < 0 or pos > len(self):
229 raise ValueError("Overwrite starts outside boundary of bitstring.")
230 self._overwrite(bs, pos)
231 self._pos = pos + len(bs)
233 def find(self, bs: BitsType, /, start: Optional[int] = None, end: Optional[int] = None,
234 bytealigned: Optional[bool] = None) -> Union[Tuple[int], Tuple[()]]:
235 """Find first occurrence of substring bs.
237 Returns a single item tuple with the bit position if found, or an
238 empty tuple if not found. The bit position (pos property) will
239 also be set to the start of the substring if it is found.
241 bs -- The bitstring to find.
242 start -- The bit position to start the search. Defaults to 0.
243 end -- The bit position one past the last bit to search.
244 Defaults to len(self).
245 bytealigned -- If True the bitstring will only be
246 found on byte boundaries.
248 Raises ValueError if bs is empty, if start < 0, if end > len(self) or
249 if end < start.
251 >>> BitStream('0xc3e').find('0b1111')
252 (6,)
254 """
256 p = super().find(bs, start, end, bytealigned)
257 if p:
258 self._pos = p[0]
259 return p
261 def rfind(self, bs: BitsType, /, start: Optional[int] = None, end: Optional[int] = None,
262 bytealigned: Optional[bool] = None) -> Union[Tuple[int], Tuple[()]]:
263 """Find final occurrence of substring bs.
265 Returns a single item tuple with the bit position if found, or an
266 empty tuple if not found. The bit position (pos property) will
267 also be set to the start of the substring if it is found.
269 bs -- The bitstring to find.
270 start -- The bit position to end the reverse search. Defaults to 0.
271 end -- The bit position one past the first bit to reverse search.
272 Defaults to len(self).
273 bytealigned -- If True the bitstring will only be found on byte
274 boundaries.
276 Raises ValueError if bs is empty, if start < 0, if end > len(self) or
277 if end < start.
279 """
280 p = super().rfind(bs, start, end, bytealigned)
281 if p:
282 self._pos = p[0]
283 return p
285 @overload
286 def read(self, fmt: int) -> Bits:
287 ...
289 @overload
290 def read(self, fmt: str) -> Any:
291 ...
293 def read(self, fmt: Union[int, str, Dtype]) -> Union[int, float, str, Bits, bool, bytes, None]:
294 """Interpret next bits according to the format string and return result.
296 fmt -- Token string describing how to interpret the next bits.
298 Token examples: 'int:12' : 12 bits as a signed integer
299 'uint:8' : 8 bits as an unsigned integer
300 'float:64' : 8 bytes as a big-endian float
301 'intbe:16' : 2 bytes as a big-endian signed integer
302 'uintbe:16' : 2 bytes as a big-endian unsigned integer
303 'intle:32' : 4 bytes as a little-endian signed integer
304 'uintle:32' : 4 bytes as a little-endian unsigned integer
305 'floatle:64': 8 bytes as a little-endian float
306 'intne:24' : 3 bytes as a native-endian signed integer
307 'uintne:24' : 3 bytes as a native-endian unsigned integer
308 'floatne:32': 4 bytes as a native-endian float
309 'hex:80' : 80 bits as a hex string
310 'oct:9' : 9 bits as an octal string
311 'bin:1' : single bit binary string
312 'ue' : next bits as unsigned exp-Golomb code
313 'se' : next bits as signed exp-Golomb code
314 'uie' : next bits as unsigned interleaved exp-Golomb code
315 'sie' : next bits as signed interleaved exp-Golomb code
316 'bits:5' : 5 bits as a bitstring
317 'bytes:10' : 10 bytes as a bytes object
318 'bool' : 1 bit as a bool
319 'pad:3' : 3 bits of padding to ignore - returns None
321 fmt may also be an integer, which will be treated like the 'bits' token.
323 The position in the bitstring is advanced to after the read items.
325 Raises ReadError if not enough bits are available.
326 Raises ValueError if the format is not understood.
328 """
329 p = self._pos
330 if isinstance(fmt, numbers.Integral):
331 if fmt < 0:
332 raise ValueError("Cannot read negative amount.")
333 if fmt > len(self) - self._pos:
334 raise bitstring.ReadError(f"Cannot read {fmt} bits, only {len(self) - self._pos} available.")
335 bs = self._slice(self._pos, self._pos + fmt)
336 self._pos += fmt
337 return bs
338 dtype = bitstring.dtypes.Dtype(fmt)
339 if dtype.bitlength is None and not dtype.variable_length:
340 # No length specified? Try again, but read to end.
341 bitlength = len(self) - self._pos
342 items, remainder = divmod(bitlength, dtype.bits_per_item)
343 if remainder != 0:
344 raise ValueError(
345 f"The '{dtype.name}' type must have a bit length that is a multiple of {dtype.bits_per_item}"
346 f" so cannot be read from the {bitlength} bits that are available.")
347 dtype = bitstring.dtypes.Dtype(fmt, items)
348 if dtype.bitlength is not None:
349 val = dtype.read_fn(self, self._pos)
350 self._pos += dtype.bitlength
351 else:
352 val, self._pos = dtype.read_fn(self, self._pos)
354 if self._pos > len(self):
355 self._pos = p
356 raise bitstring.ReadError(f"Reading off end of bitstring with fmt '{fmt}'. Only {len(self) - p} bits available.")
357 return val
359 def readlist(self, fmt: Union[str, List[Union[int, str, Dtype]]], **kwargs) \
360 -> List[Union[int, float, str, Bits, bool, bytes, None]]:
361 """Interpret next bits according to format string(s) and return list.
363 fmt -- A single string or list of strings with comma separated tokens
364 describing how to interpret the next bits in the bitstring. Items
365 can also be integers, for reading new bitstring of the given length.
366 kwargs -- A dictionary or keyword-value pairs - the keywords used in the
367 format string will be replaced with their given value.
369 The position in the bitstring is advanced to after the read items.
371 Raises ReadError is not enough bits are available.
372 Raises ValueError if the format is not understood.
374 See the docstring for 'read' for token examples. 'pad' tokens are skipped
375 and not added to the returned list.
377 >>> h, b1, b2 = s.readlist('hex:20, bin:5, bin:3')
378 >>> i, bs1, bs2 = s.readlist(['uint:12', 10, 10])
380 """
381 value, self._pos = self._readlist(fmt, self._pos, **kwargs)
382 return value
384 def readto(self: TConstBitStream, bs: BitsType, /, bytealigned: Optional[bool] = None) -> TConstBitStream:
385 """Read up to and including next occurrence of bs and return result.
387 bs -- The bitstring to find.
388 bytealigned -- If True the bitstring will only be
389 found on byte boundaries.
391 Raises ValueError if bs is empty.
392 Raises ReadError if bs is not found.
394 """
395 if isinstance(bs, numbers.Integral):
396 raise ValueError("Integers cannot be searched for")
397 bs = Bits._create_from_bitstype(bs)
398 oldpos = self._pos
399 p = self.find(bs, self._pos, bytealigned=bytealigned)
400 if not p:
401 raise bitstring.ReadError("Substring not found")
402 self._pos += len(bs)
403 return self._slice(oldpos, self._pos)
405 @overload
406 def peek(self: TConstBitStream, fmt: int) -> TConstBitStream:
407 ...
409 @overload
410 def peek(self, fmt: str) -> Union[int, float, str, TConstBitStream, bool, bytes, None]:
411 ...
413 def peek(self: TConstBitStream, fmt: Union[int, str]) -> Union[int, float, str, TConstBitStream, bool, bytes, None]:
414 """Interpret next bits according to format string and return result.
416 fmt -- Token string describing how to interpret the next bits.
418 The position in the bitstring is not changed. If not enough bits are
419 available then all bits to the end of the bitstring will be used.
421 Raises ReadError if not enough bits are available.
422 Raises ValueError if the format is not understood.
424 See the docstring for 'read' for token examples.
426 """
427 pos_before = self._pos
428 value = self.read(fmt)
429 self._pos = pos_before
430 return value
432 def peeklist(self, fmt: Union[str, List[Union[int, str]]], **kwargs) \
433 -> List[Union[int, float, str, Bits, None]]:
434 """Interpret next bits according to format string(s) and return list.
436 fmt -- One or more integers or strings with comma separated tokens describing
437 how to interpret the next bits in the bitstring.
438 kwargs -- A dictionary or keyword-value pairs - the keywords used in the
439 format string will be replaced with their given value.
441 The position in the bitstring is not changed. If not enough bits are
442 available then all bits to the end of the bitstring will be used.
444 Raises ReadError if not enough bits are available.
445 Raises ValueError if the format is not understood.
447 See the docstring for 'read' for token examples.
449 """
450 pos = self._pos
451 return_values = self.readlist(fmt, **kwargs)
452 self._pos = pos
453 return return_values
455 def bytealign(self) -> int:
456 """Align to next byte and return number of skipped bits.
458 Raises ValueError if the end of the bitstring is reached before
459 aligning to the next byte.
461 """
462 skipped = (8 - (self._pos % 8)) % 8
463 self.pos += skipped
464 return skipped
466 @classmethod
467 def fromstring(cls: TBits, s: str, /) -> TBits:
468 x = super().fromstring(s)
469 x._pos = 0
470 x._bitstore.immutable = True
471 return x
473 @overload
474 def __getitem__(self: TBits, key: slice, /) -> TBits:
475 ...
477 @overload
478 def __getitem__(self: TBits, key: int, /) -> bool:
479 ...
481 def __getitem__(self: TBits, key: Union[slice, int], /) -> Union[TBits, bool]:
482 """Return a new bitstring representing a slice of the current bitstring."""
483 if isinstance(key, numbers.Integral):
484 return bool(self._bitstore.getindex(key))
485 bs = super().__new__(self.__class__)
486 bs._bitstore = self._bitstore.getslice_withstep(key)
487 bs._pos = 0
488 return bs
490 pos = property(_getbitpos, _setbitpos,
491 doc="""The position in the bitstring in bits. Read and write.
492 """)
493 bitpos = property(_getbitpos, _setbitpos,
494 doc="""The position in the bitstring in bits. Read and write.
495 """)
496 bytepos = property(_getbytepos, _setbytepos,
497 doc="""The position in the bitstring in bytes. Read and write.
498 """)
501class BitStream(ConstBitStream, bitstring.BitArray):
502 """A container or stream holding a mutable sequence of bits
504 Subclass of the ConstBitStream and BitArray classes. Inherits all of
505 their methods.
507 Methods:
509 all() -- Check if all specified bits are set to 1 or 0.
510 any() -- Check if any of specified bits are set to 1 or 0.
511 append() -- Append a bitstring.
512 bytealign() -- Align to next byte boundary.
513 byteswap() -- Change byte endianness in-place.
514 clear() -- Remove all bits from the bitstring.
515 copy() -- Return a copy of the bitstring.
516 count() -- Count the number of bits set to 1 or 0.
517 cut() -- Create generator of constant sized chunks.
518 endswith() -- Return whether the bitstring ends with a sub-string.
519 find() -- Find a sub-bitstring in the current bitstring.
520 findall() -- Find all occurrences of a sub-bitstring in the current bitstring.
521 fromstring() -- Create a bitstring from a formatted string.
522 insert() -- Insert a bitstring.
523 invert() -- Flip bit(s) between one and zero.
524 join() -- Join bitstrings together using current bitstring.
525 overwrite() -- Overwrite a section with a new bitstring.
526 peek() -- Peek at and interpret next bits as a single item.
527 peeklist() -- Peek at and interpret next bits as a list of items.
528 pp() -- Pretty print the bitstring.
529 prepend() -- Prepend a bitstring.
530 read() -- Read and interpret next bits as a single item.
531 readlist() -- Read and interpret next bits as a list of items.
532 readto() -- Read up to and including next occurrence of a bitstring.
533 replace() -- Replace occurrences of one bitstring with another.
534 reverse() -- Reverse bits in-place.
535 rfind() -- Seek backwards to find a sub-bitstring.
536 rol() -- Rotate bits to the left.
537 ror() -- Rotate bits to the right.
538 set() -- Set bit(s) to 1 or 0.
539 split() -- Create generator of chunks split by a delimiter.
540 startswith() -- Return whether the bitstring starts with a sub-bitstring.
541 tobitarray() -- Return bitstring as a bitarray from the bitarray package.
542 tobytes() -- Return bitstring as bytes, padding if needed.
543 tofile() -- Write bitstring to file, padding if needed.
544 unpack() -- Interpret bits using format string.
546 Special methods:
548 Mutating operators are available: [], <<=, >>=, +=, *=, &=, |= and ^=
549 in addition to [], ==, !=, +, *, ~, <<, >>, &, | and ^.
551 Properties:
553 [GENERATED_PROPERTY_DESCRIPTIONS]
555 len -- Length of the bitstring in bits.
556 pos -- The current bit position in the bitstring.
557 """
559 __slots__ = ()
561 def __init__(self, auto: Optional[Union[BitsType, int]] = None, /, length: Optional[int] = None,
562 offset: Optional[int] = None, pos: int = 0, **kwargs) -> None:
563 """Either specify an 'auto' initialiser:
564 A string of comma separated tokens, an integer, a file object,
565 a bytearray, a boolean iterable or another bitstring.
567 Or initialise via **kwargs with one (and only one) of:
568 bin -- binary string representation, e.g. '0b001010'.
569 hex -- hexadecimal string representation, e.g. '0x2ef'
570 oct -- octal string representation, e.g. '0o777'.
571 bytes -- raw data as a bytes object, for example read from a binary file.
572 int -- a signed integer.
573 uint -- an unsigned integer.
574 float / floatbe -- a big-endian floating point number.
575 bool -- a boolean (True or False).
576 se -- a signed exponential-Golomb code.
577 ue -- an unsigned exponential-Golomb code.
578 sie -- a signed interleaved exponential-Golomb code.
579 uie -- an unsigned interleaved exponential-Golomb code.
580 floatle -- a little-endian floating point number.
581 floatne -- a native-endian floating point number.
582 bfloat / bfloatbe - a big-endian bfloat format 16-bit floating point number.
583 bfloatle -- a little-endian bfloat format 16-bit floating point number.
584 bfloatne -- a native-endian bfloat format 16-bit floating point number.
585 intbe -- a signed big-endian whole byte integer.
586 intle -- a signed little-endian whole byte integer.
587 intne -- a signed native-endian whole byte integer.
588 uintbe -- an unsigned big-endian whole byte integer.
589 uintle -- an unsigned little-endian whole byte integer.
590 uintne -- an unsigned native-endian whole byte integer.
591 filename -- the path of a file which will be opened in binary read-only mode.
593 Other keyword arguments:
594 length -- length of the bitstring in bits, if needed and appropriate.
595 It must be supplied for all integer and float initialisers.
596 offset -- bit offset to the data. These offset bits are
597 ignored and this is intended for use when
598 initialising using 'bytes' or 'filename'.
599 pos -- Initial bit position, defaults to 0.
601 """
602 ConstBitStream.__init__(self, auto, length, offset, pos, **kwargs)
603 if self._bitstore.immutable:
604 self._bitstore = self._bitstore._copy()
605 self._bitstore.immutable = False
607 def __copy__(self) -> BitStream:
608 """Return a new copy of the BitStream."""
609 s_copy = object.__new__(BitStream)
610 s_copy._pos = 0
611 s_copy._bitstore = self._bitstore.copy()
612 return s_copy
614 def __iadd__(self, bs: BitsType, /) -> BitStream:
615 """Append to current bitstring. Return self.
617 bs -- the bitstring to append.
619 The current bit position will be moved to the end of the BitStream.
620 """
621 self._append(bs)
622 self._pos = len(self)
623 return self
625 def prepend(self, bs: BitsType, /) -> None:
626 """Prepend a bitstring to the current bitstring.
628 bs -- The bitstring to prepend.
630 """
631 bs = Bits._create_from_bitstype(bs)
632 super().prepend(bs)
633 self._pos = 0
635 def __setitem__(self, /, key: Union[slice, int], value: BitsType) -> None:
636 length_before = len(self)
637 super().__setitem__(key, value)
638 if len(self) != length_before:
639 self._pos = 0
640 return
642 def __delitem__(self, /, key: Union[slice, int]) -> None:
643 """Delete item or range.
645 >>> a = BitStream('0x001122')
646 >>> del a[8:16]
647 >>> print a
648 0x0022
650 """
651 length_before = len(self)
652 self._bitstore.__delitem__(key)
653 if len(self) != length_before:
654 self._pos = 0
656 def insert(self, bs: BitsType, /, pos: Optional[int] = None) -> None:
657 """Insert bitstring at bit position pos.
659 bs -- The bitstring to insert.
660 pos -- The bit position to insert at.
662 The current bit position will be moved to the end of the inserted section.
663 Raises ValueError if pos < 0 or pos > len(self).
665 """
666 bs = Bits._create_from_bitstype(bs)
667 if len(bs) == 0:
668 return
669 if bs is self:
670 bs = self._copy()
671 if pos is None:
672 pos = self._pos
673 if pos < 0:
674 pos += len(self)
675 if not 0 <= pos <= len(self):
676 raise ValueError("Invalid insert position.")
677 self._insert(bs, pos)
678 self._pos = pos + len(bs)
680 def replace(self, old: BitsType, new: BitsType, start: Optional[int] = None, end: Optional[int] = None,
681 count: Optional[int] = None, bytealigned: Optional[bool] = None) -> int:
682 """Replace all occurrences of old with new in place.
684 Returns number of replacements made.
686 old -- The bitstring to replace.
687 new -- The replacement bitstring.
688 start -- Any occurrences that start before this will not be replaced.
689 Defaults to 0.
690 end -- Any occurrences that finish after this will not be replaced.
691 Defaults to len(self).
692 count -- The maximum number of replacements to make. Defaults to
693 replace all occurrences.
694 bytealigned -- If True replacements will only be made on byte
695 boundaries.
697 Raises ValueError if old is empty or if start or end are
698 out of range.
700 """
701 if count == 0:
702 return 0
703 if len(old := Bits._create_from_bitstype(old)) == 0:
704 raise ValueError("Empty bitstring cannot be replaced.")
705 start, end = self._validate_slice(start, end)
706 new = Bits._create_from_bitstype(new)
707 if new is self:
708 # Prevent self assignment woes
709 new = copy.copy(self)
710 length_before = len(self)
711 replacement_count = self._replace(old, new, start, end, 0 if count is None else count, bytealigned)
712 if len(self) != length_before:
713 self._pos = 0
714 return replacement_count