mirror of
https://github.com/python/cpython
synced 2024-09-15 22:00:08 +00:00
bpo-45085: Remove the binhex module (GH-28117)
The binhex module, deprecated in Python 3.9, is now removed. The following binascii functions, deprecated in Python 3.9, are now also removed: * a2b_hqx(), b2a_hqx(); * rlecode_hqx(), rledecode_hqx(). The binascii.crc_hqx() function remains available.
This commit is contained in:
parent
d589a7e7eb
commit
a806608705
|
@ -8,14 +8,13 @@
|
|||
.. index::
|
||||
module: uu
|
||||
module: base64
|
||||
module: binhex
|
||||
|
||||
--------------
|
||||
|
||||
The :mod:`binascii` module contains a number of methods to convert between
|
||||
binary and various ASCII-encoded binary representations. Normally, you will not
|
||||
use these functions directly but use wrapper modules like :mod:`uu`,
|
||||
:mod:`base64`, or :mod:`binhex` instead. The :mod:`binascii` module contains
|
||||
use these functions directly but use wrapper modules like :mod:`uu` or
|
||||
:mod:`base64` instead. The :mod:`binascii` module contains
|
||||
low-level functions written in C for greater speed that are used by the
|
||||
higher-level modules.
|
||||
|
||||
|
@ -98,45 +97,6 @@ The :mod:`binascii` module defines the following functions:
|
|||
stream.
|
||||
|
||||
|
||||
.. function:: a2b_hqx(string)
|
||||
|
||||
Convert binhex4 formatted ASCII data to binary, without doing RLE-decompression.
|
||||
The string should contain a complete number of binary bytes, or (in case of the
|
||||
last portion of the binhex4 data) have the remaining bits zero.
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
|
||||
.. function:: rledecode_hqx(data)
|
||||
|
||||
Perform RLE-decompression on the data, as per the binhex4 standard. The
|
||||
algorithm uses ``0x90`` after a byte as a repeat indicator, followed by a count.
|
||||
A count of ``0`` specifies a byte value of ``0x90``. The routine returns the
|
||||
decompressed data, unless data input data ends in an orphaned repeat indicator,
|
||||
in which case the :exc:`Incomplete` exception is raised.
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
Accept only bytestring or bytearray objects as input.
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
|
||||
.. function:: rlecode_hqx(data)
|
||||
|
||||
Perform binhex4 style RLE-compression on *data* and return the result.
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
|
||||
.. function:: b2a_hqx(data)
|
||||
|
||||
Perform hexbin4 binary-to-ASCII translation and return the resulting string. The
|
||||
argument should already be RLE-coded, and have a length divisible by 3 (except
|
||||
possibly the last fragment).
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
|
||||
.. function:: crc_hqx(data, value)
|
||||
|
||||
Compute a 16-bit CRC value of *data*, starting with *value* as the
|
||||
|
@ -222,9 +182,6 @@ The :mod:`binascii` module defines the following functions:
|
|||
Support for RFC compliant base64-style encoding in base 16, 32, 64,
|
||||
and 85.
|
||||
|
||||
Module :mod:`binhex`
|
||||
Support for the binhex format used on the Macintosh.
|
||||
|
||||
Module :mod:`uu`
|
||||
Support for UU encoding used on Unix.
|
||||
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
:mod:`binhex` --- Encode and decode binhex4 files
|
||||
=================================================
|
||||
|
||||
.. module:: binhex
|
||||
:synopsis: Encode and decode files in binhex4 format.
|
||||
|
||||
**Source code:** :source:`Lib/binhex.py`
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
--------------
|
||||
|
||||
This module encodes and decodes files in binhex4 format, a format allowing
|
||||
representation of Macintosh files in ASCII. Only the data fork is handled.
|
||||
|
||||
The :mod:`binhex` module defines the following functions:
|
||||
|
||||
|
||||
.. function:: binhex(input, output)
|
||||
|
||||
Convert a binary file with filename *input* to binhex file *output*. The
|
||||
*output* parameter can either be a filename or a file-like object (any object
|
||||
supporting a :meth:`write` and :meth:`close` method).
|
||||
|
||||
|
||||
.. function:: hexbin(input, output)
|
||||
|
||||
Decode a binhex file *input*. *input* may be a filename or a file-like object
|
||||
supporting :meth:`read` and :meth:`close` methods. The resulting file is written
|
||||
to a file named *output*, unless the argument is ``None`` in which case the
|
||||
output filename is read from the binhex file.
|
||||
|
||||
The following exception is also defined:
|
||||
|
||||
|
||||
.. exception:: Error
|
||||
|
||||
Exception raised when something can't be encoded using the binhex format (for
|
||||
example, a filename is too long to fit in the filename field), or when input is
|
||||
not properly encoded binhex data.
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
Module :mod:`binascii`
|
||||
Support module containing ASCII-to-binary and binary-to-ASCII conversions.
|
||||
|
||||
|
||||
.. _binhex-notes:
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
There is an alternative, more powerful interface to the coder and decoder, see
|
||||
the source for details.
|
||||
|
||||
If you code or decode textfiles on non-Macintosh platforms they will still use
|
||||
the old Macintosh newline convention (carriage-return as end of line).
|
||||
|
|
@ -17,7 +17,6 @@ on the internet.
|
|||
mailbox.rst
|
||||
mimetypes.rst
|
||||
base64.rst
|
||||
binhex.rst
|
||||
binascii.rst
|
||||
quopri.rst
|
||||
uu.rst
|
||||
|
|
|
@ -235,9 +235,21 @@ sqlite3
|
|||
|
||||
Removed
|
||||
=======
|
||||
|
||||
* :class:`smtpd.MailmanProxy` is now removed as it is unusable without
|
||||
an external module, ``mailman``. (Contributed by Dong-hee Na in :issue:`35800`.)
|
||||
|
||||
* The ``binhex`` module, deprecated in Python 3.9, is now removed.
|
||||
The following :mod:`binascii` functions, deprecated in Python 3.9, are now
|
||||
also removed:
|
||||
|
||||
* ``a2b_hqx()``, ``b2a_hqx()``;
|
||||
* ``rlecode_hqx()``, ``rledecode_hqx()``.
|
||||
|
||||
The :func:`binascii.crc_hqx` function remains available.
|
||||
|
||||
(Contributed by Victor Stinner in :issue:`45085`.)
|
||||
|
||||
|
||||
Optimizations
|
||||
=============
|
||||
|
|
502
Lib/binhex.py
502
Lib/binhex.py
|
@ -1,502 +0,0 @@
|
|||
"""Macintosh binhex compression/decompression.
|
||||
|
||||
easy interface:
|
||||
binhex(inputfilename, outputfilename)
|
||||
hexbin(inputfilename, outputfilename)
|
||||
"""
|
||||
|
||||
#
|
||||
# Jack Jansen, CWI, August 1995.
|
||||
#
|
||||
# The module is supposed to be as compatible as possible. Especially the
|
||||
# easy interface should work "as expected" on any platform.
|
||||
# XXXX Note: currently, textfiles appear in mac-form on all platforms.
|
||||
# We seem to lack a simple character-translate in python.
|
||||
# (we should probably use ISO-Latin-1 on all but the mac platform).
|
||||
# XXXX The simple routines are too simple: they expect to hold the complete
|
||||
# files in-core. Should be fixed.
|
||||
# XXXX It would be nice to handle AppleDouble format on unix
|
||||
# (for servers serving macs).
|
||||
# XXXX I don't understand what happens when you get 0x90 times the same byte on
|
||||
# input. The resulting code (xx 90 90) would appear to be interpreted as an
|
||||
# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety...
|
||||
#
|
||||
import binascii
|
||||
import contextlib
|
||||
import io
|
||||
import os
|
||||
import struct
|
||||
import warnings
|
||||
|
||||
warnings.warn('the binhex module is deprecated', DeprecationWarning,
|
||||
stacklevel=2)
|
||||
|
||||
|
||||
__all__ = ["binhex","hexbin","Error"]
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
# States (what have we written)
|
||||
_DID_HEADER = 0
|
||||
_DID_DATA = 1
|
||||
|
||||
# Various constants
|
||||
REASONABLY_LARGE = 32768 # Minimal amount we pass the rle-coder
|
||||
LINELEN = 64
|
||||
RUNCHAR = b"\x90"
|
||||
|
||||
#
|
||||
# This code is no longer byte-order dependent
|
||||
|
||||
|
||||
class FInfo:
|
||||
def __init__(self):
|
||||
self.Type = '????'
|
||||
self.Creator = '????'
|
||||
self.Flags = 0
|
||||
|
||||
def getfileinfo(name):
|
||||
finfo = FInfo()
|
||||
with io.open(name, 'rb') as fp:
|
||||
# Quick check for textfile
|
||||
data = fp.read(512)
|
||||
if 0 not in data:
|
||||
finfo.Type = 'TEXT'
|
||||
fp.seek(0, 2)
|
||||
dsize = fp.tell()
|
||||
dir, file = os.path.split(name)
|
||||
file = file.replace(':', '-', 1)
|
||||
return file, finfo, dsize, 0
|
||||
|
||||
class openrsrc:
|
||||
def __init__(self, *args):
|
||||
pass
|
||||
|
||||
def read(self, *args):
|
||||
return b''
|
||||
|
||||
def write(self, *args):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
|
||||
# DeprecationWarning is already emitted on "import binhex". There is no need
|
||||
# to repeat the warning at each call to deprecated binascii functions.
|
||||
@contextlib.contextmanager
|
||||
def _ignore_deprecation_warning():
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('ignore', '', DeprecationWarning)
|
||||
yield
|
||||
|
||||
|
||||
class _Hqxcoderengine:
|
||||
"""Write data to the coder in 3-byte chunks"""
|
||||
|
||||
def __init__(self, ofp):
|
||||
self.ofp = ofp
|
||||
self.data = b''
|
||||
self.hqxdata = b''
|
||||
self.linelen = LINELEN - 1
|
||||
|
||||
def write(self, data):
|
||||
self.data = self.data + data
|
||||
datalen = len(self.data)
|
||||
todo = (datalen // 3) * 3
|
||||
data = self.data[:todo]
|
||||
self.data = self.data[todo:]
|
||||
if not data:
|
||||
return
|
||||
with _ignore_deprecation_warning():
|
||||
self.hqxdata = self.hqxdata + binascii.b2a_hqx(data)
|
||||
self._flush(0)
|
||||
|
||||
def _flush(self, force):
|
||||
first = 0
|
||||
while first <= len(self.hqxdata) - self.linelen:
|
||||
last = first + self.linelen
|
||||
self.ofp.write(self.hqxdata[first:last] + b'\r')
|
||||
self.linelen = LINELEN
|
||||
first = last
|
||||
self.hqxdata = self.hqxdata[first:]
|
||||
if force:
|
||||
self.ofp.write(self.hqxdata + b':\r')
|
||||
|
||||
def close(self):
|
||||
if self.data:
|
||||
with _ignore_deprecation_warning():
|
||||
self.hqxdata = self.hqxdata + binascii.b2a_hqx(self.data)
|
||||
self._flush(1)
|
||||
self.ofp.close()
|
||||
del self.ofp
|
||||
|
||||
class _Rlecoderengine:
|
||||
"""Write data to the RLE-coder in suitably large chunks"""
|
||||
|
||||
def __init__(self, ofp):
|
||||
self.ofp = ofp
|
||||
self.data = b''
|
||||
|
||||
def write(self, data):
|
||||
self.data = self.data + data
|
||||
if len(self.data) < REASONABLY_LARGE:
|
||||
return
|
||||
with _ignore_deprecation_warning():
|
||||
rledata = binascii.rlecode_hqx(self.data)
|
||||
self.ofp.write(rledata)
|
||||
self.data = b''
|
||||
|
||||
def close(self):
|
||||
if self.data:
|
||||
with _ignore_deprecation_warning():
|
||||
rledata = binascii.rlecode_hqx(self.data)
|
||||
self.ofp.write(rledata)
|
||||
self.ofp.close()
|
||||
del self.ofp
|
||||
|
||||
class BinHex:
|
||||
def __init__(self, name_finfo_dlen_rlen, ofp):
|
||||
name, finfo, dlen, rlen = name_finfo_dlen_rlen
|
||||
close_on_error = False
|
||||
if isinstance(ofp, str):
|
||||
ofname = ofp
|
||||
ofp = io.open(ofname, 'wb')
|
||||
close_on_error = True
|
||||
try:
|
||||
ofp.write(b'(This file must be converted with BinHex 4.0)\r\r:')
|
||||
hqxer = _Hqxcoderengine(ofp)
|
||||
self.ofp = _Rlecoderengine(hqxer)
|
||||
self.crc = 0
|
||||
if finfo is None:
|
||||
finfo = FInfo()
|
||||
self.dlen = dlen
|
||||
self.rlen = rlen
|
||||
self._writeinfo(name, finfo)
|
||||
self.state = _DID_HEADER
|
||||
except:
|
||||
if close_on_error:
|
||||
ofp.close()
|
||||
raise
|
||||
|
||||
def _writeinfo(self, name, finfo):
|
||||
nl = len(name)
|
||||
if nl > 63:
|
||||
raise Error('Filename too long')
|
||||
d = bytes([nl]) + name.encode("latin-1") + b'\0'
|
||||
tp, cr = finfo.Type, finfo.Creator
|
||||
if isinstance(tp, str):
|
||||
tp = tp.encode("latin-1")
|
||||
if isinstance(cr, str):
|
||||
cr = cr.encode("latin-1")
|
||||
d2 = tp + cr
|
||||
|
||||
# Force all structs to be packed with big-endian
|
||||
d3 = struct.pack('>h', finfo.Flags)
|
||||
d4 = struct.pack('>ii', self.dlen, self.rlen)
|
||||
info = d + d2 + d3 + d4
|
||||
self._write(info)
|
||||
self._writecrc()
|
||||
|
||||
def _write(self, data):
|
||||
self.crc = binascii.crc_hqx(data, self.crc)
|
||||
self.ofp.write(data)
|
||||
|
||||
def _writecrc(self):
|
||||
# XXXX Should this be here??
|
||||
# self.crc = binascii.crc_hqx('\0\0', self.crc)
|
||||
if self.crc < 0:
|
||||
fmt = '>h'
|
||||
else:
|
||||
fmt = '>H'
|
||||
self.ofp.write(struct.pack(fmt, self.crc))
|
||||
self.crc = 0
|
||||
|
||||
def write(self, data):
|
||||
if self.state != _DID_HEADER:
|
||||
raise Error('Writing data at the wrong time')
|
||||
self.dlen = self.dlen - len(data)
|
||||
self._write(data)
|
||||
|
||||
def close_data(self):
|
||||
if self.dlen != 0:
|
||||
raise Error('Incorrect data size, diff=%r' % (self.rlen,))
|
||||
self._writecrc()
|
||||
self.state = _DID_DATA
|
||||
|
||||
def write_rsrc(self, data):
|
||||
if self.state < _DID_DATA:
|
||||
self.close_data()
|
||||
if self.state != _DID_DATA:
|
||||
raise Error('Writing resource data at the wrong time')
|
||||
self.rlen = self.rlen - len(data)
|
||||
self._write(data)
|
||||
|
||||
def close(self):
|
||||
if self.state is None:
|
||||
return
|
||||
try:
|
||||
if self.state < _DID_DATA:
|
||||
self.close_data()
|
||||
if self.state != _DID_DATA:
|
||||
raise Error('Close at the wrong time')
|
||||
if self.rlen != 0:
|
||||
raise Error("Incorrect resource-datasize, diff=%r" % (self.rlen,))
|
||||
self._writecrc()
|
||||
finally:
|
||||
self.state = None
|
||||
ofp = self.ofp
|
||||
del self.ofp
|
||||
ofp.close()
|
||||
|
||||
def binhex(inp, out):
|
||||
"""binhex(infilename, outfilename): create binhex-encoded copy of a file"""
|
||||
finfo = getfileinfo(inp)
|
||||
ofp = BinHex(finfo, out)
|
||||
|
||||
with io.open(inp, 'rb') as ifp:
|
||||
# XXXX Do textfile translation on non-mac systems
|
||||
while True:
|
||||
d = ifp.read(128000)
|
||||
if not d: break
|
||||
ofp.write(d)
|
||||
ofp.close_data()
|
||||
|
||||
ifp = openrsrc(inp, 'rb')
|
||||
while True:
|
||||
d = ifp.read(128000)
|
||||
if not d: break
|
||||
ofp.write_rsrc(d)
|
||||
ofp.close()
|
||||
ifp.close()
|
||||
|
||||
class _Hqxdecoderengine:
|
||||
"""Read data via the decoder in 4-byte chunks"""
|
||||
|
||||
def __init__(self, ifp):
|
||||
self.ifp = ifp
|
||||
self.eof = 0
|
||||
|
||||
def read(self, totalwtd):
|
||||
"""Read at least wtd bytes (or until EOF)"""
|
||||
decdata = b''
|
||||
wtd = totalwtd
|
||||
#
|
||||
# The loop here is convoluted, since we don't really now how
|
||||
# much to decode: there may be newlines in the incoming data.
|
||||
while wtd > 0:
|
||||
if self.eof: return decdata
|
||||
wtd = ((wtd + 2) // 3) * 4
|
||||
data = self.ifp.read(wtd)
|
||||
#
|
||||
# Next problem: there may not be a complete number of
|
||||
# bytes in what we pass to a2b. Solve by yet another
|
||||
# loop.
|
||||
#
|
||||
while True:
|
||||
try:
|
||||
with _ignore_deprecation_warning():
|
||||
decdatacur, self.eof = binascii.a2b_hqx(data)
|
||||
break
|
||||
except binascii.Incomplete:
|
||||
pass
|
||||
newdata = self.ifp.read(1)
|
||||
if not newdata:
|
||||
raise Error('Premature EOF on binhex file')
|
||||
data = data + newdata
|
||||
decdata = decdata + decdatacur
|
||||
wtd = totalwtd - len(decdata)
|
||||
if not decdata and not self.eof:
|
||||
raise Error('Premature EOF on binhex file')
|
||||
return decdata
|
||||
|
||||
def close(self):
|
||||
self.ifp.close()
|
||||
|
||||
class _Rledecoderengine:
|
||||
"""Read data via the RLE-coder"""
|
||||
|
||||
def __init__(self, ifp):
|
||||
self.ifp = ifp
|
||||
self.pre_buffer = b''
|
||||
self.post_buffer = b''
|
||||
self.eof = 0
|
||||
|
||||
def read(self, wtd):
|
||||
if wtd > len(self.post_buffer):
|
||||
self._fill(wtd - len(self.post_buffer))
|
||||
rv = self.post_buffer[:wtd]
|
||||
self.post_buffer = self.post_buffer[wtd:]
|
||||
return rv
|
||||
|
||||
def _fill(self, wtd):
|
||||
self.pre_buffer = self.pre_buffer + self.ifp.read(wtd + 4)
|
||||
if self.ifp.eof:
|
||||
with _ignore_deprecation_warning():
|
||||
self.post_buffer = self.post_buffer + \
|
||||
binascii.rledecode_hqx(self.pre_buffer)
|
||||
self.pre_buffer = b''
|
||||
return
|
||||
|
||||
#
|
||||
# Obfuscated code ahead. We have to take care that we don't
|
||||
# end up with an orphaned RUNCHAR later on. So, we keep a couple
|
||||
# of bytes in the buffer, depending on what the end of
|
||||
# the buffer looks like:
|
||||
# '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0)
|
||||
# '?\220' - Keep 2 bytes: repeated something-else
|
||||
# '\220\0' - Escaped \220: Keep 2 bytes.
|
||||
# '?\220?' - Complete repeat sequence: decode all
|
||||
# otherwise: keep 1 byte.
|
||||
#
|
||||
mark = len(self.pre_buffer)
|
||||
if self.pre_buffer[-3:] == RUNCHAR + b'\0' + RUNCHAR:
|
||||
mark = mark - 3
|
||||
elif self.pre_buffer[-1:] == RUNCHAR:
|
||||
mark = mark - 2
|
||||
elif self.pre_buffer[-2:] == RUNCHAR + b'\0':
|
||||
mark = mark - 2
|
||||
elif self.pre_buffer[-2:-1] == RUNCHAR:
|
||||
pass # Decode all
|
||||
else:
|
||||
mark = mark - 1
|
||||
|
||||
with _ignore_deprecation_warning():
|
||||
self.post_buffer = self.post_buffer + \
|
||||
binascii.rledecode_hqx(self.pre_buffer[:mark])
|
||||
self.pre_buffer = self.pre_buffer[mark:]
|
||||
|
||||
def close(self):
|
||||
self.ifp.close()
|
||||
|
||||
class HexBin:
|
||||
def __init__(self, ifp):
|
||||
if isinstance(ifp, str):
|
||||
ifp = io.open(ifp, 'rb')
|
||||
#
|
||||
# Find initial colon.
|
||||
#
|
||||
while True:
|
||||
ch = ifp.read(1)
|
||||
if not ch:
|
||||
raise Error("No binhex data found")
|
||||
# Cater for \r\n terminated lines (which show up as \n\r, hence
|
||||
# all lines start with \r)
|
||||
if ch == b'\r':
|
||||
continue
|
||||
if ch == b':':
|
||||
break
|
||||
|
||||
hqxifp = _Hqxdecoderengine(ifp)
|
||||
self.ifp = _Rledecoderengine(hqxifp)
|
||||
self.crc = 0
|
||||
self._readheader()
|
||||
|
||||
def _read(self, len):
|
||||
data = self.ifp.read(len)
|
||||
self.crc = binascii.crc_hqx(data, self.crc)
|
||||
return data
|
||||
|
||||
def _checkcrc(self):
|
||||
filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff
|
||||
#self.crc = binascii.crc_hqx('\0\0', self.crc)
|
||||
# XXXX Is this needed??
|
||||
self.crc = self.crc & 0xffff
|
||||
if filecrc != self.crc:
|
||||
raise Error('CRC error, computed %x, read %x'
|
||||
% (self.crc, filecrc))
|
||||
self.crc = 0
|
||||
|
||||
def _readheader(self):
|
||||
len = self._read(1)
|
||||
fname = self._read(ord(len))
|
||||
rest = self._read(1 + 4 + 4 + 2 + 4 + 4)
|
||||
self._checkcrc()
|
||||
|
||||
type = rest[1:5]
|
||||
creator = rest[5:9]
|
||||
flags = struct.unpack('>h', rest[9:11])[0]
|
||||
self.dlen = struct.unpack('>l', rest[11:15])[0]
|
||||
self.rlen = struct.unpack('>l', rest[15:19])[0]
|
||||
|
||||
self.FName = fname
|
||||
self.FInfo = FInfo()
|
||||
self.FInfo.Creator = creator
|
||||
self.FInfo.Type = type
|
||||
self.FInfo.Flags = flags
|
||||
|
||||
self.state = _DID_HEADER
|
||||
|
||||
def read(self, *n):
|
||||
if self.state != _DID_HEADER:
|
||||
raise Error('Read data at wrong time')
|
||||
if n:
|
||||
n = n[0]
|
||||
n = min(n, self.dlen)
|
||||
else:
|
||||
n = self.dlen
|
||||
rv = b''
|
||||
while len(rv) < n:
|
||||
rv = rv + self._read(n-len(rv))
|
||||
self.dlen = self.dlen - n
|
||||
return rv
|
||||
|
||||
def close_data(self):
|
||||
if self.state != _DID_HEADER:
|
||||
raise Error('close_data at wrong time')
|
||||
if self.dlen:
|
||||
dummy = self._read(self.dlen)
|
||||
self._checkcrc()
|
||||
self.state = _DID_DATA
|
||||
|
||||
def read_rsrc(self, *n):
|
||||
if self.state == _DID_HEADER:
|
||||
self.close_data()
|
||||
if self.state != _DID_DATA:
|
||||
raise Error('Read resource data at wrong time')
|
||||
if n:
|
||||
n = n[0]
|
||||
n = min(n, self.rlen)
|
||||
else:
|
||||
n = self.rlen
|
||||
self.rlen = self.rlen - n
|
||||
return self._read(n)
|
||||
|
||||
def close(self):
|
||||
if self.state is None:
|
||||
return
|
||||
try:
|
||||
if self.rlen:
|
||||
dummy = self.read_rsrc(self.rlen)
|
||||
self._checkcrc()
|
||||
finally:
|
||||
self.state = None
|
||||
self.ifp.close()
|
||||
|
||||
def hexbin(inp, out):
|
||||
"""hexbin(infilename, outfilename) - Decode binhexed file"""
|
||||
ifp = HexBin(inp)
|
||||
finfo = ifp.FInfo
|
||||
if not out:
|
||||
out = ifp.FName
|
||||
|
||||
with io.open(out, 'wb') as ofp:
|
||||
# XXXX Do translation on non-mac systems
|
||||
while True:
|
||||
d = ifp.read(128000)
|
||||
if not d: break
|
||||
ofp.write(d)
|
||||
ifp.close_data()
|
||||
|
||||
d = ifp.read_rsrc(128000)
|
||||
if d:
|
||||
ofp = openrsrc(out, 'wb')
|
||||
ofp.write(d)
|
||||
while True:
|
||||
d = ifp.read_rsrc(128000)
|
||||
if not d: break
|
||||
ofp.write(d)
|
||||
ofp.close()
|
||||
|
||||
ifp.close()
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
|
||||
# Note: "*_hex" functions are aliases for "(un)hexlify"
|
||||
b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_hqx', 'b2a_qp', 'b2a_uu',
|
||||
'hexlify', 'rlecode_hqx']
|
||||
a2b_functions = ['a2b_base64', 'a2b_hex', 'a2b_hqx', 'a2b_qp', 'a2b_uu',
|
||||
'unhexlify', 'rledecode_hqx']
|
||||
b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_qp', 'b2a_uu',
|
||||
'hexlify']
|
||||
a2b_functions = ['a2b_base64', 'a2b_hex', 'a2b_qp', 'a2b_uu',
|
||||
'unhexlify']
|
||||
all_functions = a2b_functions + b2a_functions + ['crc32', 'crc_hqx']
|
||||
|
||||
|
||||
|
@ -38,7 +38,6 @@ def test_functions(self):
|
|||
self.assertTrue(hasattr(getattr(binascii, name), '__call__'))
|
||||
self.assertRaises(TypeError, getattr(binascii, name))
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_returned_value(self):
|
||||
# Limit to the minimum of all limits (b2a_uu)
|
||||
MAX_ALL = 45
|
||||
|
@ -51,9 +50,6 @@ def test_returned_value(self):
|
|||
res = a2b(self.type2test(a))
|
||||
except Exception as err:
|
||||
self.fail("{}/{} conversion raises {!r}".format(fb, fa, err))
|
||||
if fb == 'b2a_hqx':
|
||||
# b2a_hqx returns a tuple
|
||||
res, _ = res
|
||||
self.assertEqual(res, raw, "{}/{} conversion: "
|
||||
"{!r} != {!r}".format(fb, fa, res, raw))
|
||||
self.assertIsInstance(res, bytes)
|
||||
|
@ -226,7 +222,6 @@ def test_uu(self):
|
|||
with self.assertRaises(TypeError):
|
||||
binascii.b2a_uu(b"", True)
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_crc_hqx(self):
|
||||
crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0)
|
||||
crc = binascii.crc_hqx(self.type2test(b" this string."), crc)
|
||||
|
@ -246,32 +241,6 @@ def test_crc32(self):
|
|||
|
||||
self.assertRaises(TypeError, binascii.crc32)
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_hqx(self):
|
||||
# Perform binhex4 style RLE-compression
|
||||
# Then calculate the hexbin4 binary-to-ASCII translation
|
||||
rle = binascii.rlecode_hqx(self.data)
|
||||
a = binascii.b2a_hqx(self.type2test(rle))
|
||||
|
||||
b, _ = binascii.a2b_hqx(self.type2test(a))
|
||||
res = binascii.rledecode_hqx(b)
|
||||
self.assertEqual(res, self.rawdata)
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_rle(self):
|
||||
# test repetition with a repetition longer than the limit of 255
|
||||
data = (b'a' * 100 + b'b' + b'c' * 300)
|
||||
|
||||
encoded = binascii.rlecode_hqx(data)
|
||||
self.assertEqual(encoded,
|
||||
(b'a\x90d' # 'a' * 100
|
||||
b'b' # 'b'
|
||||
b'c\x90\xff' # 'c' * 255
|
||||
b'c\x90-')) # 'c' * 45
|
||||
|
||||
decoded = binascii.rledecode_hqx(encoded)
|
||||
self.assertEqual(decoded, data)
|
||||
|
||||
def test_hex(self):
|
||||
# test hexlification
|
||||
s = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
|
||||
|
@ -404,7 +373,6 @@ def test_qp(self):
|
|||
self.assertEqual(b2a_qp(type2test(b'a.\n')), b'a.\n')
|
||||
self.assertEqual(b2a_qp(type2test(b'.a')[:-1]), b'=2E')
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_empty_string(self):
|
||||
# A test for SF bug #1022953. Make sure SystemError is not raised.
|
||||
empty = self.type2test(b'')
|
||||
|
@ -421,7 +389,7 @@ def test_empty_string(self):
|
|||
|
||||
def test_unicode_b2a(self):
|
||||
# Unicode strings are not accepted by b2a_* functions.
|
||||
for func in set(all_functions) - set(a2b_functions) | {'rledecode_hqx'}:
|
||||
for func in set(all_functions) - set(a2b_functions):
|
||||
try:
|
||||
self.assertRaises(TypeError, getattr(binascii, func), "test")
|
||||
except Exception as err:
|
||||
|
@ -429,15 +397,11 @@ def test_unicode_b2a(self):
|
|||
# crc_hqx needs 2 arguments
|
||||
self.assertRaises(TypeError, binascii.crc_hqx, "test", 0)
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_unicode_a2b(self):
|
||||
# Unicode strings are accepted by a2b_* functions.
|
||||
MAX_ALL = 45
|
||||
raw = self.rawdata[:MAX_ALL]
|
||||
for fa, fb in zip(a2b_functions, b2a_functions):
|
||||
if fa == 'rledecode_hqx':
|
||||
# Takes non-ASCII data
|
||||
continue
|
||||
a2b = getattr(binascii, fa)
|
||||
b2a = getattr(binascii, fb)
|
||||
try:
|
||||
|
@ -447,10 +411,6 @@ def test_unicode_a2b(self):
|
|||
res = a2b(a)
|
||||
except Exception as err:
|
||||
self.fail("{}/{} conversion raises {!r}".format(fb, fa, err))
|
||||
if fb == 'b2a_hqx':
|
||||
# b2a_hqx returns a tuple
|
||||
res, _ = res
|
||||
binary_res, _ = binary_res
|
||||
self.assertEqual(res, raw, "{}/{} conversion: "
|
||||
"{!r} != {!r}".format(fb, fa, res, raw))
|
||||
self.assertEqual(res, binary_res)
|
||||
|
@ -468,18 +428,6 @@ def test_b2a_base64_newline(self):
|
|||
self.assertEqual(binascii.b2a_base64(b, newline=False),
|
||||
b'aGVsbG8=')
|
||||
|
||||
def test_deprecated_warnings(self):
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertEqual(binascii.b2a_hqx(b'abc'), b'B@*M')
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertEqual(binascii.a2b_hqx(b'B@*M'), (b'abc', 0))
|
||||
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertEqual(binascii.rlecode_hqx(b'a' * 10), b'a\x90\n')
|
||||
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
self.assertEqual(binascii.rledecode_hqx(b'a\x90\n'), b'a' * 10)
|
||||
|
||||
|
||||
class ArrayBinASCIITest(BinASCIITest):
|
||||
def type2test(self, s):
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
"""Test script for the binhex C module
|
||||
|
||||
Uses the mechanism of the python binhex module
|
||||
Based on an original test by Roger E. Masse.
|
||||
"""
|
||||
import unittest
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support import os_helper
|
||||
from test.support import warnings_helper
|
||||
|
||||
|
||||
with warnings_helper.check_warnings(('', DeprecationWarning)):
|
||||
binhex = import_helper.import_fresh_module('binhex')
|
||||
|
||||
|
||||
class BinHexTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# binhex supports only file names encodable to Latin1
|
||||
self.fname1 = os_helper.TESTFN_ASCII + "1"
|
||||
self.fname2 = os_helper.TESTFN_ASCII + "2"
|
||||
self.fname3 = os_helper.TESTFN_ASCII + "very_long_filename__very_long_filename__very_long_filename__very_long_filename__"
|
||||
|
||||
def tearDown(self):
|
||||
os_helper.unlink(self.fname1)
|
||||
os_helper.unlink(self.fname2)
|
||||
os_helper.unlink(self.fname3)
|
||||
|
||||
DATA = b'Jack is my hero'
|
||||
|
||||
def test_binhex(self):
|
||||
with open(self.fname1, 'wb') as f:
|
||||
f.write(self.DATA)
|
||||
|
||||
binhex.binhex(self.fname1, self.fname2)
|
||||
|
||||
binhex.hexbin(self.fname2, self.fname1)
|
||||
|
||||
with open(self.fname1, 'rb') as f:
|
||||
finish = f.readline()
|
||||
|
||||
self.assertEqual(self.DATA, finish)
|
||||
|
||||
def test_binhex_error_on_long_filename(self):
|
||||
"""
|
||||
The testcase fails if no exception is raised when a filename parameter provided to binhex.binhex()
|
||||
is too long, or if the exception raised in binhex.binhex() is not an instance of binhex.Error.
|
||||
"""
|
||||
f3 = open(self.fname3, 'wb')
|
||||
f3.close()
|
||||
|
||||
self.assertRaises(binhex.Error, binhex.binhex, self.fname3, self.fname2)
|
||||
|
||||
def test_binhex_line_endings(self):
|
||||
# bpo-29566: Ensure the line endings are those for macOS 9
|
||||
with open(self.fname1, 'wb') as f:
|
||||
f.write(self.DATA)
|
||||
|
||||
binhex.binhex(self.fname1, self.fname2)
|
||||
|
||||
with open(self.fname2, 'rb') as fp:
|
||||
contents = fp.read()
|
||||
|
||||
self.assertNotIn(b'\n', contents)
|
||||
|
||||
def test_main():
|
||||
support.run_unittest(BinHexTestCase)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
|
@ -0,0 +1,10 @@
|
|||
The ``binhex`` module, deprecated in Python 3.9, is now removed. The
|
||||
following :mod:`binascii` functions, deprecated in Python 3.9, are now also
|
||||
removed:
|
||||
|
||||
* ``a2b_hqx()``, ``b2a_hqx()``;
|
||||
* ``rlecode_hqx()``, ``rledecode_hqx()``.
|
||||
|
||||
The :func:`binascii.crc_hqx` function remains available.
|
||||
|
||||
Patch by Victor Stinner.
|
|
@ -72,69 +72,6 @@ get_binascii_state(PyObject *module)
|
|||
return (binascii_state *)PyModule_GetState(module);
|
||||
}
|
||||
|
||||
/*
|
||||
** hqx lookup table, ascii->binary.
|
||||
*/
|
||||
|
||||
#define RUNCHAR 0x90
|
||||
|
||||
#define DONE 0x7F
|
||||
#define SKIP 0x7E
|
||||
#define FAIL 0x7D
|
||||
|
||||
static const unsigned char table_a2b_hqx[256] = {
|
||||
/* ^@ ^A ^B ^C ^D ^E ^F ^G */
|
||||
/* 0*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
/* \b \t \n ^K ^L \r ^N ^O */
|
||||
/* 1*/ FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
|
||||
/* ^P ^Q ^R ^S ^T ^U ^V ^W */
|
||||
/* 2*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
/* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */
|
||||
/* 3*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
/* ! " # $ % & ' */
|
||||
/* 4*/ FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
/* ( ) * + , - . / */
|
||||
/* 5*/ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
/* 6*/ 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
|
||||
/* 8 9 : ; < = > ? */
|
||||
/* 7*/ 0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
/* @ A B C D E F G */
|
||||
/* 8*/ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
|
||||
/* H I J K L M N O */
|
||||
/* 9*/ 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
|
||||
/* P Q R S T U V W */
|
||||
/*10*/ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
|
||||
/* X Y Z [ \ ] ^ _ */
|
||||
/*11*/ 0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
|
||||
/* ` a b c d e f g */
|
||||
/*12*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
|
||||
/* h i j k l m n o */
|
||||
/*13*/ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
|
||||
/* p q r s t u v w */
|
||||
/*14*/ 0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
/* x y z { | } ~ ^? */
|
||||
/*15*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
/*16*/ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
|
||||
};
|
||||
|
||||
static const unsigned char table_b2a_hqx[] =
|
||||
"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
|
||||
|
||||
static const unsigned char table_a2b_base64[] = {
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
|
@ -165,7 +102,6 @@ static const unsigned char table_b2a_base64[] =
|
|||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
|
||||
|
||||
static const unsigned short crctab_hqx[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
|
@ -649,356 +585,6 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline)
|
|||
return _PyBytesWriter_Finish(&writer, ascii_data);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
binascii.a2b_hqx
|
||||
|
||||
data: ascii_buffer
|
||||
/
|
||||
|
||||
Decode .hqx coding.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data)
|
||||
/*[clinic end generated code: output=4d6d8c54d54ea1c1 input=0d914c680e0eed55]*/
|
||||
{
|
||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"binascii.a2b_hqx() is deprecated", 1) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char *ascii_data;
|
||||
unsigned char *bin_data;
|
||||
int leftbits = 0;
|
||||
unsigned char this_ch;
|
||||
unsigned int leftchar = 0;
|
||||
PyObject *res;
|
||||
Py_ssize_t len;
|
||||
int done = 0;
|
||||
_PyBytesWriter writer;
|
||||
binascii_state *state;
|
||||
|
||||
ascii_data = data->buf;
|
||||
len = data->len;
|
||||
_PyBytesWriter_Init(&writer);
|
||||
|
||||
assert(len >= 0);
|
||||
|
||||
if (len > PY_SSIZE_T_MAX - 2)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
/* Allocate a string that is too big (fixed later)
|
||||
Add two to the initial length to prevent interning which
|
||||
would preclude subsequent resizing. */
|
||||
bin_data = _PyBytesWriter_Alloc(&writer, len + 2);
|
||||
if (bin_data == NULL)
|
||||
return NULL;
|
||||
|
||||
for( ; len > 0 ; len--, ascii_data++ ) {
|
||||
/* Get the byte and look it up */
|
||||
this_ch = table_a2b_hqx[*ascii_data];
|
||||
if ( this_ch == SKIP )
|
||||
continue;
|
||||
if ( this_ch == FAIL ) {
|
||||
state = get_binascii_state(module);
|
||||
if (state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyErr_SetString(state->Error, "Illegal char");
|
||||
_PyBytesWriter_Dealloc(&writer);
|
||||
return NULL;
|
||||
}
|
||||
if ( this_ch == DONE ) {
|
||||
/* The terminating colon */
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shift it into the buffer and see if any bytes are ready */
|
||||
leftchar = (leftchar << 6) | (this_ch);
|
||||
leftbits += 6;
|
||||
if ( leftbits >= 8 ) {
|
||||
leftbits -= 8;
|
||||
*bin_data++ = (leftchar >> leftbits) & 0xff;
|
||||
leftchar &= ((1 << leftbits) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( leftbits && !done ) {
|
||||
state = get_binascii_state(module);
|
||||
if (state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyErr_SetString(state->Incomplete,
|
||||
"String has incomplete number of bytes");
|
||||
_PyBytesWriter_Dealloc(&writer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = _PyBytesWriter_Finish(&writer, bin_data);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
return Py_BuildValue("Ni", res, done);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
binascii.rlecode_hqx
|
||||
|
||||
data: Py_buffer
|
||||
/
|
||||
|
||||
Binhex RLE-code binary data.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data)
|
||||
/*[clinic end generated code: output=393d79338f5f5629 input=e1f1712447a82b09]*/
|
||||
{
|
||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"binascii.rlecode_hqx() is deprecated", 1) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char *in_data;
|
||||
unsigned char *out_data;
|
||||
unsigned char ch;
|
||||
Py_ssize_t in, inend, len;
|
||||
_PyBytesWriter writer;
|
||||
|
||||
_PyBytesWriter_Init(&writer);
|
||||
in_data = data->buf;
|
||||
len = data->len;
|
||||
|
||||
assert(len >= 0);
|
||||
|
||||
if (len > PY_SSIZE_T_MAX / 2 - 2)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
/* Worst case: output is twice as big as input (fixed later) */
|
||||
out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2);
|
||||
if (out_data == NULL)
|
||||
return NULL;
|
||||
|
||||
for( in=0; in<len; in++) {
|
||||
ch = in_data[in];
|
||||
if ( ch == RUNCHAR ) {
|
||||
/* RUNCHAR. Escape it. */
|
||||
*out_data++ = RUNCHAR;
|
||||
*out_data++ = 0;
|
||||
} else {
|
||||
/* Check how many following are the same */
|
||||
for(inend=in+1;
|
||||
inend<len && in_data[inend] == ch &&
|
||||
inend < in+255;
|
||||
inend++) ;
|
||||
if ( inend - in > 3 ) {
|
||||
/* More than 3 in a row. Output RLE. */
|
||||
*out_data++ = ch;
|
||||
*out_data++ = RUNCHAR;
|
||||
*out_data++ = (unsigned char) (inend-in);
|
||||
in = inend-1;
|
||||
} else {
|
||||
/* Less than 3. Output the byte itself */
|
||||
*out_data++ = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _PyBytesWriter_Finish(&writer, out_data);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
binascii.b2a_hqx
|
||||
|
||||
data: Py_buffer
|
||||
/
|
||||
|
||||
Encode .hqx data.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data)
|
||||
/*[clinic end generated code: output=d0aa5a704bc9f7de input=9596ebe019fe12ba]*/
|
||||
{
|
||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"binascii.b2a_hqx() is deprecated", 1) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char *ascii_data;
|
||||
const unsigned char *bin_data;
|
||||
int leftbits = 0;
|
||||
unsigned char this_ch;
|
||||
unsigned int leftchar = 0;
|
||||
Py_ssize_t len;
|
||||
_PyBytesWriter writer;
|
||||
|
||||
bin_data = data->buf;
|
||||
len = data->len;
|
||||
_PyBytesWriter_Init(&writer);
|
||||
|
||||
assert(len >= 0);
|
||||
|
||||
if (len > PY_SSIZE_T_MAX / 2 - 2)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
/* Allocate a buffer that is at least large enough */
|
||||
ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2);
|
||||
if (ascii_data == NULL)
|
||||
return NULL;
|
||||
|
||||
for( ; len > 0 ; len--, bin_data++ ) {
|
||||
/* Shift into our buffer, and output any 6bits ready */
|
||||
leftchar = (leftchar << 8) | *bin_data;
|
||||
leftbits += 8;
|
||||
while ( leftbits >= 6 ) {
|
||||
this_ch = (leftchar >> (leftbits-6)) & 0x3f;
|
||||
leftbits -= 6;
|
||||
*ascii_data++ = table_b2a_hqx[this_ch];
|
||||
}
|
||||
}
|
||||
/* Output a possible runt byte */
|
||||
if ( leftbits ) {
|
||||
leftchar <<= (6-leftbits);
|
||||
*ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
|
||||
}
|
||||
|
||||
return _PyBytesWriter_Finish(&writer, ascii_data);
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
binascii.rledecode_hqx
|
||||
|
||||
data: Py_buffer
|
||||
/
|
||||
|
||||
Decode hexbin RLE-coded string.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data)
|
||||
/*[clinic end generated code: output=9826619565de1c6c input=54cdd49fc014402c]*/
|
||||
{
|
||||
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||
"binascii.rledecode_hqx() is deprecated", 1) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char *in_data;
|
||||
unsigned char *out_data;
|
||||
unsigned char in_byte, in_repeat;
|
||||
Py_ssize_t in_len;
|
||||
_PyBytesWriter writer;
|
||||
|
||||
in_data = data->buf;
|
||||
in_len = data->len;
|
||||
_PyBytesWriter_Init(&writer);
|
||||
binascii_state *state;
|
||||
|
||||
assert(in_len >= 0);
|
||||
|
||||
/* Empty string is a special case */
|
||||
if ( in_len == 0 )
|
||||
return PyBytes_FromStringAndSize("", 0);
|
||||
else if (in_len > PY_SSIZE_T_MAX / 2)
|
||||
return PyErr_NoMemory();
|
||||
|
||||
/* Allocate a buffer of reasonable size. Resized when needed */
|
||||
out_data = _PyBytesWriter_Alloc(&writer, in_len);
|
||||
if (out_data == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Use overallocation */
|
||||
writer.overallocate = 1;
|
||||
|
||||
/*
|
||||
** We need two macros here to get/put bytes and handle
|
||||
** end-of-buffer for input and output strings.
|
||||
*/
|
||||
#define INBYTE(b) \
|
||||
do { \
|
||||
if ( --in_len < 0 ) { \
|
||||
state = get_binascii_state(module); \
|
||||
if (state == NULL) { \
|
||||
return NULL; \
|
||||
} \
|
||||
PyErr_SetString(state->Incomplete, ""); \
|
||||
goto error; \
|
||||
} \
|
||||
b = *in_data++; \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
** Handle first byte separately (since we have to get angry
|
||||
** in case of an orphaned RLE code).
|
||||
*/
|
||||
INBYTE(in_byte);
|
||||
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
/* only 1 byte will be written, but 2 bytes were preallocated:
|
||||
subtract 1 byte to prevent overallocation */
|
||||
writer.min_size--;
|
||||
|
||||
if (in_repeat != 0) {
|
||||
/* Note Error, not Incomplete (which is at the end
|
||||
** of the string only). This is a programmer error.
|
||||
*/
|
||||
state = get_binascii_state(module);
|
||||
if (state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyErr_SetString(state->Error, "Orphaned RLE code at start");
|
||||
goto error;
|
||||
}
|
||||
*out_data++ = RUNCHAR;
|
||||
} else {
|
||||
*out_data++ = in_byte;
|
||||
}
|
||||
|
||||
while( in_len > 0 ) {
|
||||
INBYTE(in_byte);
|
||||
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
/* only 1 byte will be written, but 2 bytes were preallocated:
|
||||
subtract 1 byte to prevent overallocation */
|
||||
writer.min_size--;
|
||||
|
||||
if ( in_repeat == 0 ) {
|
||||
/* Just an escaped RUNCHAR value */
|
||||
*out_data++ = RUNCHAR;
|
||||
} else {
|
||||
/* Pick up value and output a sequence of it */
|
||||
in_byte = out_data[-1];
|
||||
|
||||
/* enlarge the buffer if needed */
|
||||
if (in_repeat > 1) {
|
||||
/* -1 because we already preallocated 1 byte */
|
||||
out_data = _PyBytesWriter_Prepare(&writer, out_data,
|
||||
in_repeat - 1);
|
||||
if (out_data == NULL)
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ( --in_repeat > 0 )
|
||||
*out_data++ = in_byte;
|
||||
}
|
||||
} else {
|
||||
/* Normal byte */
|
||||
*out_data++ = in_byte;
|
||||
}
|
||||
}
|
||||
return _PyBytesWriter_Finish(&writer, out_data);
|
||||
|
||||
error:
|
||||
_PyBytesWriter_Dealloc(&writer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
binascii.crc_hqx
|
||||
|
@ -1629,14 +1215,10 @@ static struct PyMethodDef binascii_module_methods[] = {
|
|||
BINASCII_B2A_UU_METHODDEF
|
||||
BINASCII_A2B_BASE64_METHODDEF
|
||||
BINASCII_B2A_BASE64_METHODDEF
|
||||
BINASCII_A2B_HQX_METHODDEF
|
||||
BINASCII_B2A_HQX_METHODDEF
|
||||
BINASCII_A2B_HEX_METHODDEF
|
||||
BINASCII_B2A_HEX_METHODDEF
|
||||
BINASCII_HEXLIFY_METHODDEF
|
||||
BINASCII_UNHEXLIFY_METHODDEF
|
||||
BINASCII_RLECODE_HQX_METHODDEF
|
||||
BINASCII_RLEDECODE_HQX_METHODDEF
|
||||
BINASCII_CRC_HQX_METHODDEF
|
||||
BINASCII_CRC32_METHODDEF
|
||||
BINASCII_A2B_QP_METHODDEF
|
||||
|
|
141
Modules/clinic/binascii.c.h
generated
141
Modules/clinic/binascii.c.h
generated
|
@ -191,145 +191,6 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(binascii_a2b_hqx__doc__,
|
||||
"a2b_hqx($module, data, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Decode .hqx coding.");
|
||||
|
||||
#define BINASCII_A2B_HQX_METHODDEF \
|
||||
{"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_O, binascii_a2b_hqx__doc__},
|
||||
|
||||
static PyObject *
|
||||
binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data);
|
||||
|
||||
static PyObject *
|
||||
binascii_a2b_hqx(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
Py_buffer data = {NULL, NULL};
|
||||
|
||||
if (!ascii_buffer_converter(arg, &data)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = binascii_a2b_hqx_impl(module, &data);
|
||||
|
||||
exit:
|
||||
/* Cleanup for data */
|
||||
if (data.obj)
|
||||
PyBuffer_Release(&data);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(binascii_rlecode_hqx__doc__,
|
||||
"rlecode_hqx($module, data, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Binhex RLE-code binary data.");
|
||||
|
||||
#define BINASCII_RLECODE_HQX_METHODDEF \
|
||||
{"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_O, binascii_rlecode_hqx__doc__},
|
||||
|
||||
static PyObject *
|
||||
binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data);
|
||||
|
||||
static PyObject *
|
||||
binascii_rlecode_hqx(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
Py_buffer data = {NULL, NULL};
|
||||
|
||||
if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyBuffer_IsContiguous(&data, 'C')) {
|
||||
_PyArg_BadArgument("rlecode_hqx", "argument", "contiguous buffer", arg);
|
||||
goto exit;
|
||||
}
|
||||
return_value = binascii_rlecode_hqx_impl(module, &data);
|
||||
|
||||
exit:
|
||||
/* Cleanup for data */
|
||||
if (data.obj) {
|
||||
PyBuffer_Release(&data);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(binascii_b2a_hqx__doc__,
|
||||
"b2a_hqx($module, data, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Encode .hqx data.");
|
||||
|
||||
#define BINASCII_B2A_HQX_METHODDEF \
|
||||
{"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_O, binascii_b2a_hqx__doc__},
|
||||
|
||||
static PyObject *
|
||||
binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data);
|
||||
|
||||
static PyObject *
|
||||
binascii_b2a_hqx(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
Py_buffer data = {NULL, NULL};
|
||||
|
||||
if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyBuffer_IsContiguous(&data, 'C')) {
|
||||
_PyArg_BadArgument("b2a_hqx", "argument", "contiguous buffer", arg);
|
||||
goto exit;
|
||||
}
|
||||
return_value = binascii_b2a_hqx_impl(module, &data);
|
||||
|
||||
exit:
|
||||
/* Cleanup for data */
|
||||
if (data.obj) {
|
||||
PyBuffer_Release(&data);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(binascii_rledecode_hqx__doc__,
|
||||
"rledecode_hqx($module, data, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Decode hexbin RLE-coded string.");
|
||||
|
||||
#define BINASCII_RLEDECODE_HQX_METHODDEF \
|
||||
{"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_O, binascii_rledecode_hqx__doc__},
|
||||
|
||||
static PyObject *
|
||||
binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data);
|
||||
|
||||
static PyObject *
|
||||
binascii_rledecode_hqx(PyObject *module, PyObject *arg)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
Py_buffer data = {NULL, NULL};
|
||||
|
||||
if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyBuffer_IsContiguous(&data, 'C')) {
|
||||
_PyArg_BadArgument("rledecode_hqx", "argument", "contiguous buffer", arg);
|
||||
goto exit;
|
||||
}
|
||||
return_value = binascii_rledecode_hqx_impl(module, &data);
|
||||
|
||||
exit:
|
||||
/* Cleanup for data */
|
||||
if (data.obj) {
|
||||
PyBuffer_Release(&data);
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(binascii_crc_hqx__doc__,
|
||||
"crc_hqx($module, data, crc, /)\n"
|
||||
"--\n"
|
||||
|
@ -767,4 +628,4 @@ exit:
|
|||
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=0f261ee49971f5ca input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=4162d08536697182 input=a9049054013a1b77]*/
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
<Compile Include="asyncore.py" />
|
||||
<Compile Include="base64.py" />
|
||||
<Compile Include="bdb.py" />
|
||||
<Compile Include="binhex.py" />
|
||||
<Compile Include="bisect.py" />
|
||||
<Compile Include="bz2.py" />
|
||||
<Compile Include="calendar.py" />
|
||||
|
@ -894,7 +893,6 @@
|
|||
<Compile Include="test\test_bigaddrspace.py" />
|
||||
<Compile Include="test\test_bigmem.py" />
|
||||
<Compile Include="test\test_binascii.py" />
|
||||
<Compile Include="test\test_binhex.py" />
|
||||
<Compile Include="test\test_binop.py" />
|
||||
<Compile Include="test\test_bisect.py" />
|
||||
<Compile Include="test\test_bool.py" />
|
||||
|
|
|
@ -103,7 +103,6 @@ static const char* _Py_stdlib_module_names[] = {
|
|||
"base64",
|
||||
"bdb",
|
||||
"binascii",
|
||||
"binhex",
|
||||
"bisect",
|
||||
"builtins",
|
||||
"bz2",
|
||||
|
|
Loading…
Reference in a new issue