laforge has submitted this change. (
https://gerrit.osmocom.org/c/python/pyosmocom/+/38202?usp=email )
Change subject: osmocom.utils: Make b2h/i2h/swap_nibbles return hexstr type
......................................................................
osmocom.utils: Make b2h/i2h/swap_nibbles return hexstr type
Change-Id: I4c72c33baf6e4b3a39fb28d72ad66fbd3e957e95
---
M src/osmocom/utils.py
1 file changed, 40 insertions(+), 38 deletions(-)
Approvals:
fixeria: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/src/osmocom/utils.py b/src/osmocom/utils.py
index 183bbb8..6c91783 100644
--- a/src/osmocom/utils.py
+++ b/src/osmocom/utils.py
@@ -27,7 +27,39 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-# just to differentiate strings of hex nibbles from everything else
+class hexstr(str):
+ """Class derived from 'str', represeting a string of
hexadecimal digits. It differs in that
+ comparisons are case-insensitive, and it offers encoding-free conversion from hexstr
to bytes
+ and vice-versa."""
+ def __new__(cls, s: str):
+ if not all(c in string.hexdigits for c in s):
+ raise ValueError('Input must be hexadecimal digits only')
+ # store as lower case digits
+ return super().__new__(cls, s.lower())
+
+ def __eq__(self, other: str) -> bool:
+ # make sure comparison is done case-insensitive
+ return str(self) == other.lower()
+
+ def __getitem__(self, val) -> 'hexstr':
+ # make sure slicing a hexstr will return a hexstr
+ return hexstr(super().__getitem__(val))
+
+ def to_bytes(self) -> bytes:
+ """return hex-string converted to bytes"""
+ s = str(self)
+ if len(s) & 1:
+ raise ValueError('Cannot convert hex string with odd number of
digits')
+ return h2b(s)
+
+ @classmethod
+ def from_bytes(cls, bt: bytes) -> 'hexstr':
+ """instantiate hex-string from bytes"""
+ return cls(b2h(bt))
+
+# just to differentiate strings of hex nibbles from everything else; only used for
typing
+# hints. New code should typically use the 'class hexstr' type above to get the
benefit
+# of case-insensitive comparison.
Hexstr = NewType('Hexstr', str)
def h2b(s: Hexstr) -> bytearray:
@@ -35,9 +67,9 @@
return bytearray.fromhex(s)
-def b2h(b: bytearray) -> Hexstr:
+def b2h(b: bytearray) -> hexstr:
"""convert from a sequence of bytes to a string of hex
nibbles"""
- return ''.join(['%02x' % (x) for x in b])
+ return hexstr(''.join(['%02x' % (x) for x in b]))
def h2i(s: Hexstr) -> List[int]:
@@ -45,9 +77,9 @@
return [(int(x, 16) << 4)+int(y, 16) for x, y in zip(s[0::2], s[1::2])]
-def i2h(s: List[int]) -> Hexstr:
+def i2h(s: List[int]) -> hexstr:
"""convert from a list of integers to a string of hex
nibbles"""
- return ''.join(['%02x' % (x) for x in s])
+ return hexstr(''.join(['%02x' % (x) for x in s]))
def h2s(s: Hexstr) -> str:
@@ -56,7 +88,7 @@
if int(x + y, 16) != 0xff])
-def s2h(s: str) -> Hexstr:
+def s2h(s: str) -> hexstr:
"""convert from an ASCII string to a string of hex
nibbles"""
b = bytearray()
b.extend(map(ord, s))
@@ -68,9 +100,9 @@
return ''.join([chr(x) for x in s])
-def swap_nibbles(s: Hexstr) -> Hexstr:
+def swap_nibbles(s: Hexstr) -> hexstr:
"""swap the nibbles in a hex string"""
- return ''.join([x+y for x, y in zip(s[1::2], s[0::2])])
+ return hexstr(''.join([x+y for x, y in zip(s[1::2], s[0::2])]))
def rpad(s: str, l: int, c='f') -> str:
@@ -138,36 +170,6 @@
except:
return False
-class hexstr(str):
- """Class derived from 'str', represeting a string of
hexadecimal digits. It differs in that
- comparisons are case-insensitive, and it offers encoding-free conversion from hexstr
to bytes
- and vice-versa."""
- def __new__(cls, s: str):
- if not all(c in string.hexdigits for c in s):
- raise ValueError('Input must be hexadecimal digits only')
- # store as lower case digits
- return super().__new__(cls, s.lower())
-
- def __eq__(self, other: str) -> bool:
- # make sure comparison is done case-insensitive
- return str(self) == other.lower()
-
- def __getitem__(self, val) -> 'hexstr':
- # make sure slicing a hexstr will return a hexstr
- return hexstr(super().__getitem__(val))
-
- def to_bytes(self) -> bytes:
- """return hex-string converted to bytes"""
- s = str(self)
- if len(s) & 1:
- raise ValueError('Cannot convert hex string with odd number of
digits')
- return h2b(s)
-
- @classmethod
- def from_bytes(cls, bt: bytes) -> 'hexstr':
- """instantiate hex-string from bytes"""
- return cls(b2h(bt))
-
#########################################################################
# ARGPARSE HELPERS
#########################################################################
--
To view, visit
https://gerrit.osmocom.org/c/python/pyosmocom/+/38202?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: python/pyosmocom
Gerrit-Branch: master
Gerrit-Change-Id: I4c72c33baf6e4b3a39fb28d72ad66fbd3e957e95
Gerrit-Change-Number: 38202
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>