asn1rt: 2nd step to enable non UNIQUE keys into table constraint
This commit is contained in:
parent
199666cfdf
commit
8144f262e3
|
@ -341,40 +341,76 @@ class ASN1Obj(Element):
|
|||
.format(self.fullname(), val)))
|
||||
if self._SAFE_BNDTAB and self._const_tab and self._const_tab_at:
|
||||
# check val against a constraint defined within the table constraint
|
||||
try:
|
||||
const_val = self._get_tab_obj()
|
||||
except Exception as err:
|
||||
const_val_type, const_val = self._get_tab_obj()
|
||||
if const_val_type == CLASET_NONE:
|
||||
if not self._SILENT:
|
||||
asnlog('%s._from_per_ws: %s, unable to retrieve a defined object, %s'\
|
||||
% (self.__class__.__name__, self._name, err))
|
||||
else:
|
||||
if self._mode == MODE_VALUE and val != const_val or \
|
||||
self._mode == MODE_SET and val not in const_val:
|
||||
elif self._mode == MODE_VALUE and const_val_type == CLASET_UNIQ:
|
||||
if val != const_val:
|
||||
raise(ASN1ObjErr('{0}: value out of table constraint, {1!r}'\
|
||||
.format(self.fullname(), val)))
|
||||
elif self._mode == MODE_SET or const_val_type == CLASET_MULT:
|
||||
if val not in const_val:
|
||||
raise(ASN1ObjErr('{0}: value out of table constraint, {1!r}'\
|
||||
.format(self.fullname(), val)))
|
||||
|
||||
def _get_tab_obj(self):
|
||||
ret = (CLASET_NONE, None)
|
||||
try:
|
||||
IndIdent = self._get_obj_by_path(self._const_tab_at)._const_tab_id
|
||||
IndVal = self._get_val_by_path(self._const_tab_at)
|
||||
except:
|
||||
IndVal = self._get_val_by_path(self._const_tab_at)
|
||||
except Exception:
|
||||
return ret
|
||||
cla_val_type, cla_val = self._const_tab.get(IndIdent, IndVal)
|
||||
if cla_val_type == CLASET_UNIQ and self._const_tab_id in cla_val:
|
||||
return (CLASET_UNIQ, cla_val[self._const_tab_id])
|
||||
elif cla_val_type == CLASET_MULT:
|
||||
# filter cla_val for the given tab_id
|
||||
cla_val = [val[self._const_tab_id] for val in cla_val if self._const_tab_id in val]
|
||||
if len(cla_val) > 1:
|
||||
return (CLASET_MULT, vals)
|
||||
elif cla_val:
|
||||
return (CLASET_UNIQ, vals[0])
|
||||
return ret
|
||||
|
||||
def _get_tab_obj_uniq(self):
|
||||
try:
|
||||
IndIdent = self._get_obj_by_path(self._const_tab_at)._const_tab_id
|
||||
IndVal = self._get_val_by_path(self._const_tab_at)
|
||||
except Exception:
|
||||
raise(ASN1ObjErr('{0}: invalid table constraint @ path, {1!r}'\
|
||||
.format(self.fullname(), self._const_tab_at)))
|
||||
try:
|
||||
claval = self._const_tab(IndIdent, IndVal)
|
||||
except:
|
||||
raise(ASN1ObjErr('{0}: invalid identifier {1} for the table constraint'\
|
||||
.format(self.fullname(), IndIdent)))
|
||||
claval = self._const_tab.get_uniq(IndIdent, IndVal)
|
||||
if claval is None:
|
||||
raise(ASN1ObjErr('{0}: non-existent value {1} for identifier {2} in the table constraint'\
|
||||
.format(self.fullname(), IndVal, IndIdent)))
|
||||
else:
|
||||
try:
|
||||
return claval[self._const_tab_id]
|
||||
except:
|
||||
except KeyError:
|
||||
raise(ASN1ObjErr('{0}: non-existent ident {1} within table constraint value'\
|
||||
.format(self.fullname(), self._const_tab_id)))
|
||||
|
||||
def _get_tab_obj_nonuniq(self):
|
||||
ret = []
|
||||
try:
|
||||
IndIdent = self._get_obj_by_path(self._const_tab_at)._const_tab_id
|
||||
IndVal = self._get_val_by_path(self._const_tab_at)
|
||||
except Exception:
|
||||
return []
|
||||
clavals = self._const_tab.get_mult(IndIdent, IndVal)
|
||||
if not clavals:
|
||||
return []
|
||||
else:
|
||||
ret = []
|
||||
for claval in clavals:
|
||||
try:
|
||||
ret.append( claval[self._const_tab_id] )
|
||||
except KeyError:
|
||||
pass
|
||||
return ret
|
||||
|
||||
#--------------------------------------------------------------------------#
|
||||
# user-friendly generic representation
|
||||
#--------------------------------------------------------------------------#
|
||||
|
|
|
@ -169,12 +169,25 @@ Specific method:
|
|||
# this is using the _lut attribute, which is built at module init
|
||||
# for every CLASS set defined at the root of a module
|
||||
if hasattr(self, '_lut'):
|
||||
if key == self._lut['__lut__']:
|
||||
return self._lut.get(val, (CLASET_NONE, None))
|
||||
if key == self._lut['__key__']:
|
||||
try:
|
||||
return self._lut[val]
|
||||
except KeyError:
|
||||
return (CLASET_NONE, None)
|
||||
if self._CLASET_MULT:
|
||||
return self.get_mult(key, val)
|
||||
ret = self.get_mult(key, val)
|
||||
if len(ret) > 1:
|
||||
return (CLASET_MULT, ret)
|
||||
elif ret:
|
||||
return (CLASET_UNIQ, ret[0])
|
||||
else:
|
||||
(CLASET_NONE, None)
|
||||
else:
|
||||
return self.get_uniq(key, val)
|
||||
ret = self.get_uniq(key, val)
|
||||
if ret:
|
||||
return (CLASET_UNIQ, ret)
|
||||
else:
|
||||
return (CLASET_NONE, None)
|
||||
|
||||
def get_uniq(self, name, val):
|
||||
# this is using an enumeration of all CLASS set of values,
|
||||
|
|
|
@ -234,13 +234,18 @@ Single value: Python 2-tuple
|
|||
def _from_per_ws(self, char):
|
||||
# try to get a defined object from a table constraint
|
||||
if self._TAB_LUT and self._const_tab and self._const_tab_at:
|
||||
try:
|
||||
Obj = self._get_tab_obj()
|
||||
except Exception as err:
|
||||
const_obj_type, const_obj = self._get_tab_obj()
|
||||
if const_obj_type == CLASET_NONE:
|
||||
if not self._SILENT:
|
||||
asnlog('OPEN._from_per_ws: %s, unable to retrieve a table-looked up object, %s'\
|
||||
% (self.fullname(), err))
|
||||
Obj = None
|
||||
elif const_obj_type == CLASET_UNIQ:
|
||||
Obj = const_obj
|
||||
else:
|
||||
# const_obj_type == CLASET_MULT
|
||||
# with PER, no tag to select a given object
|
||||
Obj = const_obj[0]
|
||||
else:
|
||||
# TODO: another way to provide a (set of) potential defined object(s)
|
||||
# is to look into value constraint self._const_val
|
||||
|
@ -250,7 +255,7 @@ Single value: Python 2-tuple
|
|||
#
|
||||
if Obj is None:
|
||||
if self._const_val:
|
||||
asnlog('OPEN._from_per_ws: %s, potential type constraint(s) available'\
|
||||
asnlog('OPEN._from_per_ws: %s, potential type constraint(s) available but unused'\
|
||||
% self.fullname())
|
||||
val, GEN = ASN1CodecPER.decode_unconst_open_ws(char, wrapped=None)
|
||||
assert( isinstance(val, bytes_types) )
|
||||
|
@ -268,13 +273,18 @@ Single value: Python 2-tuple
|
|||
def _from_per(self, char):
|
||||
# try to get a defined object from a table constraint
|
||||
if self._TAB_LUT and self._const_tab and self._const_tab_at:
|
||||
try:
|
||||
Obj = self._get_tab_obj()
|
||||
except Exception as err:
|
||||
const_obj_type, const_obj = self._get_tab_obj()
|
||||
if const_obj_type == CLASET_NONE:
|
||||
if not self._SILENT:
|
||||
asnlog('OPEN._from_per: %s, unable to retrieve a defined object, %s'\
|
||||
asnlog('OPEN._from_per: %s, unable to retrieve a table-looked up object, %s'\
|
||||
% (self.fullname(), err))
|
||||
Obj = None
|
||||
elif const_obj_type == CLASET_UNIQ:
|
||||
Obj = const_obj
|
||||
else:
|
||||
# const_obj_type == CLASET_MULT
|
||||
# with PER, no tag to select a given object
|
||||
Obj = const_obj[0]
|
||||
else:
|
||||
# TODO: another way to provide a (set of) potential defined object(s)
|
||||
# is to look into value constraint self._const_val
|
||||
|
@ -285,7 +295,7 @@ Single value: Python 2-tuple
|
|||
val = ASN1CodecPER.decode_unconst_open(char, wrapped=Obj)
|
||||
if Obj is None:
|
||||
if self._const_val:
|
||||
asnlog('OPEN._from_per: %s, potential type constraint(s) available'\
|
||||
asnlog('OPEN._from_per: %s, potential type constraint(s) available but unused'\
|
||||
% self.fullname())
|
||||
assert( isinstance(val, bytes_types) )
|
||||
self._val = ('_unk_004', val)
|
||||
|
@ -340,12 +350,17 @@ Single value: Python 2-tuple
|
|||
tag, Obj = (cl, tval), None
|
||||
# try to get a defined object from a table constraint
|
||||
if self._TAB_LUT and self._const_tab and self._const_tab_at:
|
||||
try:
|
||||
Obj = self._get_tab_obj()
|
||||
except Exception as err:
|
||||
const_obj_type, const_obj = self._get_tab_obj()
|
||||
if const_obj_type == CLASET_NONE:
|
||||
if not self._SILENT:
|
||||
asnlog('OPEN._decode_ber_cont_ws: %s, unable to retrieve an object in the table '\
|
||||
'constraint (%s)' % (self.fullname(), err))
|
||||
asnlog('OPEN._decode_ber_cont_ws: %s, unable to retrieve a table-looked up object, %s'\
|
||||
% (self.fullname(), err))
|
||||
Obj = None
|
||||
elif const_obj_type == CLASET_UNIQ:
|
||||
Obj = const_obj
|
||||
else:
|
||||
# const_obj_type == CLASET_MULT
|
||||
Obj = get_obj_by_tag(self, tag, const_obj)
|
||||
#
|
||||
elif self._const_val is not None:
|
||||
# another way to provide a (set of) potential defined object(s)
|
||||
|
@ -426,12 +441,17 @@ Single value: Python 2-tuple
|
|||
tag, Obj = (cl, tval), None
|
||||
# try to get a defined object from a table constraint
|
||||
if self._TAB_LUT and self._const_tab and self._const_tab_at:
|
||||
try:
|
||||
Obj = self._get_tab_obj()
|
||||
except Exception as err:
|
||||
const_obj_type, const_obj = self._get_tab_obj()
|
||||
if const_obj_type == CLASET_NONE:
|
||||
if not self._SILENT:
|
||||
asnlog('OPEN._decode_ber_cont: %s, unable to retrieve an object in the table '\
|
||||
'constraint (%s)' % (self.fullname(), err))
|
||||
asnlog('OPEN._decode_ber_cont: %s, unable to retrieve a table-looked up object, %s'\
|
||||
% (self.fullname(), err))
|
||||
Obj = None
|
||||
elif const_obj_type == CLASET_UNIQ:
|
||||
Obj = const_obj
|
||||
else:
|
||||
# const_obj_type == CLASET_MULT
|
||||
Obj = get_obj_by_tag(self, tag, const_obj)
|
||||
#
|
||||
elif self._const_val is not None:
|
||||
# another way to provide a (set of) potential defined object(s)
|
||||
|
|
|
@ -458,14 +458,17 @@ def match_tag(Obj, tag):
|
|||
# Obj is an untagged OPEN / ANY object: this is a bit more tricky again
|
||||
if Obj._TAB_LUT and Obj._const_tab and Obj._const_tab_at:
|
||||
# a usable table constraint is defined
|
||||
try:
|
||||
ConstObj = Obj._get_tab_obj()
|
||||
except Exception as err:
|
||||
# unable to retrieve a corresponding object in the table
|
||||
const_obj_type, const_obj = Obj._get_tab_obj()
|
||||
if const_obj_type == CLASET_NONE:
|
||||
return 3
|
||||
elif const_obj_type == CLASET_UNIQ:
|
||||
ret = match_tag(const_obj, tag)
|
||||
if ret:
|
||||
return ret
|
||||
else:
|
||||
if ConstObj is not None:
|
||||
ret = match_tag(ConstObj, tag)
|
||||
# const_obj_type == CLASET_MULT:
|
||||
for obj in const_obj:
|
||||
ret = match_tag(obj, tag)
|
||||
if ret:
|
||||
return ret
|
||||
elif Obj._const_val:
|
||||
|
@ -491,22 +494,23 @@ def match_tag(Obj, tag):
|
|||
assert()
|
||||
return 0
|
||||
|
||||
def get_obj_by_tag(ObjOpen, tag):
|
||||
def get_obj_by_tag(ObjOpen, tag, ConstList=None):
|
||||
"""Check within the value constraint of an OPEN / ANY object ObjOpen
|
||||
for a given tag (tag_class, tag_value) and return the matching object,
|
||||
in case the tag correspond
|
||||
in case the tag matches
|
||||
"""
|
||||
for ConstObj in ObjOpen._const_val.root:
|
||||
if ConstObj.tagc and tag == ConstObj._tagc[0]:
|
||||
if not ConstList:
|
||||
# build ConstList from ObjOpen._const_val.root and ObjOpen._const_val.ext
|
||||
ConstList = ObjOpen._const_val.root
|
||||
if ObjOpen._const_val.ext:
|
||||
ConstList = ConstList + ObjOpen._const_val.ext
|
||||
#
|
||||
for ConstObj in ConstList:
|
||||
if ConstObj._tagc and tag == ConstObj._tagc[0]:
|
||||
return ConstObj
|
||||
elif ConstObj.TYPE == TYPE_CHOICE and tag in ConstObj._cont_tags:
|
||||
return ConstObj
|
||||
if ObjOpen._const_val.ext:
|
||||
for ConstObj in ObjOpen._const_val.ext:
|
||||
if ConstObj.tagc and tag == ConstObj._tagc[0]:
|
||||
return ConstObj
|
||||
elif ConstObj.TYPE == TYPE_CHOICE and tag in ConstObj._cont_tags:
|
||||
return ConstObj
|
||||
#
|
||||
return None
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
|
|
Loading…
Reference in New Issue