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

227 statements  

1from __future__ import annotations 

2 

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 

9 

10TConstBitStream = TypeVar("TConstBitStream", bound='ConstBitStream') 

11 

12 

13class ConstBitStream(Bits): 

14 """A container or stream holding an immutable sequence of bits. 

15 

16 For a mutable container use the BitStream class instead. 

17 

18 Methods inherited from Bits: 

19 

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. 

38 

39 Other methods: 

40 

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. 

47 

48 Special methods: 

49 

50 Also available are the operators [], ==, !=, +, *, ~, <<, >>, &, |, ^. 

51 

52 Properties: 

53 

54 [GENERATED_PROPERTY_DESCRIPTIONS] 

55 

56 len -- Length of the bitstring in bits. 

57 pos -- The current bit position in the bitstring. 

58 """ 

59 

60 __slots__ = ('_pos') 

61 

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. 

67 

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. 

93 

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. 

101 

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 

109 

110 def _setbytepos(self, bytepos: int) -> None: 

111 """Move to absolute byte-aligned position in stream.""" 

112 self._setbitpos(bytepos * 8) 

113 

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 

119 

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 

127 

128 def _getbitpos(self) -> int: 

129 """Return the current position in the stream in bits.""" 

130 return self._pos 

131 

132 def _clear(self) -> None: 

133 Bits._clear(self) 

134 self._pos = 0 

135 

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 

145 

146 def __and__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream: 

147 """Bit-wise 'and' between two bitstrings. Returns new bitstring. 

148 

149 bs -- The bitstring to '&' with. 

150 

151 Raises ValueError if the two bitstrings have differing lengths. 

152 

153 """ 

154 s = Bits.__and__(self, bs) 

155 s._pos = 0 

156 return s 

157 

158 def __or__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream: 

159 """Bit-wise 'or' between two bitstrings. Returns new bitstring. 

160 

161 bs -- The bitstring to '|' with. 

162 

163 Raises ValueError if the two bitstrings have differing lengths. 

164 

165 """ 

166 s = Bits.__or__(self, bs) 

167 s._pos = 0 

168 return s 

169 

170 def __xor__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream: 

171 """Bit-wise 'xor' between two bitstrings. Returns new bitstring. 

172 

173 bs -- The bitstring to '^' with. 

174 

175 Raises ValueError if the two bitstrings have differing lengths. 

176 

177 """ 

178 s = Bits.__xor__(self, bs) 

179 s._pos = 0 

180 return s 

181 

182 def __add__(self: TConstBitStream, bs: BitsType, /) -> TConstBitStream: 

183 """Concatenate bitstrings and return new bitstring. 

184 

185 bs -- the bitstring to append. 

186 

187 """ 

188 s = Bits.__add__(self, bs) 

189 s._pos = 0 

190 return s 

191 

192 def append(self, bs: BitsType, /) -> None: 

193 """Append a bitstring to the current bitstring. 

194 

195 bs -- The bitstring to append. 

196 

197 The current bit position will be moved to the end of the BitStream. 

198 

199 """ 

200 self._append(bs) 

201 self._pos = len(self) 

202 

203 def __repr__(self) -> str: 

204 """Return representation that could be used to recreate the bitstring. 

205 

206 If the returned string is too long it will be truncated. See __str__(). 

207 

208 """ 

209 return self._repr(self.__class__.__name__, len(self), self._pos) 

210 

211 def overwrite(self, bs: BitsType, /, pos: Optional[int] = None) -> None: 

212 """Overwrite with bitstring at bit position pos. 

213 

214 bs -- The bitstring to overwrite with. 

215 pos -- The bit position to begin overwriting from. 

216 

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). 

219 

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) 

232 

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. 

236 

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. 

240 

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. 

247 

248 Raises ValueError if bs is empty, if start < 0, if end > len(self) or 

249 if end < start. 

250 

251 >>> BitStream('0xc3e').find('0b1111') 

252 (6,) 

253 

254 """ 

255 

256 p = super().find(bs, start, end, bytealigned) 

257 if p: 

258 self._pos = p[0] 

259 return p 

260 

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. 

264 

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. 

268 

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. 

275 

276 Raises ValueError if bs is empty, if start < 0, if end > len(self) or 

277 if end < start. 

278 

279 """ 

280 p = super().rfind(bs, start, end, bytealigned) 

281 if p: 

282 self._pos = p[0] 

283 return p 

284 

285 @overload 

286 def read(self, fmt: int) -> Bits: 

287 ... 

288 

289 @overload 

290 def read(self, fmt: str) -> Any: 

291 ... 

292 

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. 

295 

296 fmt -- Token string describing how to interpret the next bits. 

297 

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 

320 

321 fmt may also be an integer, which will be treated like the 'bits' token. 

322 

323 The position in the bitstring is advanced to after the read items. 

324 

325 Raises ReadError if not enough bits are available. 

326 Raises ValueError if the format is not understood. 

327 

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) 

353 

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 

358 

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. 

362 

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. 

368 

369 The position in the bitstring is advanced to after the read items. 

370 

371 Raises ReadError is not enough bits are available. 

372 Raises ValueError if the format is not understood. 

373 

374 See the docstring for 'read' for token examples. 'pad' tokens are skipped 

375 and not added to the returned list. 

376 

377 >>> h, b1, b2 = s.readlist('hex:20, bin:5, bin:3') 

378 >>> i, bs1, bs2 = s.readlist(['uint:12', 10, 10]) 

379 

380 """ 

381 value, self._pos = self._readlist(fmt, self._pos, **kwargs) 

382 return value 

383 

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. 

386 

387 bs -- The bitstring to find. 

388 bytealigned -- If True the bitstring will only be 

389 found on byte boundaries. 

390 

391 Raises ValueError if bs is empty. 

392 Raises ReadError if bs is not found. 

393 

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) 

404 

405 @overload 

406 def peek(self: TConstBitStream, fmt: int) -> TConstBitStream: 

407 ... 

408 

409 @overload 

410 def peek(self, fmt: str) -> Union[int, float, str, TConstBitStream, bool, bytes, None]: 

411 ... 

412 

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. 

415 

416 fmt -- Token string describing how to interpret the next bits. 

417 

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. 

420 

421 Raises ReadError if not enough bits are available. 

422 Raises ValueError if the format is not understood. 

423 

424 See the docstring for 'read' for token examples. 

425 

426 """ 

427 pos_before = self._pos 

428 value = self.read(fmt) 

429 self._pos = pos_before 

430 return value 

431 

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. 

435 

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. 

440 

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. 

443 

444 Raises ReadError if not enough bits are available. 

445 Raises ValueError if the format is not understood. 

446 

447 See the docstring for 'read' for token examples. 

448 

449 """ 

450 pos = self._pos 

451 return_values = self.readlist(fmt, **kwargs) 

452 self._pos = pos 

453 return return_values 

454 

455 def bytealign(self) -> int: 

456 """Align to next byte and return number of skipped bits. 

457 

458 Raises ValueError if the end of the bitstring is reached before 

459 aligning to the next byte. 

460 

461 """ 

462 skipped = (8 - (self._pos % 8)) % 8 

463 self.pos += skipped 

464 return skipped 

465 

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 

472 

473 @overload 

474 def __getitem__(self: TBits, key: slice, /) -> TBits: 

475 ... 

476 

477 @overload 

478 def __getitem__(self: TBits, key: int, /) -> bool: 

479 ... 

480 

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 

489 

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 """) 

499 

500 

501class BitStream(ConstBitStream, bitstring.BitArray): 

502 """A container or stream holding a mutable sequence of bits 

503 

504 Subclass of the ConstBitStream and BitArray classes. Inherits all of 

505 their methods. 

506 

507 Methods: 

508 

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. 

545 

546 Special methods: 

547 

548 Mutating operators are available: [], <<=, >>=, +=, *=, &=, |= and ^= 

549 in addition to [], ==, !=, +, *, ~, <<, >>, &, | and ^. 

550 

551 Properties: 

552 

553 [GENERATED_PROPERTY_DESCRIPTIONS] 

554 

555 len -- Length of the bitstring in bits. 

556 pos -- The current bit position in the bitstring. 

557 """ 

558 

559 __slots__ = () 

560 

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. 

566 

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. 

592 

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. 

600 

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 

606 

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 

613 

614 def __iadd__(self, bs: BitsType, /) -> BitStream: 

615 """Append to current bitstring. Return self. 

616 

617 bs -- the bitstring to append. 

618 

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 

624 

625 def prepend(self, bs: BitsType, /) -> None: 

626 """Prepend a bitstring to the current bitstring. 

627 

628 bs -- The bitstring to prepend. 

629 

630 """ 

631 bs = Bits._create_from_bitstype(bs) 

632 super().prepend(bs) 

633 self._pos = 0 

634 

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 

641 

642 def __delitem__(self, /, key: Union[slice, int]) -> None: 

643 """Delete item or range. 

644 

645 >>> a = BitStream('0x001122') 

646 >>> del a[8:16] 

647 >>> print a 

648 0x0022 

649 

650 """ 

651 length_before = len(self) 

652 self._bitstore.__delitem__(key) 

653 if len(self) != length_before: 

654 self._pos = 0 

655 

656 def insert(self, bs: BitsType, /, pos: Optional[int] = None) -> None: 

657 """Insert bitstring at bit position pos. 

658 

659 bs -- The bitstring to insert. 

660 pos -- The bit position to insert at. 

661 

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). 

664 

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) 

679 

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. 

683 

684 Returns number of replacements made. 

685 

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. 

696 

697 Raises ValueError if old is empty or if start or end are 

698 out of range. 

699 

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