~vil/pydev/upstream

« back to all changes in this revision

Viewing changes to org.python.pydev.jython/Lib/quopri.py

  • Committer: Vladimír Lapáček
  • Date: 2006-08-30 18:38:44 UTC
  • Revision ID: vladimir.lapacek@gmail.com-20060830183844-f4d82c1239a7770a
Initial import of upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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"]
 
8
 
 
9
ESCAPE = '='
 
10
MAXLINESIZE = 76
 
11
HEX = '0123456789ABCDEF'
 
12
 
 
13
def needsquoting(c, quotetabs):
 
14
    """Decide whether a particular character needs to be quoted.
 
15
 
 
16
    The 'quotetabs' flag indicates whether tabs should be quoted."""
 
17
    if c == '\t':
 
18
        return not quotetabs
 
19
    return c == ESCAPE or not(' ' <= c <= '~')
 
20
 
 
21
def quote(c):
 
22
    """Quote a single character."""
 
23
    i = ord(c)
 
24
    return ESCAPE + HEX[i/16] + HEX[i%16]
 
25
 
 
26
def encode(input, output, quotetabs):
 
27
    """Read 'input', apply quoted-printable encoding, and write to 'output'.
 
28
 
 
29
    'input' and 'output' are files with readline() and write() methods.
 
30
    The 'quotetabs' flag indicates whether tabs should be quoted.
 
31
        """
 
32
    while 1:
 
33
        line = input.readline()
 
34
        if not line:
 
35
            break
 
36
        new = ''
 
37
        last = line[-1:]
 
38
        if last == '\n':
 
39
            line = line[:-1]
 
40
        else:
 
41
            last = ''
 
42
        prev = ''
 
43
        for c in line:
 
44
            if needsquoting(c, quotetabs):
 
45
                c = quote(c)
 
46
            if len(new) + len(c) >= MAXLINESIZE:
 
47
                output.write(new + ESCAPE + '\n')
 
48
                new = ''
 
49
            new = new + c
 
50
            prev = c
 
51
        if prev in (' ', '\t'):
 
52
            output.write(new + ESCAPE + '\n\n')
 
53
        else:
 
54
            output.write(new + '\n')
 
55
 
 
56
def decode(input, output):
 
57
    """Read 'input', apply quoted-printable decoding, and write to 'output'.
 
58
 
 
59
    'input' and 'output' are files with readline() and write() methods."""
 
60
    new = ''
 
61
    while 1:
 
62
        line = input.readline()
 
63
        if not line: break
 
64
        i, n = 0, len(line)
 
65
        if n > 0 and line[n-1] == '\n':
 
66
            partial = 0; n = n-1
 
67
            # Strip trailing whitespace
 
68
            while n > 0 and line[n-1] in " \t\r":
 
69
                n = n-1
 
70
        else:
 
71
            partial = 1
 
72
        while i < n:
 
73
            c = line[i]
 
74
            if c != ESCAPE:
 
75
                new = new + c; i = i+1
 
76
            elif i+1 == n and not partial:
 
77
                partial = 1; break
 
78
            elif i+1 < n and line[i+1] == ESCAPE:
 
79
                new = new + ESCAPE; i = i+2
 
80
            elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]):
 
81
                new = new + chr(unhex(line[i+1:i+3])); i = i+3
 
82
            else: # Bad escape sequence -- leave it in
 
83
                new = new + c; i = i+1
 
84
        if not partial:
 
85
            output.write(new + '\n')
 
86
            new = ''
 
87
    if new:
 
88
        output.write(new)
 
89
 
 
90
def ishex(c):
 
91
    """Return true if the character 'c' is a hexadecimal digit."""
 
92
    return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
 
93
 
 
94
def unhex(s):
 
95
    """Get the integer value of a hexadecimal number."""
 
96
    bits = 0
 
97
    for c in s:
 
98
        if '0' <= c <= '9':
 
99
            i = ord('0')
 
100
        elif 'a' <= c <= 'f':
 
101
            i = ord('a')-10
 
102
        elif 'A' <= c <= 'F':
 
103
            i = ord('A')-10
 
104
        else:
 
105
            break
 
106
        bits = bits*16 + (ord(c) - i)
 
107
    return bits
 
108
 
 
109
def test():
 
110
    import sys
 
111
    import getopt
 
112
    try:
 
113
        opts, args = getopt.getopt(sys.argv[1:], 'td')
 
114
    except getopt.error, msg:
 
115
        sys.stdout = sys.stderr
 
116
        print msg
 
117
        print "usage: quopri [-t | -d] [file] ..."
 
118
        print "-t: quote tabs"
 
119
        print "-d: decode; default encode"
 
120
        sys.exit(2)
 
121
    deco = 0
 
122
    tabs = 0
 
123
    for o, a in opts:
 
124
        if o == '-t': tabs = 1
 
125
        if o == '-d': deco = 1
 
126
    if tabs and deco:
 
127
        sys.stdout = sys.stderr
 
128
        print "-t and -d are mutually exclusive"
 
129
        sys.exit(2)
 
130
    if not args: args = ['-']
 
131
    sts = 0
 
132
    for file in args:
 
133
        if file == '-':
 
134
            fp = sys.stdin
 
135
        else:
 
136
            try:
 
137
                fp = open(file)
 
138
            except IOError, msg:
 
139
                sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
 
140
                sts = 1
 
141
                continue
 
142
        if deco:
 
143
            decode(fp, sys.stdout)
 
144
        else:
 
145
            encode(fp, sys.stdout, tabs)
 
146
        if fp is not sys.stdin:
 
147
            fp.close()
 
148
    if sts:
 
149
        sys.exit(sts)
 
150
 
 
151
if __name__ == '__main__':
 
152
    test()