--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/python-2.5.2/win32/Lib/quopri.py Fri Apr 03 17:19:34 2009 +0100
@@ -0,0 +1,237 @@
+#! /usr/bin/env python
+
+"""Conversions to/from quoted-printable transport encoding as per RFC 1521."""
+
+# (Dec 1991 version).
+
+__all__ = ["encode", "decode", "encodestring", "decodestring"]
+
+ESCAPE = '='
+MAXLINESIZE = 76
+HEX = '0123456789ABCDEF'
+EMPTYSTRING = ''
+
+try:
+ from binascii import a2b_qp, b2a_qp
+except ImportError:
+ a2b_qp = None
+ b2a_qp = None
+
+
+def needsquoting(c, quotetabs, header):
+ """Decide whether a particular character needs to be quoted.
+
+ The 'quotetabs' flag indicates whether embedded tabs and spaces should be
+ quoted. Note that line-ending tabs and spaces are always encoded, as per
+ RFC 1521.
+ """
+ if c in ' \t':
+ return quotetabs
+ # if header, we have to escape _ because _ is used to escape space
+ if c == '_':
+ return header
+ return c == ESCAPE or not (' ' <= c <= '~')
+
+def quote(c):
+ """Quote a single character."""
+ i = ord(c)
+ return ESCAPE + HEX[i//16] + HEX[i%16]
+
+
+
+def encode(input, output, quotetabs, header = 0):
+ """Read 'input', apply quoted-printable encoding, and write to 'output'.
+
+ 'input' and 'output' are files with readline() and write() methods.
+ The 'quotetabs' flag indicates whether embedded tabs and spaces should be
+ quoted. Note that line-ending tabs and spaces are always encoded, as per
+ RFC 1521.
+ The 'header' flag indicates whether we are encoding spaces as _ as per
+ RFC 1522.
+ """
+
+ if b2a_qp is not None:
+ data = input.read()
+ odata = b2a_qp(data, quotetabs = quotetabs, header = header)
+ output.write(odata)
+ return
+
+ def write(s, output=output, lineEnd='\n'):
+ # RFC 1521 requires that the line ending in a space or tab must have
+ # that trailing character encoded.
+ if s and s[-1:] in ' \t':
+ output.write(s[:-1] + quote(s[-1]) + lineEnd)
+ elif s == '.':
+ output.write(quote(s) + lineEnd)
+ else:
+ output.write(s + lineEnd)
+
+ prevline = None
+ while 1:
+ line = input.readline()
+ if not line:
+ break
+ outline = []
+ # Strip off any readline induced trailing newline
+ stripped = ''
+ if line[-1:] == '\n':
+ line = line[:-1]
+ stripped = '\n'
+ # Calculate the un-length-limited encoded line
+ for c in line:
+ if needsquoting(c, quotetabs, header):
+ c = quote(c)
+ if header and c == ' ':
+ outline.append('_')
+ else:
+ outline.append(c)
+ # First, write out the previous line
+ if prevline is not None:
+ write(prevline)
+ # Now see if we need any soft line breaks because of RFC-imposed
+ # length limitations. Then do the thisline->prevline dance.
+ thisline = EMPTYSTRING.join(outline)
+ while len(thisline) > MAXLINESIZE:
+ # Don't forget to include the soft line break `=' sign in the
+ # length calculation!
+ write(thisline[:MAXLINESIZE-1], lineEnd='=\n')
+ thisline = thisline[MAXLINESIZE-1:]
+ # Write out the current line
+ prevline = thisline
+ # Write out the last line, without a trailing newline
+ if prevline is not None:
+ write(prevline, lineEnd=stripped)
+
+def encodestring(s, quotetabs = 0, header = 0):
+ if b2a_qp is not None:
+ return b2a_qp(s, quotetabs = quotetabs, header = header)
+ from cStringIO import StringIO
+ infp = StringIO(s)
+ outfp = StringIO()
+ encode(infp, outfp, quotetabs, header)
+ return outfp.getvalue()
+
+
+
+def decode(input, output, header = 0):
+ """Read 'input', apply quoted-printable decoding, and write to 'output'.
+ 'input' and 'output' are files with readline() and write() methods.
+ If 'header' is true, decode underscore as space (per RFC 1522)."""
+
+ if a2b_qp is not None:
+ data = input.read()
+ odata = a2b_qp(data, header = header)
+ output.write(odata)
+ return
+
+ 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\r":
+ n = n-1
+ else:
+ partial = 1
+ while i < n:
+ c = line[i]
+ if c == '_' and header:
+ new = new + ' '; i = i+1
+ elif 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 decodestring(s, header = 0):
+ if a2b_qp is not None:
+ return a2b_qp(s, header = header)
+ from cStringIO import StringIO
+ infp = StringIO(s)
+ outfp = StringIO()
+ decode(infp, outfp, header = header)
+ return outfp.getvalue()
+
+
+
+# Other helper functions
+def ishex(c):
+ """Return true if the character 'c' is a hexadecimal digit."""
+ return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
+
+def unhex(s):
+ """Get the integer value of a hexadecimal number."""
+ 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 main():
+ import sys
+ import getopt
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'td')
+ except getopt.error, msg:
+ sys.stdout = sys.stderr
+ print msg
+ print "usage: quopri [-t | -d] [file] ..."
+ print "-t: quote tabs"
+ print "-d: decode; default encode"
+ sys.exit(2)
+ deco = 0
+ tabs = 0
+ for o, a in opts:
+ if o == '-t': tabs = 1
+ if o == '-d': deco = 1
+ if tabs and deco:
+ sys.stdout = sys.stderr
+ print "-t and -d are mutually exclusive"
+ sys.exit(2)
+ if not args: args = ['-']
+ sts = 0
+ for file in args:
+ if file == '-':
+ fp = sys.stdin
+ else:
+ try:
+ fp = open(file)
+ except IOError, msg:
+ sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
+ sts = 1
+ continue
+ if deco:
+ decode(fp, sys.stdout)
+ else:
+ encode(fp, sys.stdout, tabs)
+ if fp is not sys.stdin:
+ fp.close()
+ if sts:
+ sys.exit(sts)
+
+
+
+if __name__ == '__main__':
+ main()