diff options
author | Thorsten Behrens <sbehrens@gmx.li> | 2010-12-28 16:26:52 -0500 |
---|---|---|
committer | Thorsten Behrens <sbehrens@gmx.li> | 2010-12-28 16:26:52 -0500 |
commit | 295ce314d9f5c750d9569ac75a4f78331fae9992 (patch) | |
tree | 943c5f2e5237b3cf0665dd8fed278e4efa518770 /src/hash_template.c | |
parent | 1873473e13161587b870adadc70c1d625f8bc5cf (diff) | |
download | pycrypto-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.c | 141 |
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 } |