@@ -550,6 +550,46 @@ def __iter__(self):
550
550
TagDex = TagCodex () # Make instance
551
551
552
552
553
+ @dataclass (frozen = True )
554
+ class LabelCodex :
555
+ """
556
+ LabelCodex is codex of.
557
+
558
+ Only provide defined codes.
559
+ Undefined are left out so that inclusion(exclusion) via 'in' operator works.
560
+ """
561
+ Tag1 : str = '0J' # 1 B64 char tag with 1 pre pad
562
+ Tag2 : str = '0K' # 2 B64 char tag
563
+ Tag3 : str = 'X' # 3 B64 char tag
564
+ Tag4 : str = '1AAF' # 4 B64 char tag
565
+ Tag5 : str = '0L' # 5 B64 char tag with 1 pre pad
566
+ Tag6 : str = '0M' # 6 B64 char tag
567
+ Tag7 : str = 'Y' # 7 B64 char tag
568
+ Tag8 : str = '1AAN' # 8 B64 char tag
569
+ Tag9 : str = '0N' # 9 B64 char tag with 1 pre pad
570
+ Tag10 : str = '0O' # 10 B64 char tag
571
+ StrB64_L0 : str = '4A' # String Base64 Only Leader Size 0
572
+ StrB64_L1 : str = '5A' # String Base64 Only Leader Size 1
573
+ StrB64_L2 : str = '6A' # String Base64 Only Leader Size 2
574
+ StrB64_Big_L0 : str = '7AAA' # String Base64 Only Big Leader Size 0
575
+ StrB64_Big_L1 : str = '8AAA' # String Base64 Only Big Leader Size 1
576
+ StrB64_Big_L2 : str = '9AAA' # String Base64 Only Big Leader Size 2
577
+ Label1 : str = 'V' # Label1 1 bytes for label lead size 1
578
+ Label2 : str = 'W' # Label2 2 bytes for label lead size 0
579
+ Bytes_L0 : str = '4B' # Byte String lead size 0
580
+ Bytes_L1 : str = '5B' # Byte String lead size 1
581
+ Bytes_L2 : str = '6B' # Byte String lead size 2
582
+ Bytes_Big_L0 : str = '7AAB' # Byte String big lead size 0
583
+ Bytes_Big_L1 : str = '8AAB' # Byte String big lead size 1
584
+ Bytes_Big_L2 : str = '9AAB' # Byte String big lead size 2
585
+
586
+ def __iter__ (self ):
587
+ return iter (astuple (self ))
588
+
589
+
590
+ LabelDex = LabelCodex () # Make instance
591
+
592
+
553
593
554
594
@dataclass (frozen = True )
555
595
class PreCodex :
@@ -2059,16 +2099,13 @@ def __init__(self, tag='', soft='', code=None, **kwa):
2059
2099
2060
2100
"""
2061
2101
if tag :
2062
- if hasattr (tag , "decode" ): # make tag str
2063
- tag = tag .decode ("utf-8" )
2064
- if not Reb64 .match (tag .encode ("utf-8" )):
2102
+ if hasattr (tag , "encode" ): # make tag bytes for regex
2103
+ tag = tag .encode ("utf-8" )
2104
+
2105
+ if not Reb64 .match (tag ):
2065
2106
raise InvalidSoftError (f"Non Base64 chars in { tag = } ." )
2066
- # TagDex tags appear in order of size 1 to 10, at indices 0 to 9
2067
- codes = astuple (TagDex )
2068
- l = len (tag ) # soft not empty so l > 0
2069
- if l > len (codes ):
2070
- raise InvalidSoftError ("Oversized tag={soft}." )
2071
- code = codes [l - 1 ] # get code for for tag of len where (index = len - 1)
2107
+
2108
+ code = self ._codify (tag = tag )
2072
2109
soft = tag
2073
2110
2074
2111
@@ -2077,6 +2114,27 @@ def __init__(self, tag='', soft='', code=None, **kwa):
2077
2114
if (not self ._special (self .code )) or self .code not in TagDex :
2078
2115
raise InvalidCodeError (f"Invalid code={ self .code } for Tagger." )
2079
2116
2117
+
2118
+ @staticmethod
2119
+ def _codify (tag ):
2120
+ """Returns code for tag when tag is appropriately sized Base64
2121
+
2122
+ Parameters:
2123
+ tag (str | bytes): Base64 value
2124
+
2125
+ Returns:
2126
+ code (str): derivation code for tag
2127
+
2128
+ """
2129
+ # TagDex tags appear in order of size 1 to 10, at indices 0 to 9
2130
+ codes = astuple (TagDex )
2131
+ l = len (tag )
2132
+ if l < 1 or l > len (codes ):
2133
+ raise InvalidSoftError (f"Invalid { tag = } size { l = } , empty or oversized." )
2134
+ return codes [l - 1 ] # return code at index = len - 1
2135
+
2136
+
2137
+
2080
2138
@property
2081
2139
def tag (self ):
2082
2140
"""Returns:
@@ -2948,7 +3006,7 @@ class Labeler(Matter):
2948
3006
"""
2949
3007
2950
3008
2951
- def __init__ (self , label = '' , code = None , ** kwa ):
3009
+ def __init__ (self , label = '' , raw = None , code = None , soft = None , ** kwa ):
2952
3010
"""
2953
3011
Inherited Parameters:
2954
3012
(see Matter)
@@ -2958,17 +3016,34 @@ def __init__(self, label='', code=None, **kwa):
2958
3016
2959
3017
"""
2960
3018
self ._label = None
2961
- if label :
2962
- if hasattr (label , "decode" ): # make label a str
2963
- label = label .decode ("utf-8" )
2964
-
2965
- if not Reb64 .match (label .encode ("utf-8" )):
2966
- raise InvalidSoftError (f"Non Base64 chars in { tag = } ." )
2967
3019
2968
- self ._label = label
3020
+ if label :
3021
+ if hasattr (label , "encode" ): # make label bytes
3022
+ label = label .encode ("utf-8" )
3023
+
3024
+ if Reb64 .match (label ): # candidate for Base64 compact encoding
3025
+ try :
3026
+ code = Tagger ._codify (tag = label )
3027
+ soft = label
3028
+ except InvalidSoftError as ex : # too big
3029
+ if label [0 ] != b'A' : # use Bexter code
3030
+ code = MtrDex .StrB64_L0
3031
+ raw = Bexter .rawify (label )
3032
+ else : # use Texter code
3033
+ code = MtrDex .Bytes_L0
3034
+ raw = label
3035
+ else :
3036
+ if len (label ) == 1 :
3037
+ code = MtrDex .Label1
3038
+ elif len (label ) == 2 :
3039
+ code = MtrDex .Label2
3040
+ else :
3041
+ code = MtrDex .Bytes_L0
3042
+ raw = label
2969
3043
3044
+ self ._label = label .decode () # convert bytes to str
2970
3045
2971
- super (Labeler , self ).__init__ (code = code , ** kwa )
3046
+ super (Labeler , self ).__init__ (raw = raw , code = code , soft = soft , ** kwa )
2972
3047
2973
3048
2974
3049
0 commit comments