diff options
author | Chris Liechti <cliechti@gmx.net> | 2015-08-25 00:55:51 +0200 |
---|---|---|
committer | Chris Liechti <cliechti@gmx.net> | 2015-08-25 00:55:51 +0200 |
commit | c0c660a3297a5babb03a01b6fca89f6348b1bd36 (patch) | |
tree | 097f464e381b1add32d884637e960c0acb5f369d | |
parent | 9a72085e2ef8c50404f6d1643efcb9b0fba680ec (diff) | |
download | pyserial-git-c0c660a3297a5babb03a01b6fca89f6348b1bd36.tar.gz |
miniterm: add "hexlify" codec
the hexlify codec can send and receive hex encoded data and converts bytes to strings (unlike the built-in hex code)
try it with --encoding hexlify
-rw-r--r-- | serial/tools/hexlify_codec.py | 82 | ||||
-rw-r--r-- | serial/tools/miniterm.py | 6 |
2 files changed, 88 insertions, 0 deletions
diff --git a/serial/tools/hexlify_codec.py b/serial/tools/hexlify_codec.py new file mode 100644 index 0000000..f3ba04f --- /dev/null +++ b/serial/tools/hexlify_codec.py @@ -0,0 +1,82 @@ +"""\ +Python 'hex' Codec - 2-digit hex with spaces content transfer encoding. +""" + +import codecs +import serial + +HEXDIGITS = '0123456789ABCDEF' + +### Codec APIs + +def hex_encode(input, errors='strict'): + return (serial.to_bytes([int(h, 16) for h in input.split()]), len(input)) + +def hex_decode(input, errors='strict'): + return (''.join('{:02X} '.format(b) for b in input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return serial.to_bytes([int(h, 16) for h in input.split()]) + def decode(self, input, errors='strict'): + return ''.join('{:02X} '.format(b) for b in input) + +class IncrementalEncoder(codecs.IncrementalEncoder): + + def __init__(self, errors='strict'): + self.errors = errors + self.state = 0 + + def reset(self): + self.state = 0 + + def getstate(self): + return self.state + + def setstate(self, state): + self.state = state + + def encode(self, input, final=False): + state = self.state + encoded = [] + for c in input.upper(): + if c in HEXDIGITS: + z = HEXDIGITS.index(c) + if state: + encoded.append(z + (state & 0xf0)) + state = 0 + else: + state = 0x100 + (z << 4) + elif c == ' ': # allow spaces to separate values + if state and self.errors == 'strict': + raise UnicodeError('odd number of hex digits') + state = 0 + else: + if self.errors == 'strict': + raise UnicodeError('non-hex digit found: %r' % c) + self.state = state + return serial.to_bytes(encoded) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return ''.join('{:02X} '.format(b) for b in input) + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hexlify', + encode=hex_encode, + decode=hex_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=True, + ) diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py index cb60a2b..e56e4cc 100644 --- a/serial/tools/miniterm.py +++ b/serial/tools/miniterm.py @@ -20,6 +20,9 @@ except NameError: raw_input = input # in python3 it's "raw" unichr = chr +from . import hexlify_codec +codecs.register(lambda c: hexlify_codec.getregentry() if c == 'hexlify' else None) + def key_description(character): """generate a readable description for a key""" @@ -198,6 +201,7 @@ class NoControls(NoTerminal): class Printable(Transform): """Show decimal code for all non-ASCII characters and replace most control codes""" + def rx(self, text): r = [] for t in text: @@ -215,6 +219,7 @@ class Printable(Transform): class Colorize(Transform): """Apply different colors for received and echo""" + def __init__(self): # XXX make it configurable, use colorama? self.input_color = '\x1b[37m' @@ -229,6 +234,7 @@ class Colorize(Transform): class DebugIO(Transform): """Print what is sent and received""" + def rx(self, text): sys.stderr.write(' [RX:{}] '.format(repr(text))) sys.stderr.flush() |