Sindbad~EG File Manager
# 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 __future__ import absolute_import
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('ThisStrange: ' + elem)
evr.append(0)
return "".join(["%02x" % n 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
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists