AddrIdxList: cleanups, new id_str property

This commit is contained in:
The MMGen Project 2022-12-01 12:32:31 +00:00
commit d9a2e0cfd1
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
3 changed files with 71 additions and 30 deletions

View file

@ -31,35 +31,52 @@ def dmsg_sc(desc,data):
if g.debug_addrlist:
Msg(f'sc_debug_{desc}: {data}')
class AddrIdxList(list,InitErrors,MMGenObject):
class AddrIdxList(tuple,InitErrors,MMGenObject):
max_len = 1000000
def __init__(self,fmt_str=None,idx_list=None,sep=','):
def __new__(cls,fmt_str=None,idx_list=None,sep=','):
try:
if idx_list:
return list.__init__(self,sorted({AddrIdx(i) for i in idx_list}))
elif fmt_str:
ret = []
for i in (fmt_str.split(sep)):
j = i.split('-')
if len(j) == 1:
idx = AddrIdx(i)
if not idx:
break
ret.append(idx)
elif len(j) == 2:
beg = AddrIdx(j[0])
if not beg:
break
end = AddrIdx(j[1])
if not beg or (end < beg):
break
ret.extend([AddrIdx(x) for x in range(beg,end+1)])
else: break
else:
return list.__init__(self,sorted(set(ret))) # fell off end of loop - success
raise ValueError(f'{i!r}: invalid range')
if fmt_str:
def gen():
for i in (fmt_str.split(sep)):
j = [int(x) for x in i.split('-')]
if len(j) == 1:
yield j[0]
elif len(j) == 2:
if j[0] > j[1]:
raise ValueError(f'{i}: invalid range')
for k in range(j[0], j[1] + 1):
yield k
else:
raise ValueError(f'{i}: invalid range')
idx_list = tuple(gen())
return tuple.__new__(cls,sorted({AddrIdx(i) for i in (idx_list or [])}))
except Exception as e:
return type(self).init_fail(e,idx_list or fmt_str)
return cls.init_fail(e,idx_list or fmt_str)
@property
def id_str(self):
def gen():
i_save = self[0]
yield f'{i_save}'
in_range = False
for i in self[1:]:
if i - i_save == 1:
in_range = True
else:
if in_range:
in_range = False
yield f'-{i_save}'
yield f',{i}'
i_save = i
if in_range:
yield f'-{i_save}'
return ''.join(gen()) if self else ''
class AddrListEntryBase(MMGenListItem):
invalid_attrs = {'proto'}

View file

@ -57,11 +57,11 @@ tests = {
},
'AddrIdxList': {
'arg1': 'fmt_str',
'bad': ('x','5,9,1-2-3','8,-11','66,3-2'),
'bad': ('x','5,9,1-2-3','8,-11','66,3-2','0-3'),
'good': (
('3,2,2',[2,3]),
('101,1,3,5,2-7,99',[1,2,3,4,5,6,7,99,101]),
({'idx_list':AddrIdxList('1-5')},[1,2,3,4,5])
('3,2,2',(2,3)),
('101,1,3,5,2-7,99',(1,2,3,4,5,6,7,99,101)),
({'idx_list':AddrIdxList('1-5')},(1,2,3,4,5))
)
},
'SubSeedIdxRange': {

View file

@ -55,6 +55,30 @@ def do_test(list_type,chksum,idx_spec=None,pw_id_str=None,add_kwargs=None):
class unit_tests:
def idxlist(self,name,ut):
for i,o in (
('99,88-102,1-3,4,9,818,444-445,816', '1-4,9,88-102,444-445,816,818'),
('99,88-99,100,102,4-7,9,818,444-445,816,1', '1,4-7,9,88-100,102,444-445,816,818'),
('8', '8'),
('2-4', '2-4'),
('1,2-4', '1-4'),
('2-4,1-9,9,1,8', '1-9'),
('2-4,1', '1-4'),
('2-2', '2'),
('2,2', '2'),
('2-3', '2-3'),
('2,3', '2-3'),
('3,2', '2-3'),
('2,4', '2,4'),
('', ''),
):
l = AddrIdxList(i)
if opt.verbose:
msg('list: {}\nin: {}\nout: {}\n'.format(list(l),i,o))
assert l.id_str == o, f'{l.id_str} != {o}'
return True
def addr(self,name,ut):
return (
do_test(AddrList,'BCE8 082C 0973 A525','1-3') and