1*e1fe3e4aSElliott Hughes"""fontTools.misc.textTools.py -- miscellaneous routines.""" 2*e1fe3e4aSElliott Hughes 3*e1fe3e4aSElliott Hughesimport ast 4*e1fe3e4aSElliott Hughesimport string 5*e1fe3e4aSElliott Hughes 6*e1fe3e4aSElliott Hughes 7*e1fe3e4aSElliott Hughes# alias kept for backward compatibility 8*e1fe3e4aSElliott HughessafeEval = ast.literal_eval 9*e1fe3e4aSElliott Hughes 10*e1fe3e4aSElliott Hughes 11*e1fe3e4aSElliott Hughesclass Tag(str): 12*e1fe3e4aSElliott Hughes @staticmethod 13*e1fe3e4aSElliott Hughes def transcode(blob): 14*e1fe3e4aSElliott Hughes if isinstance(blob, bytes): 15*e1fe3e4aSElliott Hughes blob = blob.decode("latin-1") 16*e1fe3e4aSElliott Hughes return blob 17*e1fe3e4aSElliott Hughes 18*e1fe3e4aSElliott Hughes def __new__(self, content): 19*e1fe3e4aSElliott Hughes return str.__new__(self, self.transcode(content)) 20*e1fe3e4aSElliott Hughes 21*e1fe3e4aSElliott Hughes def __ne__(self, other): 22*e1fe3e4aSElliott Hughes return not self.__eq__(other) 23*e1fe3e4aSElliott Hughes 24*e1fe3e4aSElliott Hughes def __eq__(self, other): 25*e1fe3e4aSElliott Hughes return str.__eq__(self, self.transcode(other)) 26*e1fe3e4aSElliott Hughes 27*e1fe3e4aSElliott Hughes def __hash__(self): 28*e1fe3e4aSElliott Hughes return str.__hash__(self) 29*e1fe3e4aSElliott Hughes 30*e1fe3e4aSElliott Hughes def tobytes(self): 31*e1fe3e4aSElliott Hughes return self.encode("latin-1") 32*e1fe3e4aSElliott Hughes 33*e1fe3e4aSElliott Hughes 34*e1fe3e4aSElliott Hughesdef readHex(content): 35*e1fe3e4aSElliott Hughes """Convert a list of hex strings to binary data.""" 36*e1fe3e4aSElliott Hughes return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str))) 37*e1fe3e4aSElliott Hughes 38*e1fe3e4aSElliott Hughes 39*e1fe3e4aSElliott Hughesdef deHexStr(hexdata): 40*e1fe3e4aSElliott Hughes """Convert a hex string to binary data.""" 41*e1fe3e4aSElliott Hughes hexdata = strjoin(hexdata.split()) 42*e1fe3e4aSElliott Hughes if len(hexdata) % 2: 43*e1fe3e4aSElliott Hughes hexdata = hexdata + "0" 44*e1fe3e4aSElliott Hughes data = [] 45*e1fe3e4aSElliott Hughes for i in range(0, len(hexdata), 2): 46*e1fe3e4aSElliott Hughes data.append(bytechr(int(hexdata[i : i + 2], 16))) 47*e1fe3e4aSElliott Hughes return bytesjoin(data) 48*e1fe3e4aSElliott Hughes 49*e1fe3e4aSElliott Hughes 50*e1fe3e4aSElliott Hughesdef hexStr(data): 51*e1fe3e4aSElliott Hughes """Convert binary data to a hex string.""" 52*e1fe3e4aSElliott Hughes h = string.hexdigits 53*e1fe3e4aSElliott Hughes r = "" 54*e1fe3e4aSElliott Hughes for c in data: 55*e1fe3e4aSElliott Hughes i = byteord(c) 56*e1fe3e4aSElliott Hughes r = r + h[(i >> 4) & 0xF] + h[i & 0xF] 57*e1fe3e4aSElliott Hughes return r 58*e1fe3e4aSElliott Hughes 59*e1fe3e4aSElliott Hughes 60*e1fe3e4aSElliott Hughesdef num2binary(l, bits=32): 61*e1fe3e4aSElliott Hughes items = [] 62*e1fe3e4aSElliott Hughes binary = "" 63*e1fe3e4aSElliott Hughes for i in range(bits): 64*e1fe3e4aSElliott Hughes if l & 0x1: 65*e1fe3e4aSElliott Hughes binary = "1" + binary 66*e1fe3e4aSElliott Hughes else: 67*e1fe3e4aSElliott Hughes binary = "0" + binary 68*e1fe3e4aSElliott Hughes l = l >> 1 69*e1fe3e4aSElliott Hughes if not ((i + 1) % 8): 70*e1fe3e4aSElliott Hughes items.append(binary) 71*e1fe3e4aSElliott Hughes binary = "" 72*e1fe3e4aSElliott Hughes if binary: 73*e1fe3e4aSElliott Hughes items.append(binary) 74*e1fe3e4aSElliott Hughes items.reverse() 75*e1fe3e4aSElliott Hughes assert l in (0, -1), "number doesn't fit in number of bits" 76*e1fe3e4aSElliott Hughes return " ".join(items) 77*e1fe3e4aSElliott Hughes 78*e1fe3e4aSElliott Hughes 79*e1fe3e4aSElliott Hughesdef binary2num(bin): 80*e1fe3e4aSElliott Hughes bin = strjoin(bin.split()) 81*e1fe3e4aSElliott Hughes l = 0 82*e1fe3e4aSElliott Hughes for digit in bin: 83*e1fe3e4aSElliott Hughes l = l << 1 84*e1fe3e4aSElliott Hughes if digit != "0": 85*e1fe3e4aSElliott Hughes l = l | 0x1 86*e1fe3e4aSElliott Hughes return l 87*e1fe3e4aSElliott Hughes 88*e1fe3e4aSElliott Hughes 89*e1fe3e4aSElliott Hughesdef caselessSort(alist): 90*e1fe3e4aSElliott Hughes """Return a sorted copy of a list. If there are only strings 91*e1fe3e4aSElliott Hughes in the list, it will not consider case. 92*e1fe3e4aSElliott Hughes """ 93*e1fe3e4aSElliott Hughes 94*e1fe3e4aSElliott Hughes try: 95*e1fe3e4aSElliott Hughes return sorted(alist, key=lambda a: (a.lower(), a)) 96*e1fe3e4aSElliott Hughes except TypeError: 97*e1fe3e4aSElliott Hughes return sorted(alist) 98*e1fe3e4aSElliott Hughes 99*e1fe3e4aSElliott Hughes 100*e1fe3e4aSElliott Hughesdef pad(data, size): 101*e1fe3e4aSElliott Hughes r"""Pad byte string 'data' with null bytes until its length is a 102*e1fe3e4aSElliott Hughes multiple of 'size'. 103*e1fe3e4aSElliott Hughes 104*e1fe3e4aSElliott Hughes >>> len(pad(b'abcd', 4)) 105*e1fe3e4aSElliott Hughes 4 106*e1fe3e4aSElliott Hughes >>> len(pad(b'abcde', 2)) 107*e1fe3e4aSElliott Hughes 6 108*e1fe3e4aSElliott Hughes >>> len(pad(b'abcde', 4)) 109*e1fe3e4aSElliott Hughes 8 110*e1fe3e4aSElliott Hughes >>> pad(b'abcdef', 4) == b'abcdef\x00\x00' 111*e1fe3e4aSElliott Hughes True 112*e1fe3e4aSElliott Hughes """ 113*e1fe3e4aSElliott Hughes data = tobytes(data) 114*e1fe3e4aSElliott Hughes if size > 1: 115*e1fe3e4aSElliott Hughes remainder = len(data) % size 116*e1fe3e4aSElliott Hughes if remainder: 117*e1fe3e4aSElliott Hughes data += b"\0" * (size - remainder) 118*e1fe3e4aSElliott Hughes return data 119*e1fe3e4aSElliott Hughes 120*e1fe3e4aSElliott Hughes 121*e1fe3e4aSElliott Hughesdef tostr(s, encoding="ascii", errors="strict"): 122*e1fe3e4aSElliott Hughes if not isinstance(s, str): 123*e1fe3e4aSElliott Hughes return s.decode(encoding, errors) 124*e1fe3e4aSElliott Hughes else: 125*e1fe3e4aSElliott Hughes return s 126*e1fe3e4aSElliott Hughes 127*e1fe3e4aSElliott Hughes 128*e1fe3e4aSElliott Hughesdef tobytes(s, encoding="ascii", errors="strict"): 129*e1fe3e4aSElliott Hughes if isinstance(s, str): 130*e1fe3e4aSElliott Hughes return s.encode(encoding, errors) 131*e1fe3e4aSElliott Hughes else: 132*e1fe3e4aSElliott Hughes return bytes(s) 133*e1fe3e4aSElliott Hughes 134*e1fe3e4aSElliott Hughes 135*e1fe3e4aSElliott Hughesdef bytechr(n): 136*e1fe3e4aSElliott Hughes return bytes([n]) 137*e1fe3e4aSElliott Hughes 138*e1fe3e4aSElliott Hughes 139*e1fe3e4aSElliott Hughesdef byteord(c): 140*e1fe3e4aSElliott Hughes return c if isinstance(c, int) else ord(c) 141*e1fe3e4aSElliott Hughes 142*e1fe3e4aSElliott Hughes 143*e1fe3e4aSElliott Hughesdef strjoin(iterable, joiner=""): 144*e1fe3e4aSElliott Hughes return tostr(joiner).join(iterable) 145*e1fe3e4aSElliott Hughes 146*e1fe3e4aSElliott Hughes 147*e1fe3e4aSElliott Hughesdef bytesjoin(iterable, joiner=b""): 148*e1fe3e4aSElliott Hughes return tobytes(joiner).join(tobytes(item) for item in iterable) 149*e1fe3e4aSElliott Hughes 150*e1fe3e4aSElliott Hughes 151*e1fe3e4aSElliott Hughesif __name__ == "__main__": 152*e1fe3e4aSElliott Hughes import doctest, sys 153*e1fe3e4aSElliott Hughes 154*e1fe3e4aSElliott Hughes sys.exit(doctest.testmod().failed) 155