Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/bitstring/methods.py: 20%
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.bitstream import BitStream
5from bitstring.utils import tokenparser
6from bitstring.exceptions import CreationError
7from typing import Union, List
9MutableBitStore = bitstring.bitstore.MutableBitStore
10helpers = bitstring.bitstore_helpers
11common_helpers = bitstring.bitstore_common_helpers
14def pack(fmt: Union[str, List[str]], *values, **kwargs) -> BitStream:
15 """Pack the values according to the format string and return a new BitStream.
17 fmt -- A single string or a list of strings with comma separated tokens
18 describing how to create the BitStream.
19 values -- Zero or more values to pack according to the format.
20 kwargs -- A dictionary or keyword-value pairs - the keywords used in the
21 format string will be replaced with their given value.
23 Token examples: 'int:12' : 12 bits as a signed integer
24 'uint:8' : 8 bits as an unsigned integer
25 'float:64' : 8 bytes as a big-endian float
26 'intbe:16' : 2 bytes as a big-endian signed integer
27 'uintbe:16' : 2 bytes as a big-endian unsigned integer
28 'intle:32' : 4 bytes as a little-endian signed integer
29 'uintle:32' : 4 bytes as a little-endian unsigned integer
30 'floatle:64': 8 bytes as a little-endian float
31 'intne:24' : 3 bytes as a native-endian signed integer
32 'uintne:24' : 3 bytes as a native-endian unsigned integer
33 'floatne:32': 4 bytes as a native-endian float
34 'hex:80' : 80 bits as a hex string
35 'oct:9' : 9 bits as an octal string
36 'bin:1' : single bit binary string
37 'ue' / 'uie': next bits as unsigned exp-Golomb code
38 'se' / 'sie': next bits as signed exp-Golomb code
39 'bits:5' : 5 bits as a bitstring object
40 'bytes:10' : 10 bytes as a bytes object
41 'bool' : 1 bit as a bool
42 'pad:3' : 3 zero bits as padding
44 >>> s = pack('uint:12, bits', 100, '0xffe')
45 >>> t = pack(['bits', 'bin:3'], s, '111')
46 >>> u = pack('uint:8=a, uint:8=b, uint:55=a', a=6, b=44)
48 """
49 tokens = []
50 if isinstance(fmt, str):
51 fmt = [fmt]
52 try:
53 for f_item in fmt:
54 _, tkns = tokenparser(f_item, tuple(sorted(kwargs.keys())))
55 tokens.extend(tkns)
56 except ValueError as e:
57 raise CreationError(*e.args)
58 value_iter = iter(values)
59 bsl: List[BitStore] = []
60 try:
61 for name, length, value in tokens:
62 # If the value is in the kwd dictionary then it takes precedence.
63 value = kwargs.get(value, value)
64 # If the length is in the kwd dictionary then use that too.
65 length = kwargs.get(length, length)
66 # Also if we just have a dictionary name then we want to use it
67 if name in kwargs and length is None and value is None:
68 bsl.append(BitStream(kwargs[name])._bitstore)
69 continue
70 if length is not None:
71 length = int(length)
72 if value is None and name != 'pad':
73 # Take the next value from the ones provided
74 value = next(value_iter)
75 if name == 'bits':
76 value = bitstring.bits.Bits(value)
77 if length is not None and length != len(value):
78 raise CreationError(f"Token with length {length} packed with value of length {len(value)}.")
79 bsl.append(value._bitstore)
80 continue
81 bsl.append(common_helpers.bitstore_from_token(name, length, value))
82 except StopIteration:
83 raise CreationError(f"Not enough parameters present to pack according to the "
84 f"format. {len(tokens)} values are needed.")
86 try:
87 next(value_iter)
88 except StopIteration:
89 # Good, we've used up all the *values.
90 s = BitStream()
91 if bitstring.options.lsb0:
92 bsl.reverse()
93 for b in bsl:
94 s._bitstore += b
95 return s
97 raise CreationError(f"Too many parameters present to pack according to the format. Only {len(tokens)} values were expected.")