blob: f3ba04f48dc866b8e7ea7b2ebd7edfcf09c02c0a [file] [log] [blame]
Chris Liechtic0c660a2015-08-25 00:55:51 +02001"""\
2Python 'hex' Codec - 2-digit hex with spaces content transfer encoding.
3"""
4
5import codecs
6import serial
7
8HEXDIGITS = '0123456789ABCDEF'
9
10### Codec APIs
11
12def hex_encode(input, errors='strict'):
13 return (serial.to_bytes([int(h, 16) for h in input.split()]), len(input))
14
15def hex_decode(input, errors='strict'):
16 return (''.join('{:02X} '.format(b) for b in input), len(input))
17
18class Codec(codecs.Codec):
19 def encode(self, input, errors='strict'):
20 return serial.to_bytes([int(h, 16) for h in input.split()])
21 def decode(self, input, errors='strict'):
22 return ''.join('{:02X} '.format(b) for b in input)
23
24class IncrementalEncoder(codecs.IncrementalEncoder):
25
26 def __init__(self, errors='strict'):
27 self.errors = errors
28 self.state = 0
29
30 def reset(self):
31 self.state = 0
32
33 def getstate(self):
34 return self.state
35
36 def setstate(self, state):
37 self.state = state
38
39 def encode(self, input, final=False):
40 state = self.state
41 encoded = []
42 for c in input.upper():
43 if c in HEXDIGITS:
44 z = HEXDIGITS.index(c)
45 if state:
46 encoded.append(z + (state & 0xf0))
47 state = 0
48 else:
49 state = 0x100 + (z << 4)
50 elif c == ' ': # allow spaces to separate values
51 if state and self.errors == 'strict':
52 raise UnicodeError('odd number of hex digits')
53 state = 0
54 else:
55 if self.errors == 'strict':
56 raise UnicodeError('non-hex digit found: %r' % c)
57 self.state = state
58 return serial.to_bytes(encoded)
59
60class IncrementalDecoder(codecs.IncrementalDecoder):
61 def decode(self, input, final=False):
62 return ''.join('{:02X} '.format(b) for b in input)
63
64class StreamWriter(Codec, codecs.StreamWriter):
65 pass
66
67class StreamReader(Codec, codecs.StreamReader):
68 pass
69
70### encodings module API
71
72def getregentry():
73 return codecs.CodecInfo(
74 name='hexlify',
75 encode=hex_encode,
76 decode=hex_decode,
77 incrementalencoder=IncrementalEncoder,
78 incrementaldecoder=IncrementalDecoder,
79 streamwriter=StreamWriter,
80 streamreader=StreamReader,
81 _is_text_encoding=True,
82 )