AlkantarClanX12
Current Path : /opt/cloudlinux/venv/lib/python3.11/site-packages/clcommon/ |
Current File : //opt/cloudlinux/venv/lib/python3.11/site-packages/clcommon/evr_utils.py |
# coding=utf-8 # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT # # author: Ruslan Pisarev <rpisarev@cloudlinux.com> # created: 25.07.13 12:36 # description: alternatives,rpm_compare: hash-string for coding EVR # Examples of serialization you can look at tests/test_evr_utils.py from typing import Union, List, AnyStr, Tuple, Optional __all__ = [ 'serialize_evr' ] def encode_int_to_real_numbers_segment(intgr: Union[int]) -> List[Union[int]]: """ Encode int in real-numbers segment. See http://en.wikipedia.org/wiki/Arithmetic_coding. @param intgr: int for coding in Float an segment [seg_begin, seg_end] @return: list encoding segment """ lst = [] number = intgr while number > 0: number, remainder = divmod(number, 256) lst.append(remainder) lst.append(128 + len(lst)) lst.reverse() return lst def evr_to_float(rpm_data: List[Union[int, AnyStr]]) -> AnyStr: """ Encode List of parts of Version or Epoch or Release in real-numbers segment. See http://en.wikipedia.org/wiki/Arithmetic_coding. @param rpm_data: list to convert in double @return: Converted string """ evr = [] for elem in rpm_data: if isinstance(elem, int): evr.extend(encode_int_to_real_numbers_segment(elem)) elif isinstance(elem, str) and elem.isdigit(): evr.extend(encode_int_to_real_numbers_segment(int(elem))) elif isinstance(elem, str): evr.extend(ord(ch) for ch in elem) else: raise NameError(f'ThisStrange: {elem}') evr.append(0) return "".join([f"{n:02x}" for n in evr]) def serialize_evr(evr: Union[List[AnyStr], Tuple[AnyStr], AnyStr]) -> AnyStr: """ Converts epoch, version and release of package to unique string. Ex: ['1', '2.4.4', '34'] -> '810100008102008104008104000081220000' ['0', '2.2.3', '76.el5_9.cloudlinux'] -> 80000081020081020081030000814c00656c00810500810900636c6f75646c696e75780000 @param evr: List from epoch, version and release @return: str for given list """ ret = '' if not isinstance(evr, (list, tuple)): evr = [evr] for i in evr: ret += evr_to_float(split_segments(i)) + '00' return ret def split_segments(string: Optional[AnyStr]) -> List[AnyStr]: """ Split str of epoch or version or release to numbers and strings. Ex: '76.el5_9.cloudlinux.2' -> ['76', 'el', '5', '9', 'cloudlinux', '2'] @param string: str of epoch or version or release @return: List strings and numbers from EVR """ if string is None: return [] prev_symb = string[0] begin_index = 0 segments = [] for i, el in enumerate(string): # Continue loop if a type of current symbol is equal to a type of previous symbol # Ex: In string 'el7' symbols 'e' and 'l' have the same type (alphabetic) and # we should take the part of string 'el' as whole if str(prev_symb + el).isdigit() or str(prev_symb + el).isalpha(): prev_symb = el continue # skip segement if it is't alpha/numeric if string[begin_index:i].isalnum(): segments.append(string[begin_index:i]) begin_index = i prev_symb = string[begin_index] # skip end of a string if it isn't alpha/numeric if string[begin_index:].isalnum(): segments.append(string[begin_index:]) return segments