cython module
authorHelmut Grohne <helmut@subdivi.de>
Sun, 24 Mar 2013 20:11:07 +0000 (21:11 +0100)
committerHelmut Grohne <helmut@subdivi.de>
Sun, 24 Mar 2013 20:11:07 +0000 (21:11 +0100)
Finally a Python interface in the spirit of hashlib.

pyfuzzy.pyx [new file with mode: 0644]
setup.py [new file with mode: 0755]

diff --git a/pyfuzzy.pyx b/pyfuzzy.pyx
new file mode 100644 (file)
index 0000000..2a18786
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright (C) 2013 Helmut Grohne <helmut@subdivi.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+cimport libc.errno
+import errno
+import os
+
+cdef extern from "fuzzy.h":
+    struct fuzzy_state
+    cdef enum:
+        FUZZY_MAX_RESULT
+    cdef extern fuzzy_state *fuzzy_new() nogil
+    cdef extern int fuzzy_update(fuzzy_state *, unsigned char *, size_t) nogil
+    cdef extern int fuzzy_digest(fuzzy_state *, char *) nogil
+    cdef extern void fuzzy_free(fuzzy_state *) nogil
+
+class FuzzyError(Exception):
+    def __init__(self, errno):
+        self.errno = errno
+
+    def __str__(self):
+        return "FuzzyError: %s" % os.strerror(self.errno)
+
+    def __repr__(self):
+        try:
+            return "FuzzyError(errno.%s)" % errno.errorcode[self.errno]
+        except KeyError:
+            return "FuzzyError(%d)" % self.errno
+
+cdef class FuzzyHash:
+    cdef fuzzy_state *state
+
+    def __cinit__(self):
+        self.state = fuzzy_new()
+        if self.state == NULL:
+            raise FuzzyError(libc.errno.errno)
+
+    def update(self, bytes buff):
+        if self.state == NULL:
+            raise FuzzyError(libc.errno.EINVAL)
+        if fuzzy_update(self.state, buff, len(buff)) != 0:
+            fuzzy_free(self.state)
+            self.state = NULL
+            raise FuzzyError(libc.errno.errno)
+
+    def digest(self):
+        if self.state == NULL:
+            raise FuzzyError(libc.errno.EINVAL)
+        cdef char result[FUZZY_MAX_RESULT]
+        if fuzzy_digest(self.state, result) != 0:
+            raise FuzzyError(libc.errno.errno)
+        return str(result)
+
+    def __dealloc__(self):
+        if self.state != NULL:
+            fuzzy_free(self.state)
diff --git a/setup.py b/setup.py
new file mode 100755 (executable)
index 0000000..312c181
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+from distutils.extension import Extension
+from Cython.Distutils import build_ext
+
+sourcefiles = ['pyfuzzy.pyx', 'fuzzy.c']
+
+setup(
+        cmdclass = {'build_ext': build_ext},
+        ext_modules = [Extension("pyfuzzy", sourcefiles)]
+)