Home | History | Annotate | Download | only in misc
      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 # alias kept for backward compatibility
     11 safeEval = ast.literal_eval
     12 
     13 
     14 def readHex(content):
     15 	"""Convert a list of hex strings to binary data."""
     16 	return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, basestring)))
     17 
     18 
     19 def deHexStr(hexdata):
     20 	"""Convert a hex string to binary data."""
     21 	hexdata = strjoin(hexdata.split())
     22 	if len(hexdata) % 2:
     23 		hexdata = hexdata + "0"
     24 	data = []
     25 	for i in range(0, len(hexdata), 2):
     26 		data.append(bytechr(int(hexdata[i:i+2], 16)))
     27 	return bytesjoin(data)
     28 
     29 
     30 def hexStr(data):
     31 	"""Convert binary data to a hex string."""
     32 	h = string.hexdigits
     33 	r = ''
     34 	for c in data:
     35 		i = byteord(c)
     36 		r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
     37 	return r
     38 
     39 
     40 def num2binary(l, bits=32):
     41 	items = []
     42 	binary = ""
     43 	for i in range(bits):
     44 		if l & 0x1:
     45 			binary = "1" + binary
     46 		else:
     47 			binary = "0" + binary
     48 		l = l >> 1
     49 		if not ((i+1) % 8):
     50 			items.append(binary)
     51 			binary = ""
     52 	if binary:
     53 		items.append(binary)
     54 	items.reverse()
     55 	assert l in (0, -1), "number doesn't fit in number of bits"
     56 	return ' '.join(items)
     57 
     58 
     59 def binary2num(bin):
     60 	bin = strjoin(bin.split())
     61 	l = 0
     62 	for digit in bin:
     63 		l = l << 1
     64 		if digit != "0":
     65 			l = l | 0x1
     66 	return l
     67 
     68 
     69 def caselessSort(alist):
     70 	"""Return a sorted copy of a list. If there are only strings
     71 	in the list, it will not consider case.
     72 	"""
     73 
     74 	try:
     75 		return sorted(alist, key=lambda a: (a.lower(), a))
     76 	except TypeError:
     77 		return sorted(alist)
     78 
     79 
     80 def pad(data, size):
     81 	r""" Pad byte string 'data' with null bytes until its length is a
     82 	multiple of 'size'.
     83 
     84 	>>> len(pad(b'abcd', 4))
     85 	4
     86 	>>> len(pad(b'abcde', 2))
     87 	6
     88 	>>> len(pad(b'abcde', 4))
     89 	8
     90 	>>> pad(b'abcdef', 4) == b'abcdef\x00\x00'
     91 	True
     92 	"""
     93 	data = tobytes(data)
     94 	if size > 1:
     95 		remainder = len(data) % size
     96 		if remainder:
     97 			data += b"\0" * (size - remainder)
     98 	return data
     99 
    100 
    101 if __name__ == "__main__":
    102 	import doctest, sys
    103 	sys.exit(doctest.testmod().failed)
    104