[Python-checkins] CVS: python/dist/src/Modules binascii.c,2.23,2.24

Barry Warsaw python-dev@python.org
Mon, 14 Aug 2000 23:07:17 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory slayer.i.sourceforge.net:/tmp/cvs-serv2854

Modified Files:
	binascii.c 
Log Message:
After a brief conversation and code review with TP, adding two very
commonly used functions to convert an arbitrary binary string into
a hexadecimal digit representation and back again.  These are often
(and often differently) implemented in Python.  Best to have one
common fast implementation.  Specifically,

binascii_hexlify(): a.k.a. b2a_hex() to return the hex representation
of binary data.

binascii_unhexlify(): a.k.a. a2b_hex() to do the inverse conversion
(hex digits to binary data).  The argument must have an even length,
and must contain only hex digits, otherwise a TypeError is raised.


Index: binascii.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v
retrieving revision 2.23
retrieving revision 2.24
diff -C2 -r2.23 -r2.24
*** binascii.c	2000/08/03 02:06:15	2.23
--- binascii.c	2000/08/15 06:07:13	2.24
***************
*** 875,903 ****
  }
  
  /* 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},
! 	{"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},
! 	{NULL,			NULL}		/* sentinel */
  };
  
--- 875,1007 ----
  }
  
+ 
+ static PyObject *
+ binascii_hexlify(PyObject *self, PyObject *args)
+ {
+ 	char* argbuf;
+ 	int arglen;
+ 	PyObject *retval;
+ 	char* retbuf;
+ 	int i, j;
+ 
+ 	if (!PyArg_ParseTuple(args, "t#:b2a_hex", &argbuf, &arglen))
+ 		return NULL;
+ 
+ 	retval = PyString_FromStringAndSize(NULL, arglen*2);
+ 	if (!retval)
+ 		return NULL;
+ 	retbuf = PyString_AsString(retval);
+ 	if (!retbuf)
+ 		goto finally;
+ 
+ 	/* make hex version of string, taken from shamodule.c */
+ 	for (i=j=0; i < arglen; i++) {
+ 		char c;
+ 		c = (argbuf[i] >> 4) & 0xf;
+ 		c = (c>9) ? c+'a'-10 : c + '0';
+ 		retbuf[j++] = c;
+ 		c = argbuf[i] & 0xf;
+ 		c = (c>9) ? c+'a'-10 : c + '0';
+ 		retbuf[j++] = c;
+ 	}
+ 	return retval;
+ 
+   finally:
+ 	Py_DECREF(retval);
+ 	return NULL;
+ }
+ 
+ static char doc_hexlify[] =
+ "b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\
+ \n\
+ This function is also available as \"hexlify()\".";
+ 
+ 
+ static int
+ to_int(char c) 
+ {
+ 	if (isdigit(c))
+ 		return c - '0';
+ 	else {
+ 		if (isupper(c))
+ 			c = tolower(c);
+ 		if (c >= 'a' && c <= 'f')
+ 			return c - 'a' + 10;
+ 	}
+ 	return -1;
+ }
+ 
+ 
+ static PyObject *
+ binascii_unhexlify(PyObject *self, PyObject *args)
+ {
+ 	char* argbuf;
+ 	int arglen;
+ 	PyObject *retval;
+ 	char* retbuf;
+ 	int i, j;
+ 
+ 	if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
+ 		return NULL;
+ 
+ 	/* XXX What should we do about odd-lengthed strings?  Should we add
+ 	 * an implicit leading zero, or a trailing zero?  For now, raise an
+ 	 * exception.
+ 	 */
+ 	if (arglen % 2) {
+ 		PyErr_SetString(PyExc_TypeError, "odd lengthed string");
+ 		return NULL;
+ 	}
+ 
+ 	retval = PyString_FromStringAndSize(NULL, (arglen/2));
+ 	if (!retval)
+ 		return NULL;
+ 	retbuf = PyString_AsString(retval);
+ 	if (!retbuf)
+ 		goto finally;
+ 
+ 	for (i=j=0; i < arglen; i += 2) {
+ 		int top = to_int(Py_CHARMASK(argbuf[i]));
+ 		int bot = to_int(Py_CHARMASK(argbuf[i+1]));
+ 		if (top == -1 || bot == -1) {
+ 			PyErr_SetString(PyExc_TypeError,
+ 					"non-hexadecimal digit found");
+ 			goto finally;
+ 		}
+ 		retbuf[j++] = (top << 4) + bot;
+ 	}
+ 	return retval;
+ 
+   finally:
+ 	Py_DECREF(retval);
+ 	return NULL;
+ }
+ 
+ static char 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()\"";
+ 
+ 
  /* 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},
! 	{NULL, NULL}			     /* sentinel */
  };