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

1from __future__ import annotations 

2 

3from bitstring.bitstream import BitStream 

4from bitstring.utils import tokenparser 

5from bitstring.exceptions import CreationError 

6from typing import Union, List 

7 

8 

9def pack(fmt: Union[str, List[str]], *values, **kwargs) -> BitStream: 

10 """Pack the values according to the format string and return a new BitStream. 

11 

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. 

17 

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 

38 

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) 

42 

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