Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/fontTools/misc/textTools.py: 43%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

93 statements  

1"""fontTools.misc.textTools.py -- miscellaneous routines.""" 

2 

3from __future__ import annotations 

4 

5import ast 

6import string 

7 

8 

9# alias kept for backward compatibility 

10safeEval = ast.literal_eval 

11 

12 

13class Tag(str): 

14 @staticmethod 

15 def transcode(blob): 

16 if isinstance(blob, bytes): 

17 blob = blob.decode("latin-1") 

18 return blob 

19 

20 def __new__(self, content): 

21 return str.__new__(self, self.transcode(content)) 

22 

23 def __ne__(self, other): 

24 return not self.__eq__(other) 

25 

26 def __eq__(self, other): 

27 return str.__eq__(self, self.transcode(other)) 

28 

29 def __hash__(self): 

30 return str.__hash__(self) 

31 

32 def tobytes(self): 

33 return self.encode("latin-1") 

34 

35 

36def readHex(content): 

37 """Convert a list of hex strings to binary data.""" 

38 return deHexStr(strjoin(chunk for chunk in content if isinstance(chunk, str))) 

39 

40 

41def deHexStr(hexdata): 

42 """Convert a hex string to binary data.""" 

43 hexdata = strjoin(hexdata.split()) 

44 if len(hexdata) % 2: 

45 hexdata = hexdata + "0" 

46 data = [] 

47 for i in range(0, len(hexdata), 2): 

48 data.append(bytechr(int(hexdata[i : i + 2], 16))) 

49 return bytesjoin(data) 

50 

51 

52def hexStr(data): 

53 """Convert binary data to a hex string.""" 

54 h = string.hexdigits 

55 r = "" 

56 for c in data: 

57 i = byteord(c) 

58 r = r + h[(i >> 4) & 0xF] + h[i & 0xF] 

59 return r 

60 

61 

62def num2binary(l, bits=32): 

63 items = [] 

64 binary = "" 

65 for i in range(bits): 

66 if l & 0x1: 

67 binary = "1" + binary 

68 else: 

69 binary = "0" + binary 

70 l = l >> 1 

71 if not ((i + 1) % 8): 

72 items.append(binary) 

73 binary = "" 

74 if binary: 

75 items.append(binary) 

76 items.reverse() 

77 assert l in (0, -1), "number doesn't fit in number of bits" 

78 return " ".join(items) 

79 

80 

81def binary2num(bin): 

82 bin = strjoin(bin.split()) 

83 l = 0 

84 for digit in bin: 

85 l = l << 1 

86 if digit != "0": 

87 l = l | 0x1 

88 return l 

89 

90 

91def caselessSort(alist): 

92 """Return a sorted copy of a list. If there are only strings 

93 in the list, it will not consider case. 

94 """ 

95 

96 try: 

97 return sorted(alist, key=lambda a: (a.lower(), a)) 

98 except TypeError: 

99 return sorted(alist) 

100 

101 

102def pad(data, size): 

103 r"""Pad byte string 'data' with null bytes until its length is a 

104 multiple of 'size'. 

105 

106 >>> len(pad(b'abcd', 4)) 

107 4 

108 >>> len(pad(b'abcde', 2)) 

109 6 

110 >>> len(pad(b'abcde', 4)) 

111 8 

112 >>> pad(b'abcdef', 4) == b'abcdef\x00\x00' 

113 True 

114 """ 

115 data = tobytes(data) 

116 if size > 1: 

117 remainder = len(data) % size 

118 if remainder: 

119 data += b"\0" * (size - remainder) 

120 return data 

121 

122 

123def tostr(s: str | bytes, encoding: str = "ascii", errors: str = "strict") -> str: 

124 if not isinstance(s, str): 

125 return s.decode(encoding, errors) 

126 else: 

127 return s 

128 

129 

130def tobytes(s: str | bytes, encoding: str = "ascii", errors: str = "strict") -> bytes: 

131 if isinstance(s, str): 

132 return s.encode(encoding, errors) 

133 else: 

134 return bytes(s) 

135 

136 

137def bytechr(n): 

138 return bytes([n]) 

139 

140 

141def byteord(c): 

142 return c if isinstance(c, int) else ord(c) 

143 

144 

145def strjoin(iterable, joiner=""): 

146 return tostr(joiner).join(iterable) 

147 

148 

149def bytesjoin(iterable, joiner=b""): 

150 return tobytes(joiner).join(tobytes(item) for item in iterable) 

151 

152 

153if __name__ == "__main__": 

154 import doctest, sys 

155 

156 sys.exit(doctest.testmod().failed)