import struct from io import BytesIO from typing import List, Union, Dict def long_to_bytes(x: int) -> bytes: return struct.pack('q', x) def bytes_to_long(b: bytes) -> int: return struct.unpack('q', b)[0] def read_long(bis: BytesIO) -> int: try: return struct.unpack('q', bis.read(8))[0] except IOError: return 0 def object_or_list_as_string(value: Union[str, List[str]]) -> str: if isinstance(value, list): return f"[{','.join(value)}]" return str(value) def map_as_string(map_: Dict[str, str]) -> str: return ','.join(f"{k}={object_or_list_as_string(v)}" for k, v in map_.items()) def map_with_list_as_string(map_: Dict[str, List[str]]) -> str: return ','.join(f"{k}={object_or_list_as_string(v)}" for k, v in map_.items()) def parse_map_string(input_str: str) -> Dict[str, str]: map_ = {} if input_str.startswith('{') and input_str.endswith('}'): for entry in input_str[1:-1].split(','): if len(entry) > 1: key, value = entry.split('=') map_[key] = value return map_ def csv_as_list(input_str: str) -> List[str]: return [item.strip() for item in input_str.strip('[]').split(',')] def add_to_map(map_: Dict[str, List[str]], token: str) -> None: eq_idx = token.index('=') if eq_idx > 0: key = token[:eq_idx] map_[key] = csv_as_list(token[eq_idx+1:]) def parse_map_list_string(input_str: str) -> Dict[str, List[str]]: map_ = {} if input_str.startswith('{') and input_str.endswith('}'): for token in input_str[1:-1].split('],'): add_to_map(map_, token) return map_