diff options
author | Guido van Rossum <guido@python.org> | 1995-06-14 23:43:44 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1995-06-14 23:43:44 (GMT) |
commit | f1945466e8895453f2f19900b375f9f7cce99ee3 (patch) | |
tree | 1fdfbc660466618a5808ed2be446f5e29be37a94 /Lib/quopri.py | |
parent | 8ddd0addba41868ce114f866a521cbef441b10ee (diff) | |
download | cpython-f1945466e8895453f2f19900b375f9f7cce99ee3.zip cpython-f1945466e8895453f2f19900b375f9f7cce99ee3.tar.gz cpython-f1945466e8895453f2f19900b375f9f7cce99ee3.tar.bz2 |
two mime encoding schemes
Diffstat (limited to 'Lib/quopri.py')
-rwxr-xr-x | Lib/quopri.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/Lib/quopri.py b/Lib/quopri.py new file mode 100755 index 0000000..4c39228 --- /dev/null +++ b/Lib/quopri.py @@ -0,0 +1,101 @@ +# Conversions to/from quoted-printable transport encoding as per RFC-XXXX +# (Dec 1991 version). + +ESCAPE = '=' +MAXLINESIZE = 76 +HEX = '0123456789ABCDEF' + +def needsquoting(c, quotetabs): + if c == '\t': + return not quotetabs + return c == ESCAPE or not(' ' <= c <= '~') + +def quote(c): + if c == ESCAPE: + return ESCAPE * 2 + else: + i = ord(c) + return ESCAPE + HEX[i/16] + HEX[i%16] + +def encode(input, output, quotetabs): + while 1: + line = input.readline() + if not line: break + new = '' + last = line[-1:] + if last == '\n': line = line[:-1] + else: last = '' + prev = '' + for c in line: + if needsquoting(c, quotetabs): + c = quote(c) + if len(new) + len(c) >= MAXLINESIZE: + output.write(new + ESCAPE + '\n') + new = '' + new = new + c + prev = c + if prev in (' ', '\t'): + output.write(new + ESCAPE + '\n\n') + else: + output.write(new + '\n') + +def decode(input, output): + new = '' + while 1: + line = input.readline() + if not line: break + i, n = 0, len(line) + if n > 0 and line[n-1] == '\n': + partial = 0; n = n-1 + # Strip trailing whitespace + while n > 0 and line[n-1] in (' ', '\t'): + n = n-1 + else: + partial = 1 + while i < n: + c = line[i] + if c <> ESCAPE: + new = new + c; i = i+1 + elif i+1 == n and not partial: + partial = 1; break + elif i+1 < n and line[i+1] == ESCAPE: + new = new + ESCAPE; i = i+2 + elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]): + new = new + chr(unhex(line[i+1:i+3])); i = i+3 + else: # Bad escape sequence -- leave it in + new = new + c; i = i+1 + if not partial: + output.write(new + '\n') + new = '' + if new: + output.write(new) + +def ishex(c): + return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F' + +def unhex(s): + bits = 0 + for c in s: + if '0' <= c <= '9': + i = ord('0') + elif 'a' <= c <= 'f': + i = ord('a')-10 + elif 'A' <= c <= 'F': + i = ord('A')-10 + else: + break + bits = bits*16 + (ord(c) - i) + return bits + +def test(): + import sys + if sys.argv[1:]: + if sys.argv[1] == '-t': # Quote tabs + encode(sys.stdin, sys.stdout, 1) + else: + decode(sys.stdin, sys.stdout) + else: + encode(sys.stdin, sys.stdout, 0) + +if __name__ == '__main__': + main() |