1 """fontTools.misc.textTools.py -- miscellaneous routines.""" 2 3 4 from __future__ import print_function, division, absolute_import 5 from fontTools.misc.py23 import * 6 import ast 7 import string 8 9 10 safeEval = ast.literal_eval 11 12 def readHex(content): 13 """Convert a list of hex strings to binary data.""" 14 return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, basestring))) 15 16 def deHexStr(hexdata): 17 """Convert a hex string to binary data.""" 18 hexdata = strjoin(hexdata.split()) 19 if len(hexdata) % 2: 20 hexdata = hexdata + "0" 21 data = [] 22 for i in range(0, len(hexdata), 2): 23 data.append(bytechr(int(hexdata[i:i+2], 16))) 24 return bytesjoin(data) 25 26 27 def hexStr(data): 28 """Convert binary data to a hex string.""" 29 h = string.hexdigits 30 r = '' 31 for c in data: 32 i = byteord(c) 33 r = r + h[(i >> 4) & 0xF] + h[i & 0xF] 34 return r 35 36 37 def num2binary(l, bits=32): 38 items = [] 39 binary = "" 40 for i in range(bits): 41 if l & 0x1: 42 binary = "1" + binary 43 else: 44 binary = "0" + binary 45 l = l >> 1 46 if not ((i+1) % 8): 47 items.append(binary) 48 binary = "" 49 if binary: 50 items.append(binary) 51 items.reverse() 52 assert l in (0, -1), "number doesn't fit in number of bits" 53 return ' '.join(items) 54 55 56 def binary2num(bin): 57 bin = strjoin(bin.split()) 58 l = 0 59 for digit in bin: 60 l = l << 1 61 if digit != "0": 62 l = l | 0x1 63 return l 64 65 66 def caselessSort(alist): 67 """Return a sorted copy of a list. If there are only strings 68 in the list, it will not consider case. 69 """ 70 71 try: 72 return sorted(alist, key=lambda a: (a.lower(), a)) 73 except TypeError: 74 return sorted(alist) 75 76