Factor out LDAPberval_to_object()

Also commit other berval converters which are not yet called by anything.

In places where bervals are returned as objects, PyString_FromStringAndSize()
was being used. In some rare cases, a NULL berval pointer (not NULL data)
is returned as None (not a string). This factors that out to the berval.c
compilation unit.
This commit is contained in:
leonard 2009-08-17 01:49:47 +00:00
parent ce8aca92cf
commit 20bee65a8b
3 changed files with 138 additions and 0 deletions

97
Modules/berval.c Normal file
View File

@ -0,0 +1,97 @@
/* See http://www.python-ldap.org/ for details.
* $Id: berval.c,v 1.1 2009/08/17 01:49:47 leonard Exp $ */
#include "common.h"
#include "berval.h"
/*
* Converts a Python object into a data for a berval structure.
*
* New memory is allocated, and the content of the object is copied into it.
* Then the (pre-existing) berval structure's field are filled in with pointer
* and length data.
*
* The source object must implement the buffer interface, or be None.
* If the source object is None, bv->bv_val will be set to NULL and bv_len to 0.
* Otherwise, bv->bv_val will be non-NULL (even for zero-length data).
* This allows the caller to distinguish a None argument as something special.
*
* Returns 0 on failure, leaving *bv unchanged, and setting an error.
* Returns 1 on success: the berval must be freed with LDAPberval_release().
*/
int
LDAPberval_from_object(PyObject *obj, struct berval *bv)
{
const void *data;
char *datacp;
Py_ssize_t len;
if (PyNone_Check(obj)) {
bv->bv_len = 0;
bv->bv_val = NULL;
return 1;
}
if (!PyObject_AsReadBuffer(obj, &data, &len))
return 0;
datacp = PyMem_MALLOC(len ? len : 1);
if (!datacp) {
PyErr_NoMemory();
return 0;
}
memcpy(datacp, data, len);
bv->bv_len = len;
bv->bv_val = datacp;
return 1;
}
/*
* Returns true if the object could be used to initialize a berval structure
* with LDAPberval_from_object()
*/
int
LDAPberval_from_object_check(PyObject *obj)
{
return PyNone_Check(obj) ||
PyObject_CheckReadBuffer(obj);
}
/*
* Releases memory allocated by LDAPberval_from_object().
* Has no effect if the berval pointer is NULL or the berval data is NULL.
*/
void
LDAPberval_release(struct berval *bv) {
if (bv && bv->bv_val) {
PyMem_FREE(bv->bv_val);
bv->bv_len = 0;
bv->bv_val = NULL;
}
}
/*
* Copies out the data from a berval, and returns it as a new Python object,
* Returns None if the berval pointer is NULL.
*
* Note that this function is not the exact inverse of LDAPberval_from_object
* with regards to the NULL/None conversion.
*
* Returns a new Python object on success, or NULL on failure.
*/
PyObject *
LDAPberval_to_object(const struct berval *bv)
{
PyObject *ret = NULL;
if (!bv) {
ret = Py_None;
Py_INCREF(ret);
}
else {
ret = PyString_FromStringAndSize(bv->bv_val, bv->bv_len);
}
return ret;
}

15
Modules/berval.h Normal file
View File

@ -0,0 +1,15 @@
/* See http://www.python-ldap.org/ for details.
* $Id: berval.h,v 1.1 2009/08/17 01:49:47 leonard Exp $ */
#ifndef __h_berval
#define __h_berval
#include "common.h"
#include "lber.h"
int LDAPberval_from_object(PyObject *obj, struct berval *bv);
int LDAPberval_from_object_check(PyObject *obj);
void LDAPberval_release(struct berval *bv);
PyObject *LDAPberval_to_object(const struct berval *bv);
#endif /* __h_berval_ */

26
Tests/runtests.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/sh
#
# This script runs all the t_*.py tests in the current directory,
# preparing PYTHONPATH to use the most recent local build
#
# Run with -v option for verbose
#
set -e
: ${PYTHON:="python"}
plat_specifier=`$PYTHON -c 'import sys,distutils.util; \
print(distutils.util.get_platform()+"-"+sys.version[0:3])'`
failed=
for test in t_*.py; do
echo "$test:"
PYTHONPATH="../build/lib.$plat_specifier" $PYTHON "$test" "$@" ||
failed="$failed $test"
done
if test -n "$failed"; then
echo "Tests that failed:$failed" >&2
exit 1
else
echo "All tests passed. Yay."
exit 0
fi