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

91 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:33 +0000

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

2 

3 

4import ast 

5import string 

6 

7 

8# alias kept for backward compatibility 

9safeEval = ast.literal_eval 

10 

11 

12class Tag(str): 

13 @staticmethod 

14 def transcode(blob): 

15 if isinstance(blob, bytes): 

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

17 return blob 

18 

19 def __new__(self, content): 

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

21 

22 def __ne__(self, other): 

23 return not self.__eq__(other) 

24 

25 def __eq__(self, other): 

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

27 

28 def __hash__(self): 

29 return str.__hash__(self) 

30 

31 def tobytes(self): 

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

33 

34 

35def readHex(content): 

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

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

38 

39 

40def deHexStr(hexdata): 

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

42 hexdata = strjoin(hexdata.split()) 

43 if len(hexdata) % 2: 

44 hexdata = hexdata + "0" 

45 data = [] 

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

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

48 return bytesjoin(data) 

49 

50 

51def hexStr(data): 

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

53 h = string.hexdigits 

54 r = "" 

55 for c in data: 

56 i = byteord(c) 

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

58 return r 

59 

60 

61def num2binary(l, bits=32): 

62 items = [] 

63 binary = "" 

64 for i in range(bits): 

65 if l & 0x1: 

66 binary = "1" + binary 

67 else: 

68 binary = "0" + binary 

69 l = l >> 1 

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

71 items.append(binary) 

72 binary = "" 

73 if binary: 

74 items.append(binary) 

75 items.reverse() 

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

77 return " ".join(items) 

78 

79 

80def binary2num(bin): 

81 bin = strjoin(bin.split()) 

82 l = 0 

83 for digit in bin: 

84 l = l << 1 

85 if digit != "0": 

86 l = l | 0x1 

87 return l 

88 

89 

90def caselessSort(alist): 

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

92 in the list, it will not consider case. 

93 """ 

94 

95 try: 

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

97 except TypeError: 

98 return sorted(alist) 

99 

100 

101def pad(data, size): 

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

103 multiple of 'size'. 

104 

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

106 4 

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

108 6 

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

110 8 

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

112 True 

113 """ 

114 data = tobytes(data) 

115 if size > 1: 

116 remainder = len(data) % size 

117 if remainder: 

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

119 return data 

120 

121 

122def tostr(s, encoding="ascii", errors="strict"): 

123 if not isinstance(s, str): 

124 return s.decode(encoding, errors) 

125 else: 

126 return s 

127 

128 

129def tobytes(s, encoding="ascii", errors="strict"): 

130 if isinstance(s, str): 

131 return s.encode(encoding, errors) 

132 else: 

133 return bytes(s) 

134 

135 

136def bytechr(n): 

137 return bytes([n]) 

138 

139 

140def byteord(c): 

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

142 

143 

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

145 return tostr(joiner).join(iterable) 

146 

147 

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

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

150 

151 

152if __name__ == "__main__": 

153 import doctest, sys 

154 

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