diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/tools/python3/src/Lib/quopri.py | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Lib/quopri.py')
-rw-r--r-- | contrib/tools/python3/src/Lib/quopri.py | 476 |
1 files changed, 238 insertions, 238 deletions
diff --git a/contrib/tools/python3/src/Lib/quopri.py b/contrib/tools/python3/src/Lib/quopri.py index 400b7d4320..08899c5cb7 100644 --- a/contrib/tools/python3/src/Lib/quopri.py +++ b/contrib/tools/python3/src/Lib/quopri.py @@ -1,242 +1,242 @@ -#! /usr/bin/env python3 - -"""Conversions to/from quoted-printable transport encoding as per RFC 1521.""" - -# (Dec 1991 version). - -__all__ = ["encode", "decode", "encodestring", "decodestring"] - -ESCAPE = b'=' -MAXLINESIZE = 76 -HEX = b'0123456789ABCDEF' -EMPTYSTRING = b'' - -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 byte ordinal 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. - """ - assert isinstance(c, bytes) - if c in b' \t': - return quotetabs - # if header, we have to escape _ because _ is used to escape space - if c == b'_': - return header - return c == ESCAPE or not (b' ' <= c <= b'~') - -def quote(c): - """Quote a single character.""" - assert isinstance(c, bytes) and len(c)==1 - c = ord(c) - return ESCAPE + bytes((HEX[c//16], HEX[c%16])) - - - -def encode(input, output, quotetabs, header=False): - """Read 'input', apply quoted-printable encoding, and write to 'output'. - - 'input' and 'output' are binary file objects. 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=b'\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 b' \t': - output.write(s[:-1] + quote(s[-1:]) + lineEnd) - elif s == b'.': - 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 = b'' - if line[-1:] == b'\n': - line = line[:-1] - stripped = b'\n' - # Calculate the un-length-limited encoded line - for c in line: - c = bytes((c,)) - if needsquoting(c, quotetabs, header): - c = quote(c) - if header and c == b' ': - outline.append(b'_') - 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=b'=\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=False, header=False): - if b2a_qp is not None: - return b2a_qp(s, quotetabs=quotetabs, header=header) - from io import BytesIO - infp = BytesIO(s) - outfp = BytesIO() - encode(infp, outfp, quotetabs, header) - return outfp.getvalue() - - - -def decode(input, output, header=False): - """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).""" - - if a2b_qp is not None: - data = input.read() - odata = a2b_qp(data, header=header) - output.write(odata) - return - - new = b'' - while 1: - line = input.readline() - if not line: break - i, n = 0, len(line) - if n > 0 and line[n-1:n] == b'\n': - partial = 0; n = n-1 - # Strip trailing whitespace - while n > 0 and line[n-1:n] in b" \t\r": - n = n-1 - else: - partial = 1 - while i < n: - c = line[i:i+1] - if c == b'_' and header: - new = new + b' '; 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:i+2] == ESCAPE: - new = new + ESCAPE; i = i+2 - elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]): - new = new + bytes((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 + b'\n') - new = b'' - if new: - output.write(new) - -def decodestring(s, header=False): - if a2b_qp is not None: - return a2b_qp(s, header=header) - from io import BytesIO - infp = BytesIO(s) - outfp = BytesIO() - decode(infp, outfp, header=header) - return outfp.getvalue() - - - -# Other helper functions -def ishex(c): - """Return true if the byte ordinal 'c' is a hexadecimal digit in ASCII.""" - assert isinstance(c, bytes) - return b'0' <= c <= b'9' or b'a' <= c <= b'f' or b'A' <= c <= b'F' - -def unhex(s): - """Get the integer value of a hexadecimal number.""" - bits = 0 - for c in s: - c = bytes((c,)) - if b'0' <= c <= b'9': - i = ord('0') - elif b'a' <= c <= b'f': - i = ord('a')-10 - elif b'A' <= c <= b'F': - i = ord(b'A')-10 - else: - assert False, "non-hex digit "+repr(c) - 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 as 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) +#! /usr/bin/env python3 + +"""Conversions to/from quoted-printable transport encoding as per RFC 1521.""" + +# (Dec 1991 version). + +__all__ = ["encode", "decode", "encodestring", "decodestring"] + +ESCAPE = b'=' +MAXLINESIZE = 76 +HEX = b'0123456789ABCDEF' +EMPTYSTRING = b'' + +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 byte ordinal 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. + """ + assert isinstance(c, bytes) + if c in b' \t': + return quotetabs + # if header, we have to escape _ because _ is used to escape space + if c == b'_': + return header + return c == ESCAPE or not (b' ' <= c <= b'~') + +def quote(c): + """Quote a single character.""" + assert isinstance(c, bytes) and len(c)==1 + c = ord(c) + return ESCAPE + bytes((HEX[c//16], HEX[c%16])) + + + +def encode(input, output, quotetabs, header=False): + """Read 'input', apply quoted-printable encoding, and write to 'output'. + + 'input' and 'output' are binary file objects. 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=b'\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 b' \t': + output.write(s[:-1] + quote(s[-1:]) + lineEnd) + elif s == b'.': + 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 = b'' + if line[-1:] == b'\n': + line = line[:-1] + stripped = b'\n' + # Calculate the un-length-limited encoded line + for c in line: + c = bytes((c,)) + if needsquoting(c, quotetabs, header): + c = quote(c) + if header and c == b' ': + outline.append(b'_') + 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=b'=\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=False, header=False): + if b2a_qp is not None: + return b2a_qp(s, quotetabs=quotetabs, header=header) + from io import BytesIO + infp = BytesIO(s) + outfp = BytesIO() + encode(infp, outfp, quotetabs, header) + return outfp.getvalue() + + + +def decode(input, output, header=False): + """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).""" + + if a2b_qp is not None: + data = input.read() + odata = a2b_qp(data, header=header) + output.write(odata) + return + + new = b'' + while 1: + line = input.readline() + if not line: break + i, n = 0, len(line) + if n > 0 and line[n-1:n] == b'\n': + partial = 0; n = n-1 + # Strip trailing whitespace + while n > 0 and line[n-1:n] in b" \t\r": + n = n-1 + else: + partial = 1 + while i < n: + c = line[i:i+1] + if c == b'_' and header: + new = new + b' '; 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:i+2] == ESCAPE: + new = new + ESCAPE; i = i+2 + elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]): + new = new + bytes((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 + b'\n') + new = b'' + if new: + output.write(new) + +def decodestring(s, header=False): + if a2b_qp is not None: + return a2b_qp(s, header=header) + from io import BytesIO + infp = BytesIO(s) + outfp = BytesIO() + decode(infp, outfp, header=header) + return outfp.getvalue() + + + +# Other helper functions +def ishex(c): + """Return true if the byte ordinal 'c' is a hexadecimal digit in ASCII.""" + assert isinstance(c, bytes) + return b'0' <= c <= b'9' or b'a' <= c <= b'f' or b'A' <= c <= b'F' + +def unhex(s): + """Get the integer value of a hexadecimal number.""" + bits = 0 + for c in s: + c = bytes((c,)) + if b'0' <= c <= b'9': + i = ord('0') + elif b'a' <= c <= b'f': + i = ord('a')-10 + elif b'A' <= c <= b'F': + i = ord(b'A')-10 + else: + assert False, "non-hex digit "+repr(c) + 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 as 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 = False tabs = False - for o, a in opts: + for o, a in opts: if o == '-t': tabs = True if o == '-d': deco = True - 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.buffer - else: - try: - fp = open(file, "rb") - except OSError as msg: - sys.stderr.write("%s: can't open (%s)\n" % (file, msg)) - sts = 1 - continue - try: - if deco: - decode(fp, sys.stdout.buffer) - else: - encode(fp, sys.stdout.buffer, tabs) - finally: - if file != '-': - fp.close() - if sts: - sys.exit(sts) - - - -if __name__ == '__main__': - main() + 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.buffer + else: + try: + fp = open(file, "rb") + except OSError as msg: + sys.stderr.write("%s: can't open (%s)\n" % (file, msg)) + sts = 1 + continue + try: + if deco: + decode(fp, sys.stdout.buffer) + else: + encode(fp, sys.stdout.buffer, tabs) + finally: + if file != '-': + fp.close() + if sts: + sys.exit(sts) + + + +if __name__ == '__main__': + main() |