Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/fontTools/misc/textTools.py: 42%
91 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:33 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:33 +0000
1"""fontTools.misc.textTools.py -- miscellaneous routines."""
4import ast
5import string
8# alias kept for backward compatibility
9safeEval = ast.literal_eval
12class Tag(str):
13 @staticmethod
14 def transcode(blob):
15 if isinstance(blob, bytes):
16 blob = blob.decode("latin-1")
17 return blob
19 def __new__(self, content):
20 return str.__new__(self, self.transcode(content))
22 def __ne__(self, other):
23 return not self.__eq__(other)
25 def __eq__(self, other):
26 return str.__eq__(self, self.transcode(other))
28 def __hash__(self):
29 return str.__hash__(self)
31 def tobytes(self):
32 return self.encode("latin-1")
35def readHex(content):
36 """Convert a list of hex strings to binary data."""
37 return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str)))
40def deHexStr(hexdata):
41 """Convert a hex string to binary data."""
42 hexdata = strjoin(hexdata.split())
43 if len(hexdata) % 2:
44 hexdata = hexdata + "0"
45 data = []
46 for i in range(0, len(hexdata), 2):
47 data.append(bytechr(int(hexdata[i : i + 2], 16)))
48 return bytesjoin(data)
51def hexStr(data):
52 """Convert binary data to a hex string."""
53 h = string.hexdigits
54 r = ""
55 for c in data:
56 i = byteord(c)
57 r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
58 return r
61def num2binary(l, bits=32):
62 items = []
63 binary = ""
64 for i in range(bits):
65 if l & 0x1:
66 binary = "1" + binary
67 else:
68 binary = "0" + binary
69 l = l >> 1
70 if not ((i + 1) % 8):
71 items.append(binary)
72 binary = ""
73 if binary:
74 items.append(binary)
75 items.reverse()
76 assert l in (0, -1), "number doesn't fit in number of bits"
77 return " ".join(items)
80def binary2num(bin):
81 bin = strjoin(bin.split())
82 l = 0
83 for digit in bin:
84 l = l << 1
85 if digit != "0":
86 l = l | 0x1
87 return l
90def caselessSort(alist):
91 """Return a sorted copy of a list. If there are only strings
92 in the list, it will not consider case.
93 """
95 try:
96 return sorted(alist, key=lambda a: (a.lower(), a))
97 except TypeError:
98 return sorted(alist)
101def pad(data, size):
102 r"""Pad byte string 'data' with null bytes until its length is a
103 multiple of 'size'.
105 >>> len(pad(b'abcd', 4))
106 4
107 >>> len(pad(b'abcde', 2))
108 6
109 >>> len(pad(b'abcde', 4))
110 8
111 >>> pad(b'abcdef', 4) == b'abcdef\x00\x00'
112 True
113 """
114 data = tobytes(data)
115 if size > 1:
116 remainder = len(data) % size
117 if remainder:
118 data += b"\0" * (size - remainder)
119 return data
122def tostr(s, encoding="ascii", errors="strict"):
123 if not isinstance(s, str):
124 return s.decode(encoding, errors)
125 else:
126 return s
129def tobytes(s, encoding="ascii", errors="strict"):
130 if isinstance(s, str):
131 return s.encode(encoding, errors)
132 else:
133 return bytes(s)
136def bytechr(n):
137 return bytes([n])
140def byteord(c):
141 return c if isinstance(c, int) else ord(c)
144def strjoin(iterable, joiner=""):
145 return tostr(joiner).join(iterable)
148def bytesjoin(iterable, joiner=b""):
149 return tobytes(joiner).join(tobytes(item) for item in iterable)
152if __name__ == "__main__":
153 import doctest, sys
155 sys.exit(doctest.testmod().failed)