]> granicus.if.org Git - python/commitdiff
Have the binascii module use zlib's optimized crc32() function when available
authorGregory P. Smith <greg@mad-scientist.com>
Mon, 24 Mar 2008 00:08:01 +0000 (00:08 +0000)
committerGregory P. Smith <greg@mad-scientist.com>
Mon, 24 Mar 2008 00:08:01 +0000 (00:08 +0000)
to reduce our code size (1k data table and tiny bit of code).  It falls back
to its own without zlib.

Modules/binascii.c
setup.py

index 659e08ce5c6cbf48b52ef829102ae2f44e405901..dfc3b7a5c96badd340a4007e87a317a96a27f420 100644 (file)
@@ -56,6 +56,9 @@
 #define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
+#ifdef USE_ZLIB_CRC32
+#include "zlib.h"
+#endif
 
 static PyObject *Error;
 static PyObject *Incomplete;
@@ -748,6 +751,26 @@ binascii_crc_hqx(PyObject *self, PyObject *args)
 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)
+{
+    uLong crc32val = 0;  /* crc32(0L, Z_NULL, 0) */
+    Byte *buf;
+    Py_ssize_t len;
+    int signed_val;
+
+    if (!PyArg_ParseTuple(args, "s#|k:crc32", &buf, &len, &crc32val))
+       return NULL;
+    /* In Python 2.x we return a signed integer regardless of native platform
+     * long size (the 32bit unsigned long is treated as 32-bit signed and sign
+     * extended into a 64-bit long inside the integer object).  3.0 does the
+     * right thing and returns unsigned. http://bugs.python.org/issue1202 */
+    signed_val = crc32(crc32val, buf, len);
+    return PyInt_FromLong(signed_val);
+}
+#else  /* USE_ZLIB_CRC32 */
 /*  Crc - 32 BIT ANSI X3.66 CRC checksum files
     Also known as: ISO 3307
 **********************************************************************|
@@ -898,6 +921,7 @@ binascii_crc32(PyObject *self, PyObject *args)
 #endif
        return PyInt_FromLong(result);
 }
+#endif  /* USE_ZLIB_CRC32 */
 
 
 static PyObject *
index c28d83999024f8659e7ade3ea23dfa4fc0afaaa1..20a3e9be460d57ee4eea8f7d03511a3ea80f6c39 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -486,9 +486,6 @@ class PyBuildExt(build_ext):
         # select(2); not on ancient System V
         exts.append( Extension('select', ['selectmodule.c']) )
 
-        # Helper module for various ascii-encoders
-        exts.append( Extension('binascii', ['binascii.c']) )
-
         # Fred Drake's interface to the Python parser
         exts.append( Extension('parser', ['parsermodule.c']) )
 
@@ -1069,6 +1066,7 @@ class PyBuildExt(build_ext):
         # You can upgrade zlib to version 1.1.4 yourself by going to
         # http://www.gzip.org/zlib/
         zlib_inc = find_file('zlib.h', [], inc_dirs)
+        have_zlib = False
         if zlib_inc is not None:
             zlib_h = zlib_inc[0] + '/zlib.h'
             version = '"0.0.0"'
@@ -1090,6 +1088,7 @@ class PyBuildExt(build_ext):
                     exts.append( Extension('zlib', ['zlibmodule.c'],
                                            libraries = ['z'],
                                            extra_link_args = zlib_extra_link_args))
+                    have_zlib = True
                 else:
                     missing.append('zlib')
             else:
@@ -1097,6 +1096,21 @@ class PyBuildExt(build_ext):
         else:
             missing.append('zlib')
 
+        # Helper module for various ascii-encoders.  Uses zlib for an optimized
+        # crc32 if we have it.  Otherwise binascii uses its own.
+        if have_zlib:
+            extra_compile_args = ['-DUSE_ZLIB_CRC32']
+            libraries = ['z']
+            extra_link_args = zlib_extra_link_args
+        else:
+            extra_compile_args = []
+            libraries = []
+            extra_link_args = []
+        exts.append( Extension('binascii', ['binascii.c'],
+                               extra_compile_args = extra_compile_args,
+                               libraries = libraries,
+                               extra_link_args = extra_link_args) )
+
         # Gustavo Niemeyer's bz2 module.
         if (self.compiler.find_library_file(lib_dirs, 'bz2')):
             if sys.platform == "darwin":