3 # Conversions to/from quoted-printable transport encoding as per RFC-1521
8 HEX
= '0123456789ABCDEF'
10 def needsquoting(c
, quotetabs
):
13 return c
== ESCAPE
or not(' ' <= c
<= '~')
20 return ESCAPE
+ HEX
[i
/16] + HEX
[i
%16]
22 def encode(input, output
, quotetabs
):
24 line
= input.readline()
28 if last
== '\n': line
= line
[:-1]
32 if needsquoting(c
, quotetabs
):
34 if len(new
) + len(c
) >= MAXLINESIZE
:
35 output
.write(new
+ ESCAPE
+ '\n')
39 if prev
in (' ', '\t'):
40 output
.write(new
+ ESCAPE
+ '\n\n')
42 output
.write(new
+ '\n')
44 def decode(input, output
):
47 line
= input.readline()
50 if n
> 0 and line
[n
-1] == '\n':
52 # Strip trailing whitespace
53 while n
> 0 and line
[n
-1] in (' ', '\t'):
60 new
= new
+ c
; i
= i
+1
61 elif i
+1 == n
and not partial
:
63 elif i
+1 < n
and line
[i
+1] == ESCAPE
:
64 new
= new
+ ESCAPE
; i
= i
+2
65 elif i
+2 < n
and ishex(line
[i
+1]) and ishex(line
[i
+2]):
66 new
= new
+ chr(unhex(line
[i
+1:i
+3])); i
= i
+3
67 else: # Bad escape sequence -- leave it in
68 new
= new
+ c
; i
= i
+1
70 output
.write(new
+ '\n')
76 return '0' <= c
<= '9' or 'a' <= c
<= 'f' or 'A' <= c
<= 'F'
89 bits
= bits
*16 + (ord(c
) - i
)
96 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'td')
97 except getopt
.error
, msg
:
98 sys
.stdout
= sys
.stderr
100 print "usage: quopri [-t | -d] [file] ..."
101 print "-t: quote tabs"
102 print "-d: decode; default encode"
107 if o
== '-t': tabs
= 1
108 if o
== '-d': deco
= 1
110 sys
.stdout
= sys
.stderr
111 print "-t and -d are mutually exclusive"
113 if not args
: args
= ['-']
122 sys
.stderr
.write("%s: can't open (%s)\n" % (file, msg
))
126 decode(fp
, sys
.stdout
)
128 encode(fp
, sys
.stdout
, tabs
)
129 if fp
is not sys
.stdin
:
134 if __name__
== '__main__':