summaryrefslogtreecommitdiffstats
path: root/Modules/binascii.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/binascii.c')
-rw-r--r--Modules/binascii.c686
1 files changed, 361 insertions, 325 deletions
diff --git a/Modules/binascii.c b/Modules/binascii.c
index 829bde8..c9309ce 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -183,6 +183,27 @@ static unsigned short crctab_hqx[256] = {
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
};
+/*[clinic input]
+output preset file
+module binascii
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=44c6f840ce708f0c]*/
+
+/*[python input]
+
+class ascii_buffer_converter(CConverter):
+ type = 'Py_buffer'
+ converter = 'ascii_buffer_converter'
+ impl_by_reference = True
+ c_default = "{NULL, NULL}"
+
+ def cleanup(self):
+ name = self.name
+ return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"])
+
+[python start generated code]*/
+/*[python end generated code: output=da39a3ee5e6b4b0d input=3eb7b63610da92cd]*/
+
static int
ascii_buffer_converter(PyObject *arg, Py_buffer *buf)
{
@@ -207,26 +228,34 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf)
if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError,
"argument should be bytes, buffer or ASCII string, "
- "not %R", Py_TYPE(arg));
+ "not '%.100s'", Py_TYPE(arg)->tp_name);
return 0;
}
if (!PyBuffer_IsContiguous(buf, 'C')) {
PyErr_Format(PyExc_TypeError,
"argument should be a contiguous buffer, "
- "not %R", Py_TYPE(arg));
+ "not '%.100s'", Py_TYPE(arg)->tp_name);
PyBuffer_Release(buf);
return 0;
}
return Py_CLEANUP_SUPPORTED;
}
+#include "clinic/binascii.c.h"
+
+/*[clinic input]
+binascii.a2b_uu
-PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data");
+ data: ascii_buffer
+ /
+
+Decode a line of uuencoded data.
+[clinic start generated code]*/
static PyObject *
-binascii_a2b_uu(PyObject *self, PyObject *args)
+binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=5779f39b0b48459f input=7cafeaf73df63d1c]*/
{
- Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -234,10 +263,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t ascii_len, bin_len;
- if ( !PyArg_ParseTuple(args, "O&:a2b_uu", ascii_buffer_converter, &pascii) )
- return NULL;
- ascii_data = pascii.buf;
- ascii_len = pascii.len;
+ ascii_data = data->buf;
+ ascii_len = data->len;
assert(ascii_len >= 0);
@@ -246,10 +273,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
ascii_len--;
/* Allocate the buffer */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
- PyBuffer_Release(&pascii);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
return NULL;
- }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) {
@@ -269,7 +294,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
*/
if ( this_ch < ' ' || this_ch > (' ' + 64)) {
PyErr_SetString(Error, "Illegal char");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -298,21 +322,26 @@ binascii_a2b_uu(PyObject *self, PyObject *args)
if ( this_ch != ' ' && this_ch != ' '+64 &&
this_ch != '\n' && this_ch != '\r' ) {
PyErr_SetString(Error, "Trailing garbage");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
}
- PyBuffer_Release(&pascii);
return rv;
}
-PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data");
+/*[clinic input]
+binascii.b2a_uu
+
+ data: Py_buffer
+ /
+
+Uuencode line of data.
+[clinic start generated code]*/
static PyObject *
-binascii_b2a_uu(PyObject *self, PyObject *args)
+binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=181021b69bb9a414 input=00fdf458ce8b465b]*/
{
- Py_buffer pbin;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -320,22 +349,17 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t bin_len;
- if ( !PyArg_ParseTuple(args, "y*:b2a_uu", &pbin) )
- return NULL;
- bin_data = pbin.buf;
- bin_len = pbin.len;
+ bin_data = data->buf;
+ bin_len = data->len;
if ( bin_len > 45 ) {
/* The 45 is a limit that appears in all uuencode's */
PyErr_SetString(Error, "At most 45 bytes at once");
- PyBuffer_Release(&pbin);
return NULL;
}
/* We're lazy and allocate to much (fixed up later) */
- if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) {
- PyBuffer_Release(&pbin);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL )
return NULL;
- }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
/* Store the length */
@@ -361,10 +385,8 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
if (_PyBytes_Resize(&rv,
(ascii_data -
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
- PyBuffer_Release(&pbin);
return rv;
}
@@ -394,12 +416,19 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num)
return ret;
}
-PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data");
+/*[clinic input]
+binascii.a2b_base64
+
+ data: ascii_buffer
+ /
+
+Decode a line of base64 data.
+[clinic start generated code]*/
static PyObject *
-binascii_a2b_base64(PyObject *self, PyObject *args)
+binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=3e351b702bed56d2 input=5872acf6e1cac243]*/
{
- Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -408,25 +437,19 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
Py_ssize_t ascii_len, bin_len;
int quad_pos = 0;
- if ( !PyArg_ParseTuple(args, "O&:a2b_base64", ascii_buffer_converter, &pascii) )
- return NULL;
- ascii_data = pascii.buf;
- ascii_len = pascii.len;
+ ascii_data = data->buf;
+ ascii_len = data->len;
assert(ascii_len >= 0);
- if (ascii_len > PY_SSIZE_T_MAX - 3) {
- PyBuffer_Release(&pascii);
+ if (ascii_len > PY_SSIZE_T_MAX - 3)
return PyErr_NoMemory();
- }
bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
/* Allocate the buffer */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) {
- PyBuffer_Release(&pascii);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL )
return NULL;
- }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
bin_len = 0;
@@ -479,7 +502,6 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
}
if (leftbits != 0) {
- PyBuffer_Release(&pascii);
PyErr_SetString(Error, "Incorrect padding");
Py_DECREF(rv);
return NULL;
@@ -491,24 +513,30 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
*/
if (bin_len > 0) {
if (_PyBytes_Resize(&rv, bin_len) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
}
else {
Py_DECREF(rv);
rv = PyBytes_FromStringAndSize("", 0);
}
- PyBuffer_Release(&pascii);
return rv;
}
-PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data");
+
+/*[clinic input]
+binascii.b2a_base64
+
+ data: Py_buffer
+ /
+
+Base64-code line of data.
+[clinic start generated code]*/
static PyObject *
-binascii_b2a_base64(PyObject *self, PyObject *args)
+binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=3cd61fbee2913285 input=14ec4e47371174a9]*/
{
- Py_buffer pbuf;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -516,26 +544,21 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t bin_len;
- if ( !PyArg_ParseTuple(args, "y*:b2a_base64", &pbuf) )
- return NULL;
- bin_data = pbuf.buf;
- bin_len = pbuf.len;
+ bin_data = data->buf;
+ bin_len = data->len;
assert(bin_len >= 0);
if ( bin_len > BASE64_MAXBIN ) {
PyErr_SetString(Error, "Too much data for base64 line");
- PyBuffer_Release(&pbuf);
return NULL;
}
/* We're lazy and allocate too much (fixed up later).
"+3" leaves room for up to two pad characters and a trailing
newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */
- if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) {
- PyBuffer_Release(&pbuf);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL )
return NULL;
- }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; bin_len > 0 ; bin_len--, bin_data++ ) {
@@ -563,19 +586,24 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
if (_PyBytes_Resize(&rv,
(ascii_data -
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
- PyBuffer_Release(&pbuf);
return rv;
}
-PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding");
+/*[clinic input]
+binascii.a2b_hqx
+
+ data: ascii_buffer
+ /
+
+Decode .hqx coding.
+[clinic start generated code]*/
static PyObject *
-binascii_a2b_hqx(PyObject *self, PyObject *args)
+binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=60bcdbbd28b105cd input=0d914c680e0eed55]*/
{
- Py_buffer pascii;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -584,25 +612,19 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
Py_ssize_t len;
int done = 0;
- if ( !PyArg_ParseTuple(args, "O&:a2b_hqx", ascii_buffer_converter, &pascii) )
- return NULL;
- ascii_data = pascii.buf;
- len = pascii.len;
+ ascii_data = data->buf;
+ len = data->len;
assert(len >= 0);
- if (len > PY_SSIZE_T_MAX - 2) {
- PyBuffer_Release(&pascii);
+ 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. */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) {
- PyBuffer_Release(&pascii);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL )
return NULL;
- }
bin_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; len > 0 ; len--, ascii_data++ ) {
@@ -612,7 +634,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
continue;
if ( this_ch == FAIL ) {
PyErr_SetString(Error, "Illegal char");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
@@ -635,55 +656,53 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
if ( leftbits && !done ) {
PyErr_SetString(Incomplete,
"String has incomplete number of bytes");
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return NULL;
}
if (_PyBytes_Resize(&rv,
(bin_data -
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
if (rv) {
PyObject *rrv = Py_BuildValue("Oi", rv, done);
- PyBuffer_Release(&pascii);
Py_DECREF(rv);
return rrv;
}
- PyBuffer_Release(&pascii);
return NULL;
}
-PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data");
+
+/*[clinic input]
+binascii.rlecode_hqx
+
+ data: Py_buffer
+ /
+
+Binhex RLE-code binary data.
+[clinic start generated code]*/
static PyObject *
-binascii_rlecode_hqx(PyObject *self, PyObject *args)
+binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=0905da344dbf0648 input=e1f1712447a82b09]*/
{
- Py_buffer pbuf;
unsigned char *in_data, *out_data;
PyObject *rv;
unsigned char ch;
Py_ssize_t in, inend, len;
- if ( !PyArg_ParseTuple(args, "y*:rlecode_hqx", &pbuf) )
- return NULL;
- in_data = pbuf.buf;
- len = pbuf.len;
+ in_data = data->buf;
+ len = data->len;
assert(len >= 0);
- if (len > PY_SSIZE_T_MAX / 2 - 2) {
- PyBuffer_Release(&pbuf);
+ if (len > PY_SSIZE_T_MAX / 2 - 2)
return PyErr_NoMemory();
- }
/* Worst case: output is twice as big as input (fixed later) */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) {
- PyBuffer_Release(&pbuf);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
return NULL;
- }
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( in=0; in<len; in++) {
@@ -713,19 +732,25 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
if (_PyBytes_Resize(&rv,
(out_data -
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
- PyBuffer_Release(&pbuf);
return rv;
}
-PyDoc_STRVAR(doc_b2a_hqx, "Encode .hqx data");
+
+/*[clinic input]
+binascii.b2a_hqx
+
+ data: Py_buffer
+ /
+
+Encode .hqx data.
+[clinic start generated code]*/
static PyObject *
-binascii_b2a_hqx(PyObject *self, PyObject *args)
+binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=5a987810d5e3cdbb input=9596ebe019fe12ba]*/
{
- Py_buffer pbin;
unsigned char *ascii_data, *bin_data;
int leftbits = 0;
unsigned char this_ch;
@@ -733,23 +758,17 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
PyObject *rv;
Py_ssize_t len;
- if ( !PyArg_ParseTuple(args, "y*:b2a_hqx", &pbin) )
- return NULL;
- bin_data = pbin.buf;
- len = pbin.len;
+ bin_data = data->buf;
+ len = data->len;
assert(len >= 0);
- if (len > PY_SSIZE_T_MAX / 2 - 2) {
- PyBuffer_Release(&pbin);
+ if (len > PY_SSIZE_T_MAX / 2 - 2)
return PyErr_NoMemory();
- }
/* Allocate a buffer that is at least large enough */
- if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) {
- PyBuffer_Release(&pbin);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
return NULL;
- }
ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);
for( ; len > 0 ; len--, bin_data++ ) {
@@ -770,47 +789,45 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
if (_PyBytes_Resize(&rv,
(ascii_data -
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
- PyBuffer_Release(&pbin);
return rv;
}
-PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string");
+
+/*[clinic input]
+binascii.rledecode_hqx
+
+ data: Py_buffer
+ /
+
+Decode hexbin RLE-coded string.
+[clinic start generated code]*/
static PyObject *
-binascii_rledecode_hqx(PyObject *self, PyObject *args)
+binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=f7afd89b789946ab input=54cdd49fc014402c]*/
{
- Py_buffer pin;
unsigned char *in_data, *out_data;
unsigned char in_byte, in_repeat;
PyObject *rv;
Py_ssize_t in_len, out_len, out_len_left;
- if ( !PyArg_ParseTuple(args, "y*:rledecode_hqx", &pin) )
- return NULL;
- in_data = pin.buf;
- in_len = pin.len;
+ in_data = data->buf;
+ in_len = data->len;
assert(in_len >= 0);
/* Empty string is a special case */
- if ( in_len == 0 ) {
- PyBuffer_Release(&pin);
+ if ( in_len == 0 )
return PyBytes_FromStringAndSize("", 0);
- }
- else if (in_len > PY_SSIZE_T_MAX / 2) {
- PyBuffer_Release(&pin);
+ else if (in_len > PY_SSIZE_T_MAX / 2)
return PyErr_NoMemory();
- }
/* Allocate a buffer of reasonable size. Resized when needed */
out_len = in_len*2;
- if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) {
- PyBuffer_Release(&pin);
+ if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL )
return NULL;
- }
out_len_left = out_len;
out_data = (unsigned char *)PyBytes_AS_STRING(rv);
@@ -823,7 +840,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --in_len < 0 ) { \
PyErr_SetString(Incomplete, ""); \
Py_DECREF(rv); \
- PyBuffer_Release(&pin); \
return NULL; \
} \
b = *in_data++; \
@@ -834,7 +850,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if ( --out_len_left < 0 ) { \
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
if (_PyBytes_Resize(&rv, 2*out_len) < 0) \
- { Py_DECREF(rv); PyBuffer_Release(&pin); return NULL; } \
+ { Py_XDECREF(rv); return NULL; } \
out_data = (unsigned char *)PyBytes_AS_STRING(rv) \
+ out_len; \
out_len_left = out_len-1; \
@@ -856,7 +872,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
** of the string only). This is a programmer error.
*/
PyErr_SetString(Error, "Orphaned RLE code at start");
- PyBuffer_Release(&pin);
Py_DECREF(rv);
return NULL;
}
@@ -887,60 +902,41 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
if (_PyBytes_Resize(&rv,
(out_data -
(unsigned char *)PyBytes_AS_STRING(rv))) < 0) {
- Py_DECREF(rv);
- rv = NULL;
+ Py_CLEAR(rv);
}
- PyBuffer_Release(&pin);
return rv;
}
-PyDoc_STRVAR(doc_crc_hqx,
-"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally");
-static PyObject *
-binascii_crc_hqx(PyObject *self, PyObject *args)
+/*[clinic input]
+binascii.crc_hqx -> unsigned_int
+
+ data: Py_buffer
+ crc: unsigned_int(bitwise=True)
+ /
+
+Compute hqx CRC incrementally.
+[clinic start generated code]*/
+
+static unsigned int
+binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)
+/*[clinic end generated code: output=167c2dac62625717 input=add8c53712ccceda]*/
{
- Py_buffer pin;
unsigned char *bin_data;
- unsigned int crc;
Py_ssize_t len;
- if ( !PyArg_ParseTuple(args, "y*i:crc_hqx", &pin, &crc) )
- return NULL;
- bin_data = pin.buf;
- len = pin.len;
+ crc &= 0xffff;
+ bin_data = data->buf;
+ len = data->len;
while(len-- > 0) {
- crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
+ crc = ((crc<<8)&0xff00) ^ crctab_hqx[(crc>>8)^*bin_data++];
}
- PyBuffer_Release(&pin);
- return Py_BuildValue("i", crc);
+ return crc;
}
-PyDoc_STRVAR(doc_crc32,
-"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally");
-
-#ifdef USE_ZLIB_CRC32
-/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */
-static PyObject *
-binascii_crc32(PyObject *self, PyObject *args)
-{
- unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */
- Py_buffer pbuf;
- Byte *buf;
- Py_ssize_t len;
- int signed_val;
-
- if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val))
- return NULL;
- buf = (Byte*)pbuf.buf;
- len = pbuf.len;
- signed_val = crc32(crc32val, buf, len);
- PyBuffer_Release(&pbuf);
- return PyLong_FromUnsignedLong(signed_val & 0xffffffffU);
-}
-#else /* USE_ZLIB_CRC32 */
+#ifndef USE_ZLIB_CRC32
/* Crc - 32 BIT ANSI X3.66 CRC checksum files
Also known as: ISO 3307
**********************************************************************|
@@ -1058,20 +1054,42 @@ static unsigned int crc_32_tab[256] = {
0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
0x2d02ef8dU
};
+#endif /* USE_ZLIB_CRC32 */
-static PyObject *
-binascii_crc32(PyObject *self, PyObject *args)
+/*[clinic input]
+binascii.crc32 -> unsigned_int
+
+ data: Py_buffer
+ crc: unsigned_int(bitwise=True) = 0
+ /
+
+Compute CRC-32 incrementally.
+[clinic start generated code]*/
+
+static unsigned int
+binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)
+/*[clinic end generated code: output=620a961643393c4f input=bbe340bc99d25aa8]*/
+
+#ifdef USE_ZLIB_CRC32
+/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */
+{
+ Byte *buf;
+ Py_ssize_t len;
+ int signed_val;
+
+ buf = (Byte*)data->buf;
+ len = data->len;
+ signed_val = crc32(crc, buf, len);
+ return (unsigned int)signed_val & 0xffffffffU;
+}
+#else /* USE_ZLIB_CRC32 */
{ /* By Jim Ahlstrom; All rights transferred to CNRI */
- Py_buffer pbin;
unsigned char *bin_data;
- unsigned int crc = 0; /* initial value of CRC */
Py_ssize_t len;
unsigned int result;
- if ( !PyArg_ParseTuple(args, "y*|I:crc32", &pbin, &crc) )
- return NULL;
- bin_data = pbin.buf;
- len = pbin.len;
+ bin_data = data->buf;
+ len = data->len;
crc = ~ crc;
while (len-- > 0) {
@@ -1080,38 +1098,42 @@ binascii_crc32(PyObject *self, PyObject *args)
}
result = (crc ^ 0xFFFFFFFF);
- PyBuffer_Release(&pbin);
- return PyLong_FromUnsignedLong(result & 0xffffffff);
+ return result & 0xffffffff;
}
#endif /* USE_ZLIB_CRC32 */
+/*[clinic input]
+binascii.b2a_hex
+
+ data: Py_buffer
+ /
+
+Hexadecimal representation of binary data.
+
+The return value is a bytes object. This function is also
+available as "hexlify()".
+[clinic start generated code]*/
static PyObject *
-binascii_hexlify(PyObject *self, PyObject *args)
+binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=179318922c2f8fda input=96423cfa299ff3b1]*/
{
- Py_buffer parg;
char* argbuf;
Py_ssize_t arglen;
PyObject *retval;
char* retbuf;
Py_ssize_t i, j;
- if (!PyArg_ParseTuple(args, "y*:b2a_hex", &parg))
- return NULL;
- argbuf = parg.buf;
- arglen = parg.len;
+ argbuf = data->buf;
+ arglen = data->len;
assert(arglen >= 0);
- if (arglen > PY_SSIZE_T_MAX / 2) {
- PyBuffer_Release(&parg);
+ if (arglen > PY_SSIZE_T_MAX / 2)
return PyErr_NoMemory();
- }
retval = PyBytes_FromStringAndSize(NULL, arglen*2);
- if (!retval) {
- PyBuffer_Release(&parg);
+ if (!retval)
return NULL;
- }
retbuf = PyBytes_AS_STRING(retval);
/* make hex version of string, taken from shamodule.c */
@@ -1122,16 +1144,23 @@ binascii_hexlify(PyObject *self, PyObject *args)
c = argbuf[i] & 0xf;
retbuf[j++] = Py_hexdigits[c];
}
- PyBuffer_Release(&parg);
return retval;
}
-PyDoc_STRVAR(doc_hexlify,
-"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\
-\n\
-The return value is a bytes object. This function is also\n\
-available as \"hexlify()\".");
+/*[clinic input]
+binascii.hexlify = binascii.b2a_hex
+Hexadecimal representation of binary data.
+
+The return value is a bytes object.
+[clinic start generated code]*/
+
+static PyObject *
+binascii_hexlify_impl(PyModuleDef *module, Py_buffer *data)
+/*[clinic end generated code: output=6098440091fb61dc input=2e3afae7f083f061]*/
+{
+ return binascii_b2a_hex_impl(module, data);
+}
static int
to_int(int c)
@@ -1148,20 +1177,30 @@ to_int(int c)
}
+/*[clinic input]
+binascii.a2b_hex
+
+ hexstr: ascii_buffer
+ /
+
+Binary data of hexadecimal representation.
+
+hexstr must contain an even number of hex digits (upper or lower case).
+This function is also available as "unhexlify()".
+[clinic start generated code]*/
+
static PyObject *
-binascii_unhexlify(PyObject *self, PyObject *args)
+binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr)
+/*[clinic end generated code: output=d61da452b5c6d290 input=9e1e7f2f94db24fd]*/
{
- Py_buffer parg;
char* argbuf;
Py_ssize_t arglen;
PyObject *retval;
char* retbuf;
Py_ssize_t i, j;
- if (!PyArg_ParseTuple(args, "O&:a2b_hex", ascii_buffer_converter, &parg))
- return NULL;
- argbuf = parg.buf;
- arglen = parg.len;
+ argbuf = hexstr->buf;
+ arglen = hexstr->len;
assert(arglen >= 0);
@@ -1170,16 +1209,13 @@ binascii_unhexlify(PyObject *self, PyObject *args)
* raise an exception.
*/
if (arglen % 2) {
- PyBuffer_Release(&parg);
PyErr_SetString(Error, "Odd-length string");
return NULL;
}
retval = PyBytes_FromStringAndSize(NULL, (arglen/2));
- if (!retval) {
- PyBuffer_Release(&parg);
+ if (!retval)
return NULL;
- }
retbuf = PyBytes_AS_STRING(retval);
for (i=j=0; i < arglen; i += 2) {
@@ -1192,20 +1228,27 @@ binascii_unhexlify(PyObject *self, PyObject *args)
}
retbuf[j++] = (top << 4) + bot;
}
- PyBuffer_Release(&parg);
return retval;
finally:
- PyBuffer_Release(&parg);
Py_DECREF(retval);
return NULL;
}
-PyDoc_STRVAR(doc_unhexlify,
-"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\
-\n\
-hexstr must contain an even number of hex digits (upper or lower case).\n\
-This function is also available as \"unhexlify()\"");
+/*[clinic input]
+binascii.unhexlify = binascii.a2b_hex
+
+Binary data of hexadecimal representation.
+
+hexstr must contain an even number of hex digits (upper or lower case).
+[clinic start generated code]*/
+
+static PyObject *
+binascii_unhexlify_impl(PyModuleDef *module, Py_buffer *hexstr)
+/*[clinic end generated code: output=17cec7544499803e input=dd8c012725f462da]*/
+{
+ return binascii_a2b_hex_impl(module, hexstr);
+}
static int table_hex[128] = {
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
@@ -1222,25 +1265,28 @@ static int table_hex[128] = {
#define MAXLINESIZE 76
-PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data");
-static PyObject*
-binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
+/*[clinic input]
+binascii.a2b_qp
+
+ data: ascii_buffer
+ header: int(c_default="0") = False
+
+Decode a string of qp-encoded data.
+[clinic start generated code]*/
+
+static PyObject *
+binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header)
+/*[clinic end generated code: output=a44ef88270352114 input=5187a0d3d8e54f3b]*/
{
Py_ssize_t in, out;
char ch;
- Py_buffer pdata;
- unsigned char *data, *odata;
+ unsigned char *ascii_data, *odata;
Py_ssize_t datalen = 0;
PyObject *rv;
- static char *kwlist[] = {"data", "header", NULL};
- int header = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", kwlist,
- ascii_buffer_converter, &pdata, &header))
- return NULL;
- data = pdata.buf;
- datalen = pdata.len;
+ ascii_data = data->buf;
+ datalen = data->len;
/* We allocate the output same size as input, this is overkill.
* The previous implementation used calloc() so we'll zero out the
@@ -1248,7 +1294,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
*/
odata = (unsigned char *) PyMem_Malloc(datalen);
if (odata == NULL) {
- PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1256,31 +1301,31 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
in = out = 0;
while (in < datalen) {
- if (data[in] == '=') {
+ if (ascii_data[in] == '=') {
in++;
if (in >= datalen) break;
/* Soft line breaks */
- if ((data[in] == '\n') || (data[in] == '\r')) {
- if (data[in] != '\n') {
- while (in < datalen && data[in] != '\n') in++;
+ if ((ascii_data[in] == '\n') || (ascii_data[in] == '\r')) {
+ if (ascii_data[in] != '\n') {
+ while (in < datalen && ascii_data[in] != '\n') in++;
}
if (in < datalen) in++;
}
- else if (data[in] == '=') {
+ else if (ascii_data[in] == '=') {
/* broken case from broken python qp */
odata[out++] = '=';
in++;
}
- else if (((data[in] >= 'A' && data[in] <= 'F') ||
- (data[in] >= 'a' && data[in] <= 'f') ||
- (data[in] >= '0' && data[in] <= '9')) &&
- ((data[in+1] >= 'A' && data[in+1] <= 'F') ||
- (data[in+1] >= 'a' && data[in+1] <= 'f') ||
- (data[in+1] >= '0' && data[in+1] <= '9'))) {
+ else if (((ascii_data[in] >= 'A' && ascii_data[in] <= 'F') ||
+ (ascii_data[in] >= 'a' && ascii_data[in] <= 'f') ||
+ (ascii_data[in] >= '0' && ascii_data[in] <= '9')) &&
+ ((ascii_data[in+1] >= 'A' && ascii_data[in+1] <= 'F') ||
+ (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') ||
+ (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) {
/* hexval */
- ch = hexval(data[in]) << 4;
+ ch = hexval(ascii_data[in]) << 4;
in++;
- ch |= hexval(data[in]);
+ ch |= hexval(ascii_data[in]);
in++;
odata[out++] = ch;
}
@@ -1288,22 +1333,20 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs)
odata[out++] = '=';
}
}
- else if (header && data[in] == '_') {
+ else if (header && ascii_data[in] == '_') {
odata[out++] = ' ';
in++;
}
else {
- odata[out] = data[in];
+ odata[out] = ascii_data[in];
in++;
out++;
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}
@@ -1319,63 +1362,63 @@ to_hex (unsigned char ch, unsigned char *s)
return 0;
}
-PyDoc_STRVAR(doc_b2a_qp,
-"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\
- Encode a string using quoted-printable encoding. \n\
-\n\
-On encoding, when istext is set, newlines are not encoded, and white \n\
-space at end of lines is. When istext is not set, \\r and \\n (CR/LF) are \n\
-both encoded. When quotetabs is set, space and tabs are encoded.");
-
/* XXX: This is ridiculously complicated to be backward compatible
* (mostly) with the quopri module. It doesn't re-create the quopri
* module bug where text ending in CRLF has the CR encoded */
-static PyObject*
-binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
+
+/*[clinic input]
+binascii.b2a_qp
+
+ data: Py_buffer
+ quotetabs: int(c_default="0") = False
+ istext: int(c_default="1") = True
+ header: int(c_default="0") = False
+
+Encode a string using quoted-printable encoding.
+
+On encoding, when istext is set, newlines are not encoded, and white
+space at end of lines is. When istext is not set, \r and \n (CR/LF)
+are both encoded. When quotetabs is set, space and tabs are encoded.
+[clinic start generated code]*/
+
+static PyObject *
+binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header)
+/*[clinic end generated code: output=ff2991ba640fff3e input=7f2a9aaa008e92b2]*/
{
Py_ssize_t in, out;
- Py_buffer pdata;
- unsigned char *data, *odata;
+ unsigned char *databuf, *odata;
Py_ssize_t datalen = 0, odatalen = 0;
PyObject *rv;
unsigned int linelen = 0;
- static char *kwlist[] = {"data", "quotetabs", "istext",
- "header", NULL};
- int istext = 1;
- int quotetabs = 0;
- int header = 0;
unsigned char ch;
int crlf = 0;
unsigned char *p;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii", kwlist, &pdata,
- &quotetabs, &istext, &header))
- return NULL;
- data = pdata.buf;
- datalen = pdata.len;
+ databuf = data->buf;
+ datalen = data->len;
/* See if this string is using CRLF line ends */
/* XXX: this function has the side effect of converting all of
* the end of lines to be the same depending on this detection
* here */
- p = (unsigned char *) memchr(data, '\n', datalen);
- if ((p != NULL) && (p > data) && (*(p-1) == '\r'))
+ p = (unsigned char *) memchr(databuf, '\n', datalen);
+ if ((p != NULL) && (p > databuf) && (*(p-1) == '\r'))
crlf = 1;
/* First, scan to see how many characters need to be encoded */
in = 0;
while (in < datalen) {
Py_ssize_t delta = 0;
- if ((data[in] > 126) ||
- (data[in] == '=') ||
- (header && data[in] == '_') ||
- ((data[in] == '.') && (linelen == 0) &&
- (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) ||
- (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
- ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
- ((data[in] < 33) &&
- (data[in] != '\r') && (data[in] != '\n') &&
- (quotetabs || ((data[in] != '\t') && (data[in] != ' ')))))
+ if ((databuf[in] > 126) ||
+ (databuf[in] == '=') ||
+ (header && databuf[in] == '_') ||
+ ((databuf[in] == '.') && (linelen == 0) &&
+ (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) ||
+ (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) ||
+ ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) ||
+ ((databuf[in] < 33) &&
+ (databuf[in] != '\r') && (databuf[in] != '\n') &&
+ (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' ')))))
{
if ((linelen + 3) >= MAXLINESIZE) {
linelen = 0;
@@ -1390,26 +1433,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
}
else {
if (istext &&
- ((data[in] == '\n') ||
- ((in+1 < datalen) && (data[in] == '\r') &&
- (data[in+1] == '\n'))))
+ ((databuf[in] == '\n') ||
+ ((in+1 < datalen) && (databuf[in] == '\r') &&
+ (databuf[in+1] == '\n'))))
{
linelen = 0;
/* Protect against whitespace on end of line */
- if (in && ((data[in-1] == ' ') || (data[in-1] == '\t')))
+ if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t')))
delta += 2;
if (crlf)
delta += 2;
else
delta += 1;
- if (data[in] == '\r')
+ if (databuf[in] == '\r')
in += 2;
else
in++;
}
else {
if ((in + 1 != datalen) &&
- (data[in+1] != '\n') &&
+ (databuf[in+1] != '\n') &&
(linelen + 1) >= MAXLINESIZE) {
linelen = 0;
if (crlf)
@@ -1423,7 +1466,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
}
}
if (PY_SSIZE_T_MAX - delta < odatalen) {
- PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1436,7 +1478,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
*/
odata = (unsigned char *) PyMem_Malloc(odatalen);
if (odata == NULL) {
- PyBuffer_Release(&pdata);
PyErr_NoMemory();
return NULL;
}
@@ -1444,17 +1485,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
in = out = linelen = 0;
while (in < datalen) {
- if ((data[in] > 126) ||
- (data[in] == '=') ||
- (header && data[in] == '_') ||
- ((data[in] == '.') && (linelen == 0) &&
- (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) ||
- (!istext && ((data[in] == '\r') || (data[in] == '\n'))) ||
- ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) ||
- ((data[in] < 33) &&
- (data[in] != '\r') && (data[in] != '\n') &&
+ if ((databuf[in] > 126) ||
+ (databuf[in] == '=') ||
+ (header && databuf[in] == '_') ||
+ ((databuf[in] == '.') && (linelen == 0) &&
+ (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) ||
+ (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) ||
+ ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) ||
+ ((databuf[in] < 33) &&
+ (databuf[in] != '\r') && (databuf[in] != '\n') &&
(quotetabs ||
- (!quotetabs && ((data[in] != '\t') && (data[in] != ' '))))))
+ (!quotetabs && ((databuf[in] != '\t') && (databuf[in] != ' '))))))
{
if ((linelen + 3 )>= MAXLINESIZE) {
odata[out++] = '=';
@@ -1463,16 +1504,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
linelen = 0;
}
odata[out++] = '=';
- to_hex(data[in], &odata[out]);
+ to_hex(databuf[in], &odata[out]);
out += 2;
in++;
linelen += 3;
}
else {
if (istext &&
- ((data[in] == '\n') ||
- ((in+1 < datalen) && (data[in] == '\r') &&
- (data[in+1] == '\n'))))
+ ((databuf[in] == '\n') ||
+ ((in+1 < datalen) && (databuf[in] == '\r') &&
+ (databuf[in+1] == '\n'))))
{
linelen = 0;
/* Protect against whitespace on end of line */
@@ -1485,14 +1526,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
if (crlf) odata[out++] = '\r';
odata[out++] = '\n';
- if (data[in] == '\r')
+ if (databuf[in] == '\r')
in += 2;
else
in++;
}
else {
if ((in + 1 != datalen) &&
- (data[in+1] != '\n') &&
+ (databuf[in+1] != '\n') &&
(linelen + 1) >= MAXLINESIZE) {
odata[out++] = '=';
if (crlf) odata[out++] = '\r';
@@ -1500,22 +1541,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
linelen = 0;
}
linelen++;
- if (header && data[in] == ' ') {
+ if (header && databuf[in] == ' ') {
odata[out++] = '_';
in++;
}
else {
- odata[out++] = data[in++];
+ odata[out++] = databuf[in++];
}
}
}
}
if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) {
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return NULL;
}
- PyBuffer_Release(&pdata);
PyMem_Free(odata);
return rv;
}
@@ -1523,25 +1562,22 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs)
/* List of functions defined in the module */
static struct PyMethodDef binascii_module_methods[] = {
- {"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu},
- {"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu},
- {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64},
- {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64},
- {"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx},
- {"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx},
- {"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify},
- {"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify},
- {"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify},
- {"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify},
- {"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx},
- {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS,
- doc_rledecode_hqx},
- {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx},
- {"crc32", binascii_crc32, METH_VARARGS, doc_crc32},
- {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS,
- doc_a2b_qp},
- {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS,
- doc_b2a_qp},
+ BINASCII_A2B_UU_METHODDEF
+ 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
+ BINASCII_B2A_QP_METHODDEF
{NULL, NULL} /* sentinel */
};