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