/* * C implementation of the pyutil xor module. * * * Copyright (c) 2002 Faried Nawaz * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software to deal in this software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of this software, and to permit * persons to whom this software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of this software. * * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN * THIS SOFTWARE. * * Optimized and patched by Zooko, 2002-07-18 */ #include #include #define C_XOR_VERSION "1.1" static PyObject * c_xor_xor(PyObject *self, PyObject *args) { const unsigned char *str1, *str2; int len_str1, len_str2; PyObject * newstr; unsigned char *bytep; const unsigned char *endp; if (!PyArg_ParseTuple(args, "s#s#", &str1, &len_str1, &str2, &len_str2)) return NULL; if (len_str1 != len_str2) { /* XXX It would be nicer to raise an instance of type AssertionError here so that the behavior would be the same as xor.py_xor(). But people should not be catching assertion errors anyway. */ PyErr_SetString(PyExc_ValueError, "passed strings must be of the same length."); return NULL; } /* Calling PyString_FromStringAndSize with NULL first argument is a special call that asks PyString_FromStringAndSize to allocate the buffer for us, and appended the null terminating byte. */ newstr = PyString_FromStringAndSize(NULL, len_str1); if (newstr == NULL) return NULL; /* the Python/C API is that the function which returned NULL (PyString_FromStringAndSize) has already set the global PyErr value for us, so we just release any refcounts and return NULL. */ bytep = PyString_AS_STRING(newstr); assert (bytep != NULL); endp = PyString_AS_STRING(newstr) + len_str1; while (bytep < endp) *bytep++ = *str1++ ^ *str2++; return newstr; } static PyMethodDef XorMethods[] = { {"xor", c_xor_xor, METH_VARARGS, "Exclusive-Or on two strings."}, {NULL, NULL, 0, NULL} }; void initc_xor(void) { Py_InitModule("c_xor", XorMethods); } int main(int argc, char **argv) { Py_SetProgramName(argv[0]); Py_Initialize(); initc_xor(); return 0; }