You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.0 KiB
103 lines
2.0 KiB
4 months ago
|
"""fontTools.misc.textTools.py -- miscellaneous routines."""
|
||
|
|
||
|
|
||
|
from fontTools.misc.py23 import bytechr, byteord, bytesjoin, strjoin, tobytes
|
||
|
import ast
|
||
|
import string
|
||
|
|
||
|
|
||
|
# alias kept for backward compatibility
|
||
|
safeEval = ast.literal_eval
|
||
|
|
||
|
|
||
|
def readHex(content):
|
||
|
"""Convert a list of hex strings to binary data."""
|
||
|
return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str)))
|
||
|
|
||
|
|
||
|
def deHexStr(hexdata):
|
||
|
"""Convert a hex string to binary data."""
|
||
|
hexdata = strjoin(hexdata.split())
|
||
|
if len(hexdata) % 2:
|
||
|
hexdata = hexdata + "0"
|
||
|
data = []
|
||
|
for i in range(0, len(hexdata), 2):
|
||
|
data.append(bytechr(int(hexdata[i:i+2], 16)))
|
||
|
return bytesjoin(data)
|
||
|
|
||
|
|
||
|
def hexStr(data):
|
||
|
"""Convert binary data to a hex string."""
|
||
|
h = string.hexdigits
|
||
|
r = ''
|
||
|
for c in data:
|
||
|
i = byteord(c)
|
||
|
r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
|
||
|
return r
|
||
|
|
||
|
|
||
|
def num2binary(l, bits=32):
|
||
|
items = []
|
||
|
binary = ""
|
||
|
for i in range(bits):
|
||
|
if l & 0x1:
|
||
|
binary = "1" + binary
|
||
|
else:
|
||
|
binary = "0" + binary
|
||
|
l = l >> 1
|
||
|
if not ((i+1) % 8):
|
||
|
items.append(binary)
|
||
|
binary = ""
|
||
|
if binary:
|
||
|
items.append(binary)
|
||
|
items.reverse()
|
||
|
assert l in (0, -1), "number doesn't fit in number of bits"
|
||
|
return ' '.join(items)
|
||
|
|
||
|
|
||
|
def binary2num(bin):
|
||
|
bin = strjoin(bin.split())
|
||
|
l = 0
|
||
|
for digit in bin:
|
||
|
l = l << 1
|
||
|
if digit != "0":
|
||
|
l = l | 0x1
|
||
|
return l
|
||
|
|
||
|
|
||
|
def caselessSort(alist):
|
||
|
"""Return a sorted copy of a list. If there are only strings
|
||
|
in the list, it will not consider case.
|
||
|
"""
|
||
|
|
||
|
try:
|
||
|
return sorted(alist, key=lambda a: (a.lower(), a))
|
||
|
except TypeError:
|
||
|
return sorted(alist)
|
||
|
|
||
|
|
||
|
def pad(data, size):
|
||
|
r""" Pad byte string 'data' with null bytes until its length is a
|
||
|
multiple of 'size'.
|
||
|
|
||
|
>>> len(pad(b'abcd', 4))
|
||
|
4
|
||
|
>>> len(pad(b'abcde', 2))
|
||
|
6
|
||
|
>>> len(pad(b'abcde', 4))
|
||
|
8
|
||
|
>>> pad(b'abcdef', 4) == b'abcdef\x00\x00'
|
||
|
True
|
||
|
"""
|
||
|
data = tobytes(data)
|
||
|
if size > 1:
|
||
|
remainder = len(data) % size
|
||
|
if remainder:
|
||
|
data += b"\0" * (size - remainder)
|
||
|
return data
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
import doctest, sys
|
||
|
sys.exit(doctest.testmod().failed)
|