summaryrefslogtreecommitdiff
path: root/src/hash_template.c
diff options
context:
space:
mode:
authorThorsten Behrens <sbehrens@gmx.li>2010-12-28 16:26:52 -0500
committerThorsten Behrens <sbehrens@gmx.li>2010-12-28 16:26:52 -0500
commit295ce314d9f5c750d9569ac75a4f78331fae9992 (patch)
tree943c5f2e5237b3cf0665dd8fed278e4efa518770 /src/hash_template.c
parent1873473e13161587b870adadc70c1d625f8bc5cf (diff)
downloadpycrypto-295ce314d9f5c750d9569ac75a4f78331fae9992.tar.gz
Changes to allow pycrpyto to work on Python 3.x as well as 2.1 through 2.7
Diffstat (limited to 'src/hash_template.c')
-rw-r--r--src/hash_template.c141
1 files changed, 117 insertions, 24 deletions
diff --git a/src/hash_template.c b/src/hash_template.c
index 78e37be..7bb9139 100644
--- a/src/hash_template.c
+++ b/src/hash_template.c
@@ -30,12 +30,18 @@
#ifdef _HAVE_STDC_HEADERS
#include <string.h>
#endif
+#include "Python.h"
+#include "pycrypto_compat.h"
#define _STR(x) #x
#define _XSTR(x) _STR(x)
#define _PASTE(x,y) x##y
#define _PASTE2(x,y) _PASTE(x,y)
+#ifdef IS_PY3K
+#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME)
+#else
#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
+#endif
#define _MODULE_STRING _XSTR(MODULE_NAME)
typedef struct {
@@ -43,9 +49,17 @@ typedef struct {
hash_state st;
} ALGobject;
+/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C.
+ * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize
+ */
+#ifdef IS_PY3K
+static PyTypeObject ALGtype;
+#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype)
+#else
staticforward PyTypeObject ALGtype;
-
#define is_ALGobject(v) ((v)->ob_type == &ALGtype)
+#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */
+#endif
static ALGobject *
newALGobject(void)
@@ -117,22 +131,27 @@ ALG_hexdigest(ALGobject *self, PyObject *args)
/* Get the raw (binary) digest value */
value = (PyObject *)hash_digest(&(self->st));
- size = PyString_Size(value);
- raw_digest = (unsigned char *) PyString_AsString(value);
+ size = PyBytes_Size(value);
+ raw_digest = (unsigned char *) PyBytes_AsString(value);
/* Create a new string */
- retval = PyString_FromStringAndSize(NULL, size * 2 );
- hex_digest = (unsigned char *) PyString_AsString(retval);
+ retval = PyBytes_FromStringAndSize(NULL, size * 2 );
+ hex_digest = (unsigned char *) PyBytes_AsString(retval);
/* Make hex version of the digest */
- for(i=j=0; i<size; i++)
+ for(i=j=0; i<size; i++)
{
char c;
c = raw_digest[i] / 16; c = (c>9) ? c+'a'-10 : c + '0';
hex_digest[j++] = c;
c = raw_digest[i] % 16; c = (c>9) ? c+'a'-10 : c + '0';
hex_digest[j++] = c;
- }
+ }
+#ifdef IS_PY3K
+ /* Create a text string return value */
+ retval = PyUnicode_FromEncodedObject(retval,"latin-1","strict");
+#endif
+
Py_DECREF(value);
return retval;
}
@@ -150,47 +169,90 @@ ALG_update(ALGobject *self, PyObject *args)
return NULL;
Py_BEGIN_ALLOW_THREADS;
+
hash_update(&(self->st), cp, len);
Py_END_ALLOW_THREADS;
Py_INCREF(Py_None);
+
return Py_None;
}
static PyMethodDef ALG_methods[] = {
{"copy", (PyCFunction)ALG_copy, METH_VARARGS, ALG_copy__doc__},
{"digest", (PyCFunction)ALG_digest, METH_VARARGS, ALG_digest__doc__},
- {"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS,
- ALG_hexdigest__doc__},
+ {"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS, ALG_hexdigest__doc__},
{"update", (PyCFunction)ALG_update, METH_VARARGS, ALG_update__doc__},
{NULL, NULL} /* sentinel */
};
static PyObject *
+#ifdef IS_PY3K
+ALG_getattro(PyObject *self, PyObject *attr)
+#else
ALG_getattr(PyObject *self, char *name)
+#endif
{
+#ifdef IS_PY3K
+ if (!PyUnicode_Check(attr))
+ goto generic;
+
+ if (PyUnicode_CompareWithASCIIString(attr, "digest_size")==0)
+#else
if (strcmp(name, "digest_size")==0)
- return PyInt_FromLong(DIGEST_SIZE);
-
+#endif
+ return PyLong_FromLong(DIGEST_SIZE);
+
+#ifdef IS_PY3K
+ generic:
+ return PyObject_GenericGetAttr(self, attr);
+#else
return Py_FindMethod(ALG_methods, self, name);
+#endif
}
static PyTypeObject ALGtype = {
+#ifdef IS_PY3K
+ PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */
+#else
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
- _MODULE_STRING, /*tp_name*/
- sizeof(ALGobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- ALG_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
+#endif
+ _MODULE_STRING, /*tp_name*/
+ sizeof(ALGobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) ALG_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+#ifdef IS_PY3K
+ 0, /*tp_getattr*/
+#else
ALG_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
-};
-
+#endif
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+#ifdef IS_PY3K
+ 0, /*tp_as_sequence */
+ 0, /*tp_as_mapping */
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ ALG_getattro, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ ALG_methods, /*tp_methods*/
+#endif
+ };
/* The single module-level function: new() */
@@ -231,7 +293,6 @@ ALG_new(PyObject *self, PyObject *args)
return (PyObject *)new;
}
-
/* List of functions exported by this module */
static struct PyMethodDef ALG_functions[] = {
@@ -239,22 +300,51 @@ static struct PyMethodDef ALG_functions[] = {
{NULL, NULL} /* Sentinel */
};
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "Crypto.Hash." _MODULE_STRING,
+ NULL,
+ -1,
+ ALG_functions,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+#endif
/* Initialize this module. */
+/* Deal with old API in Python 2.1 */
#if PYTHON_API_VERSION < 1011
#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \
if (o!=NULL) \
{PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}}
#endif
+#ifdef IS_PY3K
+PyMODINIT_FUNC
+#else
void
+#endif
_MODULE_NAME (void)
{
PyObject *m;
+#ifdef IS_PY3K
+ /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */
+ if (PyType_Ready(&ALGtype) < 0)
+ return NULL;
+
+ /* Create the module and add the functions */
+ m = PyModule_Create(&moduledef);
+ if (m == NULL)
+ return NULL;
+#else
ALGtype.ob_type = &PyType_Type;
m = Py_InitModule("Crypto.Hash." _MODULE_STRING, ALG_functions);
+#endif
/* Add some symbolic constants to the module */
PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE);
@@ -263,4 +353,7 @@ _MODULE_NAME (void)
if (PyErr_Occurred())
Py_FatalError("can't initialize module "
_MODULE_STRING);
+#ifdef IS_PY3K
+ return m;
+#endif
}