LZO decompression utility method on Windows using ctypes for dummies

Kim Hansen <[email protected]>
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>
Hi ctypes-list,

(Sorry if this is a double post, I posted first from an alternate account
(unintentionally), but I could not see my question popping up on the forum).

I would like to implement a
def lzo_decompress(bytestr):
    ....
    return decompressed_bytestr


utility method in a Python module for use in a project using Python 2.5.4 on
a Win XP 32-bit system.

I think I have assembled the pieces for the puzzle, but I cannot figure out
how to put the puzzle together (what to put in the body of the function).

I am an ignorant concerning dlls, C and ctypes, so this is really a tough
problem for me, and I hope you can help.

I have the following:

>From the pytables project an lzo1.dll is available in a zip file here:

http://www.pytables.org/download/lzo-win/

My initial thoughts about getting a fast solution was to use some utility
function in pytables, but there is not one available, see the discussion
here:

http://sourceforge.net/mailarchive/message.php?msg_name=AANLkTim6jGiCcbLEFbh4ybH1X5b0HXPXx7XAcuA0Jc28%40mail.gmail.com

There is also a header file lzo1x.h, which contains the call signature for
the lzo decompress function I should bind to:

/* safe decompression with overrun testing */
LZO_EXTERN(int)
lzo1x_decompress_safe   ( const lzo_byte *src, lzo_uint  src_len,
                                lzo_byte *dst, lzo_uintp dst_len,
                                lzo_voidp wrkmem /* NOT USED */ );

Using a DLL export viewer I have verified that this function is exported in
the DLL and I have also checked that I can load the dll in ctypes and that
the function is available once loaded:

In [11]: dll = ctypes.windll(r"C:\Some\Path\GnuWin32\bin\lzo1.dll")
In [12]: dll.lzo1x_decompress_safe?
Type:           _FuncPtr
Base Class:     <class 'ctypes._FuncPtr'>
String Form:    <_FuncPtr object at 0x00AC6A08>
Namespace:      Interactive
Docstring:
    <no docstring>

Now, my big problem is to understand how I can write wrapper code, which can
call this function with a bytestr and return a bytestr?

Input to this may be the very old (Python 2.2 from 2002) and not maintained
lzo python module:

http://www.oberhumer.com/opensource/lzo/

http://www.oberhumer.com/opensource/lzo/download/LZO-v1/python-lzo-1.08.tar.gz

which I cannot figure out how to compile. This tarball contains a C file,
with what I guess contains CPython code for making a decompress function the
way I would like it using that very same lzo library function,
lzo1x_decompress_safe

The relevant part is here


/***********************************************************************
// decompress
************************************************************************/

static /* const */ char decompress__doc__[] =
"decompress(string) -- Decompress the data in string, returning a string
containing the decompressed data.\n"
;

static PyObject *
decompress(PyObject *dummy, PyObject *args)
{
    PyObject *result_str;
    const lzo_bytep in;
    lzo_bytep out;
    lzo_uint in_len;
    lzo_uint out_len;
    lzo_uint new_len;
    int len;
    int err;

    /* init */
    UNUSED(dummy);
    if (!PyArg_ParseTuple(args, "s#", &in, &len))
        return NULL;
    if (len < 5 + 3 || in[0] < 0xf0 || in[0] > 0xf1)
        goto header_error;
    in_len = len - 5;
    out_len = (in[1] << 24) | (in[2] << 16) | (in[3] << 8) | in[4];
    if ((int)out_len < 0 || in_len > out_len + out_len / 64 + 16 + 3)
        goto header_error;

    /* alloc buffers */
    result_str = PyString_FromStringAndSize(NULL, out_len);
    if (result_str == NULL)
        return PyErr_NoMemory();

    /* decompress */
    out = (lzo_bytep) PyString_AsString(result_str);
    new_len = out_len;
    err = lzo1x_decompress_safe(in+5, in_len, out, &new_len, NULL);
    if (err != LZO_E_OK || new_len != out_len)
    {
        Py_DECREF(result_str);
        PyErr_Format(LzoError, "Compressed data violation %i", err);
        return NULL;
    }

    /* success */
    return result_str;

header_error:
    PyErr_SetString(LzoError, "Header error - invalid compressed data");
    return NULL;
}

How do I implement equivalent ctype pure Python code such that I do not have
to C compile anything?
Best wishes,

Kim

------------------------------------------------------------------------------
This SF.net Dev2Dev email is sponsored by:

Show off your parallel programming skills.
Enter the Intel(R) Threading Challenge 2010.
http://p.sf.net/sfu/intel-thread-sfd

_______________________________________________
ctypes-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ctypes-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.