symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/quopri.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #! /usr/bin/env python
       
     2 
       
     3 """Conversions to/from quoted-printable transport encoding as per RFC 1521."""
       
     4 
       
     5 # (Dec 1991 version).
       
     6 
       
     7 __all__ = ["encode", "decode", "encodestring", "decodestring"]
       
     8 
       
     9 ESCAPE = '='
       
    10 MAXLINESIZE = 76
       
    11 HEX = '0123456789ABCDEF'
       
    12 EMPTYSTRING = ''
       
    13 
       
    14 try:
       
    15     from binascii import a2b_qp, b2a_qp
       
    16 except ImportError:
       
    17     a2b_qp = None
       
    18     b2a_qp = None
       
    19 
       
    20 
       
    21 def needsquoting(c, quotetabs, header):
       
    22     """Decide whether a particular character needs to be quoted.
       
    23 
       
    24     The 'quotetabs' flag indicates whether embedded tabs and spaces should be
       
    25     quoted.  Note that line-ending tabs and spaces are always encoded, as per
       
    26     RFC 1521.
       
    27     """
       
    28     if c in ' \t':
       
    29         return quotetabs
       
    30     # if header, we have to escape _ because _ is used to escape space
       
    31     if c == '_':
       
    32         return header
       
    33     return c == ESCAPE or not (' ' <= c <= '~')
       
    34 
       
    35 def quote(c):
       
    36     """Quote a single character."""
       
    37     i = ord(c)
       
    38     return ESCAPE + HEX[i//16] + HEX[i%16]
       
    39 
       
    40 
       
    41 
       
    42 def encode(input, output, quotetabs, header = 0):
       
    43     """Read 'input', apply quoted-printable encoding, and write to 'output'.
       
    44 
       
    45     'input' and 'output' are files with readline() and write() methods.
       
    46     The 'quotetabs' flag indicates whether embedded tabs and spaces should be
       
    47     quoted.  Note that line-ending tabs and spaces are always encoded, as per
       
    48     RFC 1521.
       
    49     The 'header' flag indicates whether we are encoding spaces as _ as per
       
    50     RFC 1522.
       
    51     """
       
    52 
       
    53     if b2a_qp is not None:
       
    54         data = input.read()
       
    55         odata = b2a_qp(data, quotetabs = quotetabs, header = header)
       
    56         output.write(odata)
       
    57         return
       
    58 
       
    59     def write(s, output=output, lineEnd='\n'):
       
    60         # RFC 1521 requires that the line ending in a space or tab must have
       
    61         # that trailing character encoded.
       
    62         if s and s[-1:] in ' \t':
       
    63             output.write(s[:-1] + quote(s[-1]) + lineEnd)
       
    64         elif s == '.':
       
    65             output.write(quote(s) + lineEnd)
       
    66         else:
       
    67             output.write(s + lineEnd)
       
    68 
       
    69     prevline = None
       
    70     while 1:
       
    71         line = input.readline()
       
    72         if not line:
       
    73             break
       
    74         outline = []
       
    75         # Strip off any readline induced trailing newline
       
    76         stripped = ''
       
    77         if line[-1:] == '\n':
       
    78             line = line[:-1]
       
    79             stripped = '\n'
       
    80         # Calculate the un-length-limited encoded line
       
    81         for c in line:
       
    82             if needsquoting(c, quotetabs, header):
       
    83                 c = quote(c)
       
    84             if header and c == ' ':
       
    85                 outline.append('_')
       
    86             else:
       
    87                 outline.append(c)
       
    88         # First, write out the previous line
       
    89         if prevline is not None:
       
    90             write(prevline)
       
    91         # Now see if we need any soft line breaks because of RFC-imposed
       
    92         # length limitations.  Then do the thisline->prevline dance.
       
    93         thisline = EMPTYSTRING.join(outline)
       
    94         while len(thisline) > MAXLINESIZE:
       
    95             # Don't forget to include the soft line break `=' sign in the
       
    96             # length calculation!
       
    97             write(thisline[:MAXLINESIZE-1], lineEnd='=\n')
       
    98             thisline = thisline[MAXLINESIZE-1:]
       
    99         # Write out the current line
       
   100         prevline = thisline
       
   101     # Write out the last line, without a trailing newline
       
   102     if prevline is not None:
       
   103         write(prevline, lineEnd=stripped)
       
   104 
       
   105 def encodestring(s, quotetabs = 0, header = 0):
       
   106     if b2a_qp is not None:
       
   107         return b2a_qp(s, quotetabs = quotetabs, header = header)
       
   108     from cStringIO import StringIO
       
   109     infp = StringIO(s)
       
   110     outfp = StringIO()
       
   111     encode(infp, outfp, quotetabs, header)
       
   112     return outfp.getvalue()
       
   113 
       
   114 
       
   115 
       
   116 def decode(input, output, header = 0):
       
   117     """Read 'input', apply quoted-printable decoding, and write to 'output'.
       
   118     'input' and 'output' are files with readline() and write() methods.
       
   119     If 'header' is true, decode underscore as space (per RFC 1522)."""
       
   120 
       
   121     if a2b_qp is not None:
       
   122         data = input.read()
       
   123         odata = a2b_qp(data, header = header)
       
   124         output.write(odata)
       
   125         return
       
   126 
       
   127     new = ''
       
   128     while 1:
       
   129         line = input.readline()
       
   130         if not line: break
       
   131         i, n = 0, len(line)
       
   132         if n > 0 and line[n-1] == '\n':
       
   133             partial = 0; n = n-1
       
   134             # Strip trailing whitespace
       
   135             while n > 0 and line[n-1] in " \t\r":
       
   136                 n = n-1
       
   137         else:
       
   138             partial = 1
       
   139         while i < n:
       
   140             c = line[i]
       
   141             if c == '_' and header:
       
   142                 new = new + ' '; i = i+1
       
   143             elif c != ESCAPE:
       
   144                 new = new + c; i = i+1
       
   145             elif i+1 == n and not partial:
       
   146                 partial = 1; break
       
   147             elif i+1 < n and line[i+1] == ESCAPE:
       
   148                 new = new + ESCAPE; i = i+2
       
   149             elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]):
       
   150                 new = new + chr(unhex(line[i+1:i+3])); i = i+3
       
   151             else: # Bad escape sequence -- leave it in
       
   152                 new = new + c; i = i+1
       
   153         if not partial:
       
   154             output.write(new + '\n')
       
   155             new = ''
       
   156     if new:
       
   157         output.write(new)
       
   158 
       
   159 def decodestring(s, header = 0):
       
   160     if a2b_qp is not None:
       
   161         return a2b_qp(s, header = header)
       
   162     from cStringIO import StringIO
       
   163     infp = StringIO(s)
       
   164     outfp = StringIO()
       
   165     decode(infp, outfp, header = header)
       
   166     return outfp.getvalue()
       
   167 
       
   168 
       
   169 
       
   170 # Other helper functions
       
   171 def ishex(c):
       
   172     """Return true if the character 'c' is a hexadecimal digit."""
       
   173     return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
       
   174 
       
   175 def unhex(s):
       
   176     """Get the integer value of a hexadecimal number."""
       
   177     bits = 0
       
   178     for c in s:
       
   179         if '0' <= c <= '9':
       
   180             i = ord('0')
       
   181         elif 'a' <= c <= 'f':
       
   182             i = ord('a')-10
       
   183         elif 'A' <= c <= 'F':
       
   184             i = ord('A')-10
       
   185         else:
       
   186             break
       
   187         bits = bits*16 + (ord(c) - i)
       
   188     return bits
       
   189 
       
   190 
       
   191 
       
   192 def main():
       
   193     import sys
       
   194     import getopt
       
   195     try:
       
   196         opts, args = getopt.getopt(sys.argv[1:], 'td')
       
   197     except getopt.error, msg:
       
   198         sys.stdout = sys.stderr
       
   199         print msg
       
   200         print "usage: quopri [-t | -d] [file] ..."
       
   201         print "-t: quote tabs"
       
   202         print "-d: decode; default encode"
       
   203         sys.exit(2)
       
   204     deco = 0
       
   205     tabs = 0
       
   206     for o, a in opts:
       
   207         if o == '-t': tabs = 1
       
   208         if o == '-d': deco = 1
       
   209     if tabs and deco:
       
   210         sys.stdout = sys.stderr
       
   211         print "-t and -d are mutually exclusive"
       
   212         sys.exit(2)
       
   213     if not args: args = ['-']
       
   214     sts = 0
       
   215     for file in args:
       
   216         if file == '-':
       
   217             fp = sys.stdin
       
   218         else:
       
   219             try:
       
   220                 fp = open(file)
       
   221             except IOError, msg:
       
   222                 sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
       
   223                 sts = 1
       
   224                 continue
       
   225         if deco:
       
   226             decode(fp, sys.stdout)
       
   227         else:
       
   228             encode(fp, sys.stdout, tabs)
       
   229         if fp is not sys.stdin:
       
   230             fp.close()
       
   231     if sts:
       
   232         sys.exit(sts)
       
   233 
       
   234 
       
   235 
       
   236 if __name__ == '__main__':
       
   237     main()