Read 'input', apply quoted-printable decoding, and write to 'output'. 'input' and 'output' are binary file objects. If 'header' is true, decode underscore as space (per RFC 1522).
(input, output, header=False)
| 110 | |
| 111 | |
| 112 | def decode(input, output, header=False): |
| 113 | """Read 'input', apply quoted-printable decoding, and write to 'output'. |
| 114 | 'input' and 'output' are binary file objects. |
| 115 | If 'header' is true, decode underscore as space (per RFC 1522).""" |
| 116 | |
| 117 | if a2b_qp is not None: |
| 118 | data = input.read() |
| 119 | odata = a2b_qp(data, header=header) |
| 120 | output.write(odata) |
| 121 | return |
| 122 | |
| 123 | new = b'' |
| 124 | while line := input.readline(): |
| 125 | i, n = 0, len(line) |
| 126 | if n > 0 and line[n-1:n] == b'\n': |
| 127 | partial = 0; n = n-1 |
| 128 | # Strip trailing whitespace |
| 129 | while n > 0 and line[n-1:n] in b" \t\r": |
| 130 | n = n-1 |
| 131 | else: |
| 132 | partial = 1 |
| 133 | while i < n: |
| 134 | c = line[i:i+1] |
| 135 | if c == b'_' and header: |
| 136 | new = new + b' '; i = i+1 |
| 137 | elif c != ESCAPE: |
| 138 | new = new + c; i = i+1 |
| 139 | elif i+1 == n and not partial: |
| 140 | partial = 1; break |
| 141 | elif i+1 < n and line[i+1:i+2] == ESCAPE: |
| 142 | new = new + ESCAPE; i = i+2 |
| 143 | elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]): |
| 144 | new = new + bytes((unhex(line[i+1:i+3]),)); i = i+3 |
| 145 | else: # Bad escape sequence -- leave it in |
| 146 | new = new + c; i = i+1 |
| 147 | if not partial: |
| 148 | output.write(new + b'\n') |
| 149 | new = b'' |
| 150 | if new: |
| 151 | output.write(new) |
| 152 | |
| 153 | def decodestring(s, header=False): |
| 154 | if a2b_qp is not None: |