diff -r e634b377d5cc Modules/binascii.c --- a/Modules/binascii.c Tue Jan 07 14:25:26 2014 -0800 +++ b/Modules/binascii.c Wed Jan 08 01:44:23 2014 +0200 @@ -183,6 +183,21 @@ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, }; +/*[clinic input] +module binascii +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +/*[python input] + +class ascii_buffer_converter(CConverter): + type = 'Py_buffer' + converter = 'ascii_buffer_converter' + impl_by_reference = True + +[python start generated code]*/ +/*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + static int ascii_buffer_converter(PyObject *arg, Py_buffer *buf) { @@ -221,12 +236,45 @@ } -PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data"); +/*[clinic input] +binascii.a2b_uu + + ascii: ascii_buffer + / + +Decode a line of uuencoded data +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_a2b_uu__doc__, +"a2b_uu(ascii)\n" +"Decode a line of uuencoded data"); + +#define BINASCII_A2B_UU_METHODDEF \ + {"a2b_uu", (PyCFunction)binascii_a2b_uu, METH_VARARGS, binascii_a2b_uu__doc__}, static PyObject * -binascii_a2b_uu(PyObject *self, PyObject *args) +binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *ascii); + +static PyObject * +binascii_a2b_uu(PyModuleDef *module, PyObject *args) { - Py_buffer pascii; + PyObject *return_value = NULL; + Py_buffer ascii; + + if (!PyArg_ParseTuple(args, + "O&:a2b_uu", + ascii_buffer_converter, &ascii)) + goto exit; + return_value = binascii_a2b_uu_impl(module, &ascii); + +exit: + return return_value; +} + +static PyObject * +binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *ascii) +/*[clinic end generated code: checksum=88fac2b6dea9cd39861c6603ac488c5140f279dd]*/ +{ unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -234,10 +282,8 @@ 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 = ascii->buf; + ascii_len = ascii->len; assert(ascii_len >= 0); @@ -246,10 +292,8 @@ 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 +313,6 @@ */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -298,21 +341,56 @@ 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]*/ + +PyDoc_STRVAR(binascii_b2a_uu__doc__, +"b2a_uu(data)\n" +"Uuencode line of data"); + +#define BINASCII_B2A_UU_METHODDEF \ + {"b2a_uu", (PyCFunction)binascii_b2a_uu, METH_VARARGS, binascii_b2a_uu__doc__}, static PyObject * -binascii_b2a_uu(PyObject *self, PyObject *args) +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_uu(PyModuleDef *module, PyObject *args) { - Py_buffer pbin; + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_uu", + &data)) + goto exit; + return_value = binascii_b2a_uu_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: checksum=db1b74e3a7a72442cdc71bd77dd5ef686dc273eb]*/ +{ unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -320,22 +398,17 @@ 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 */ @@ -363,7 +436,6 @@ (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pbin); return rv; } @@ -393,12 +465,45 @@ return ret; } -PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data"); +/*[clinic input] +binascii.a2b_base64 + + ascii: ascii_buffer + / + +Decode a line of base64 data +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_a2b_base64__doc__, +"a2b_base64(ascii)\n" +"Decode a line of base64 data"); + +#define BINASCII_A2B_BASE64_METHODDEF \ + {"a2b_base64", (PyCFunction)binascii_a2b_base64, METH_VARARGS, binascii_a2b_base64__doc__}, static PyObject * -binascii_a2b_base64(PyObject *self, PyObject *args) +binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *ascii); + +static PyObject * +binascii_a2b_base64(PyModuleDef *module, PyObject *args) { - Py_buffer pascii; + PyObject *return_value = NULL; + Py_buffer ascii; + + if (!PyArg_ParseTuple(args, + "O&:a2b_base64", + ascii_buffer_converter, &ascii)) + goto exit; + return_value = binascii_a2b_base64_impl(module, &ascii); + +exit: + return return_value; +} + +static PyObject * +binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *ascii) +/*[clinic end generated code: checksum=9a30008c0d5b10f89ca5284008aa4da41616cc59]*/ +{ unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -407,25 +512,19 @@ 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 = ascii->buf; + ascii_len = ascii->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; @@ -478,7 +577,6 @@ } if (leftbits != 0) { - PyBuffer_Release(&pascii); PyErr_SetString(Error, "Incorrect padding"); Py_DECREF(rv); return NULL; @@ -497,16 +595,53 @@ 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]*/ + +PyDoc_STRVAR(binascii_b2a_base64__doc__, +"b2a_base64(data)\n" +"Base64-code line of data"); + +#define BINASCII_B2A_BASE64_METHODDEF \ + {"b2a_base64", (PyCFunction)binascii_b2a_base64, METH_VARARGS, binascii_b2a_base64__doc__}, static PyObject * -binascii_b2a_base64(PyObject *self, PyObject *args) +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_base64(PyModuleDef *module, PyObject *args) { - Py_buffer pbuf; + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_base64", + &data)) + goto exit; + return_value = binascii_b2a_base64_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: checksum=1584cb9ec7434bdd8e6269bc6afb7ecf3332d5b6]*/ +{ unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -514,26 +649,21 @@ 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,16 +693,48 @@ (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pbuf); return rv; } -PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding"); +/*[clinic input] +binascii.a2b_hqx + + ascii: ascii_buffer + / + +Decode .hqx coding +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_a2b_hqx__doc__, +"a2b_hqx(ascii)\n" +"Decode .hqx coding"); + +#define BINASCII_A2B_HQX_METHODDEF \ + {"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_VARARGS, binascii_a2b_hqx__doc__}, static PyObject * -binascii_a2b_hqx(PyObject *self, PyObject *args) +binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *ascii); + +static PyObject * +binascii_a2b_hqx(PyModuleDef *module, PyObject *args) { - Py_buffer pascii; + PyObject *return_value = NULL; + Py_buffer ascii; + + if (!PyArg_ParseTuple(args, + "O&:a2b_hqx", + ascii_buffer_converter, &ascii)) + goto exit; + return_value = binascii_a2b_hqx_impl(module, &ascii); + +exit: + return return_value; +} + +static PyObject * +binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *ascii) +/*[clinic end generated code: checksum=d07cf8f22deb837ebb1910860d14e77962978c59]*/ +{ unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -581,25 +743,19 @@ 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 = ascii->buf; + len = ascii->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++ ) { @@ -609,7 +765,6 @@ continue; if ( this_ch == FAIL ) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -632,7 +787,6 @@ if ( leftbits && !done ) { PyErr_SetString(Incomplete, "String has incomplete number of bytes"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -643,43 +797,73 @@ } 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]*/ + +PyDoc_STRVAR(binascii_rlecode_hqx__doc__, +"rlecode_hqx(data)\n" +"Binhex RLE-code binary data"); + +#define BINASCII_RLECODE_HQX_METHODDEF \ + {"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_VARARGS, binascii_rlecode_hqx__doc__}, static PyObject * -binascii_rlecode_hqx(PyObject *self, PyObject *args) +binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_rlecode_hqx(PyModuleDef *module, PyObject *args) { - Py_buffer pbuf; + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:rlecode_hqx", + &data)) + goto exit; + return_value = binascii_rlecode_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: checksum=f115a43cd67a4ab65ea8b6c8923b8bd51579ee17]*/ +{ 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; inbuf; + 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++ ) { @@ -767,44 +982,73 @@ (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { 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]*/ + +PyDoc_STRVAR(binascii_rledecode_hqx__doc__, +"rledecode_hqx(data)\n" +"Decode hexbin RLE-coded string"); + +#define BINASCII_RLEDECODE_HQX_METHODDEF \ + {"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_VARARGS, binascii_rledecode_hqx__doc__}, static PyObject * -binascii_rledecode_hqx(PyObject *self, PyObject *args) +binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_rledecode_hqx(PyModuleDef *module, PyObject *args) { - Py_buffer pin; + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:rledecode_hqx", + &data)) + goto exit; + return_value = binascii_rledecode_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: checksum=abe8342ef6138aaa2ab6bc8af39211c30546f9f9]*/ +{ 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); @@ -817,7 +1061,6 @@ if ( --in_len < 0 ) { \ PyErr_SetString(Incomplete, ""); \ Py_DECREF(rv); \ - PyBuffer_Release(&pin); \ return NULL; \ } \ b = *in_data++; \ @@ -828,7 +1071,7 @@ 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_XDECREF(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; \ @@ -850,7 +1093,6 @@ ** 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; } @@ -883,57 +1125,69 @@ (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pin); return rv; } -PyDoc_STRVAR(doc_crc_hqx, -"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally"); + +/*[clinic input] +binascii.crc_hqx + + data: Py_buffer + crc: unsigned_int(bitwise=True) + / + +Compute hqx CRC incrementally +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_crc_hqx__doc__, +"crc_hqx(data, crc)\n" +"Compute hqx CRC incrementally"); + +#define BINASCII_CRC_HQX_METHODDEF \ + {"crc_hqx", (PyCFunction)binascii_crc_hqx, METH_VARARGS, binascii_crc_hqx__doc__}, static PyObject * -binascii_crc_hqx(PyObject *self, PyObject *args) +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc_hqx(PyModuleDef *module, PyObject *args) { - Py_buffer pin; + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + unsigned int crc; + + if (!PyArg_ParseTuple(args, + "y*I:crc_hqx", + &data, &crc)) + goto exit; + return_value = binascii_crc_hqx_impl(module, &data, crc); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: checksum=76227b36f7be835e864f7061611d9d2f1e5551b2]*/ +{ 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; + bin_data = data->buf; + len = data->len; while(len-- > 0) { crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++]; } - PyBuffer_Release(&pin); return Py_BuildValue("i", 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 **********************************************************************| @@ -1051,20 +1305,73 @@ 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; +#endif /* USE_ZLIB_CRC32 */ + +/*[clinic input] +binascii.crc32 + + data: Py_buffer + crc: unsigned_int(bitwise=True) = 0 + / + +Compute CRC-32 incrementally +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_crc32__doc__, +"crc32(data, crc=0)\n" +"Compute CRC-32 incrementally"); + +#define BINASCII_CRC32_METHODDEF \ + {"crc32", (PyCFunction)binascii_crc32, METH_VARARGS, binascii_crc32__doc__}, static PyObject * -binascii_crc32(PyObject *self, PyObject *args) +binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + unsigned int crc = 0; + + if (!PyArg_ParseTuple(args, + "y*|I:crc32", + &data, &crc)) + goto exit; + return_value = binascii_crc32_impl(module, &data, crc); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: checksum=cd0ced8d55a1d9d7ae87532c44bf84810b6715e0]*/ + +#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 PyLong_FromUnsignedLong(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) { @@ -1073,38 +1380,75 @@ } result = (crc ^ 0xFFFFFFFF); - PyBuffer_Release(&pbin); return PyLong_FromUnsignedLong(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]*/ + +PyDoc_STRVAR(binascii_b2a_hex__doc__, +"b2a_hex(data)\n" +"Hexadecimal representation of binary data.\n" +"\n" +"The return value is a bytes object. This function is also\n" +"available as \"hexlify()\"."); + +#define BINASCII_B2A_HEX_METHODDEF \ + {"b2a_hex", (PyCFunction)binascii_b2a_hex, METH_VARARGS, binascii_b2a_hex__doc__}, static PyObject * -binascii_hexlify(PyObject *self, PyObject *args) +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_hex(PyModuleDef *module, PyObject *args) { - Py_buffer parg; + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_hex", + &data)) + goto exit; + return_value = binascii_b2a_hex_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: checksum=8b977e106d8970450a3844622685194f78d536db]*/ +{ 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 */ @@ -1115,16 +1459,9 @@ 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()\"."); - static int to_int(int c) @@ -1141,20 +1478,59 @@ } +/*[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]*/ + +PyDoc_STRVAR(binascii_a2b_hex__doc__, +"a2b_hex(hexstr)\n" +"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()\"."); + +#define BINASCII_A2B_HEX_METHODDEF \ + {"a2b_hex", (PyCFunction)binascii_a2b_hex, METH_VARARGS, binascii_a2b_hex__doc__}, + static PyObject * -binascii_unhexlify(PyObject *self, PyObject *args) +binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr); + +static PyObject * +binascii_a2b_hex(PyModuleDef *module, PyObject *args) { - Py_buffer parg; + PyObject *return_value = NULL; + Py_buffer hexstr; + + if (!PyArg_ParseTuple(args, + "O&:a2b_hex", + ascii_buffer_converter, &hexstr)) + goto exit; + return_value = binascii_a2b_hex_impl(module, &hexstr); + +exit: + return return_value; +} + +static PyObject * +binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: checksum=c4b254b6dd4b2020fbb666e667692839b613cc86]*/ +{ 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); @@ -1163,16 +1539,13 @@ * 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) { @@ -1185,21 +1558,13 @@ } 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()\""); - static int table_hex[128] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -1215,25 +1580,56 @@ #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 + + ascii: ascii_buffer + header: int = 0 + / + +Decode a string of qp-encoded data +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_a2b_qp__doc__, +"a2b_qp(ascii, header=0)\n" +"Decode a string of qp-encoded data"); + +#define BINASCII_A2B_QP_METHODDEF \ + {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS, binascii_a2b_qp__doc__}, + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *ascii, int header); + +static PyObject * +binascii_a2b_qp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer ascii; + int header = 0; + + if (!PyArg_ParseTuple(args, + "O&|i:a2b_qp", + ascii_buffer_converter, &ascii, &header)) + goto exit; + return_value = binascii_a2b_qp_impl(module, &ascii, header); + +exit: + return return_value; +} + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *ascii, int header) +/*[clinic end generated code: checksum=86e18f31addcf5cc93687bf1281d0a58f11e548b]*/ { Py_ssize_t in, out; char ch; - Py_buffer pdata; unsigned char *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; + data = ascii->buf; + datalen = ascii->len; /* We allocate the output same size as input, this is overkill. * The previous implementation used calloc() so we'll zero out the @@ -1241,7 +1637,6 @@ */ odata = (unsigned char *) PyMem_Malloc(datalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1292,11 +1687,9 @@ } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1312,62 +1705,100 @@ 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 = 0 + istext: int = 1 + header: int = 0 + +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]*/ + +PyDoc_STRVAR(binascii_b2a_qp__doc__, +"b2a_qp(data, quotetabs=0, istext=1, header=0)\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."); + +#define BINASCII_B2A_QP_METHODDEF \ + {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS|METH_KEYWORDS, binascii_b2a_qp__doc__}, + +static PyObject * +binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header); + +static PyObject * +binascii_b2a_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "quotetabs", "istext", "header", NULL}; + Py_buffer data = {NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}; + int quotetabs = 0; + int istext = 1; + int header = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "y*|iii:b2a_qp", _keywords, + &data, "etabs, &istext, &header)) + goto exit; + return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header); + +exit: + /* Cleanup for data */ + if (data.buf) + PyBuffer_Release(&data); + + return return_value; +} + +static PyObject * +binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header) +/*[clinic end generated code: checksum=b0dd0e90d309c80a4f114d7dd9b7719212c721c4]*/ { 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, - "etabs, &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) { - 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; @@ -1382,26 +1813,26 @@ } 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'))) odatalen += 2; if (crlf) odatalen += 2; else odatalen += 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) @@ -1422,7 +1853,6 @@ */ odata = (unsigned char *) PyMem_Malloc(odatalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1430,17 +1860,17 @@ 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++] = '='; @@ -1449,16 +1879,16 @@ 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 */ @@ -1471,14 +1901,14 @@ 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'; @@ -1486,22 +1916,20 @@ 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; } @@ -1509,25 +1937,22 @@ /* 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 + {"unhexlify", (PyCFunction)binascii_a2b_hex, METH_VARARGS, binascii_a2b_hex__doc__}, + {"hexlify", (PyCFunction)binascii_b2a_hex, METH_VARARGS, binascii_b2a_hex__doc__}, + 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 */ };