|
From: David L. <dav...@cs...> - 2000-07-26 09:19:16
|
On Wed, 26 Jul 2000, Michael Ströder typed thusly:
> > i've been working on adding a display template object into
> > ldapmodule this morning.
> Into the Python part or the C part based on the OpenLDAP libs?
the c part
/* David Leonard <dav...@cs...>, 2000. Public domain. */
/*
* DispTmplObject - wrapper around an LDAP Display Template (disptmpl)
* $Id$
*/
#include "common.h"
#if defined(HAVE_LDAP_INIT_TEMPLATES)
#include "lber.h"
#include "ldap.h"
#include "disptmpl.h"
#include "linkedlist.h"
#include "template.h"
PyObject *DispTmpl_Error;
PyObject *DispTmpl_VersionError;
PyObject *DispTmpl_SyntaxError;
LinkedListType DispTmplSeq_Type;
LinkedListType DispTmplRowSeq_Type;
LinkedListType DispTmplColSeq_Type;
static PyObject *DispTmplSeq_new(struct ldap_disptmpl *);
static PyObject *DispTmplRowSeq_new(DispTmplObject *);
static PyObject *DispTmplColSeq_new(DispTmplRowSeqObject *,
struct ldap_tmplitem *);
static PyObject *DispTmplItem_new(DispTmplObject *, struct ldap_tmplitem *);
static PyObject *DispTmpl_new(struct ldap_disptmpl *, DispTmplSeqObject *);
static PyObject *
makestring(s)
char *s;
{
if (s != NULL)
return PyString_FromString(s);
Py_INCREF(Py_None);
return Py_None;
}
/*------------------------------------------------------------
* DispTmplSeq: a sequence of templates
*/
static PyObject *
DispTmplSeq_new(tmpllist)
struct ldap_disptmpl *tmpllist;
{
DispTmplSeqObject *seq;
struct ldap_disptmpl *t;
struct ldap_tmplitem *r, *c;
seq = (DispTmplSeqObject *)LinkedList_new(&DispTmplSeq_Type);
seq->tmpllist = tmpllist;
/* clear all the application data fields */
for (t = ldap_first_disptmpl(tmpllist);
t;
t = ldap_next_disptmpl(tmpllist, t))
{
LDAP_SET_DISPTMPL_APPDATA(t, NULL);
for (r = ldap_first_tmplrow(t);
r;
r = ldap_next_tmplrow(t, r))
for (c = ldap_first_tmplcol(t, r);
c;
c = ldap_next_tmplcol(t, r, c))
LDAP_SET_TMPLITEM_APPDATA(c, NULL);
}
return (PyObject *)seq;
}
/* Deallocate */
static void
DispTmplSeq_dealloc(self)
DispTmplSeqObject *self;
{
struct ldap_disptmpl *t;
struct ldap_tmplitem *r, *c;
/* Deallocate any application data */
for (t = ldap_first_disptmpl(self->tmpllist);
t;
t = ldap_next_disptmpl(self->tmpllist, t))
{
Py_XDECREF(LDAP_GET_DISPTMPL_APPDATA(t, PyObject *));
for (r = ldap_first_tmplrow(t);
r;
r = ldap_next_tmplrow(t, r))
for (c = ldap_first_tmplcol(t, r);
c;
c = ldap_next_tmplcol(t, r, c))
Py_XDECREF(LDAP_GET_TMPLITEM_APPDATA(c,
PyObject *));
}
ldap_free_templates(self->tmpllist);
PyMem_DEL((PyObject *)self);
}
/* first in list */
static struct ldap_disptmpl *
DispTmplSeq_first(self)
DispTmplSeqObject *self;
{
return ldap_first_disptmpl(self->tmpllist);
}
/* next in list */
static struct ldap_disptmpl *
DispTmplSeq_next(self, tmpl)
DispTmplSeqObject *self;
struct ldap_disptmpl *tmpl;
{
return ldap_next_disptmpl(self->tmpllist, tmpl);
}
/* create object from pointer into list */
static PyObject *
DispTmplSeq_item(self, tmpl)
DispTmplSeqObject *self;
struct ldap_disptmpl *tmpl;
{
return DispTmpl_new(tmpl, self);
}
/* retrieve a template by name */
static PyObject *
DispTmplSeq_name2template(self, args)
DispTmplSeqObject *self;
PyObject *args;
{
struct ldap_disptmpl *t;
char *s;
if (!PyArg_ParseTuple(args, "s", &s))
return NULL;
t = ldap_name2template(s, self->tmpllist);
if (t == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
return DispTmpl_new(t, self);
}
static char DispTmplSeq_name2template_doc[] =
"name2template(name) -> template\n"
"Do stuff.";
/* retrieve a template by objectClass */
static PyObject *
DispTmplSeq_oc2template(self, args)
DispTmplSeqObject *self;
PyObject *args;
{
struct ldap_disptmpl *t;
PyObject *seq, *o;
char **strs;
int len, i;
if (!PyArg_ParseTuple(args, "O", &seq))
return NULL;
if (!PySequence_Check(seq)) {
PyErr_SetString(PyExc_TypeError, "expected list of strings");
return NULL;
}
len = PySequence_Length(seq);
strs = (char **)malloc(sizeof (char *) * (len + 1));
if (strs == NULL)
return PyErr_NoMemory();
for (i = 0; i < len; i++) {
o = PySequence_GetItem(seq, i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_TypeError,
"expected list of strings");
free(strs);
return NULL;
}
strs[i] = PyString_AsString(o);
}
strs[len] = NULL;
t = ldap_oc2template(strs, self->tmpllist);
free(strs);
if (t == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
return DispTmpl_new(t, self);
}
static char DispTmplSeq_oc2template_doc[] =
"oc2template(list of strings) -> template\n"
"Do stuff.";
static PyMethodDef DispTmplSeq_methods[] = {
{ "name2template", (PyCFunction)DispTmplSeq_name2template,
METH_VARARGS, DispTmplSeq_name2template_doc },
{ "oc2template", (PyCFunction)DispTmplSeq_oc2template,
METH_VARARGS, DispTmplSeq_oc2template_doc },
{ NULL, NULL }
};
PyObject *
DispTmplSeq_getattr(self, name)
LinkedListObject *self;
char *name;
{
return Py_FindMethod(DispTmplSeq_methods, (PyObject *)self, name);
}
/*------------------------------------------------------------
* DispTmplRowSeq: a sequence of rows
*/
/* new row sequence */
static PyObject *
DispTmplRowSeq_new(template)
DispTmplObject *template;
{
DispTmplRowSeqObject *rowseq;
rowseq = (DispTmplRowSeqObject *)LinkedList_new(
&DispTmplRowSeq_Type);
rowseq->tmplobj = template;
Py_INCREF(template);
return (PyObject *)rowseq;
}
/* deallocate */
static void
DispTmplRowSeq_dealloc(self)
DispTmplRowSeqObject *self;
{
Py_DECREF(self->tmplobj);
PyMem_DEL((PyObject *)self);
}
/* first in list */
static struct ldap_tmplitem *
DispTmplRowSeq_first(self)
DispTmplRowSeqObject *self;
{
return ldap_first_tmplrow(self->tmplobj->disptmpl);
}
/* next in list */
static struct ldap_tmplitem *
DispTmplRowSeq_next(self, row)
DispTmplRowSeqObject *self;
struct ldap_tmplitem *row;
{
return ldap_next_tmplrow(self->tmplobj->disptmpl, row);
}
/* return a row (sequence of columns) */
static PyObject *
DispTmplRowSeq_item(self, cols)
DispTmplRowSeqObject *self;
struct ldap_tmplitem *cols;
{
return DispTmplColSeq_new(self, cols);
}
/*------------------------------------------------------------
* DispTmplColSeq: a sequence of columns
*/
/* new columns */
static PyObject *
DispTmplColSeq_new(rowseq, row)
DispTmplRowSeqObject *rowseq;
struct ldap_tmplitem *row;
{
DispTmplColSeqObject *colseq;
colseq = (DispTmplColSeqObject *)LinkedList_new(
&DispTmplColSeq_Type);
colseq->tmplobj = rowseq->tmplobj;
Py_INCREF(colseq->tmplobj);
colseq->row = row;
return (PyObject *)colseq;
}
/* Deallocate */
static void
DispTmplColSeq_dealloc(self)
DispTmplColSeqObject *self;
{
Py_DECREF(self->tmplobj);
PyMem_DEL((PyObject *)self);
}
/* first in list */
static struct ldap_tmplitem *
DispTmplColSeq_first(self)
DispTmplColSeqObject *self;
{
return ldap_first_tmplcol(self->tmplobj->disptmpl,
self->row);
}
/* next in list */
static struct ldap_tmplitem *
DispTmplColSeq_next(self, col)
DispTmplColSeqObject *self;
struct ldap_tmplitem *col;
{
return ldap_next_tmplcol(self->tmplobj->disptmpl,
self->row, col);
}
/* extract item from current column */
static PyObject *
DispTmplColSeq_item(self, item)
DispTmplColSeqObject *self;
struct ldap_tmplitem *item;
{
return DispTmplItem_new(self->tmplobj, item);
}
/*------------------------------------------------------------
* template item
*/
static struct { long attr; char *name; PyObject *intern; } anam[] = {
{ LDAP_DITEM_OPT_READONLY, "readonly" },
{ LDAP_DITEM_OPT_SORTVALUES, "sortvalues" },
{ LDAP_DITEM_OPT_SINGLEVALUED, "singlevalued" },
{ LDAP_DITEM_OPT_VALUEREQUIRED, "valuerequired" },
{ LDAP_DITEM_OPT_HIDEIFEMPTY, "hideifempty" },
{ LDAP_DITEM_OPT_HIDEIFFALSE, "hideiffalse" },
};
static int nanam = sizeof anam / sizeof anam[0];
/* deallocate item */
static PyObject *
DispTmplItem_repr(self)
DispTmplItemObject *self;
{
char *label;
char buf[1024];
label = self->item->ti_label;
fprintf(stderr, "label=%p\n", label);
if (label == NULL)
return PyString_FromString("<TemplateItem>");
snprintf(buf, sizeof buf, "<TemplateItem %s>", label);
fprintf(stderr, "buf='%s'\n", buf);
return PyString_FromString(buf);
}
/* deallocate item */
static void
DispTmplItem_dealloc(self)
DispTmplItemObject *self;
{
/* Note: appdata is released later */
Py_DECREF(self->tmplobj);
PyMem_DEL((PyObject *)self);
}
/* read an attribute */
static PyObject *
DispTmplItem_getattr(self, attr)
DispTmplItemObject *self;
char *attr;
{
if (streq(attr, "__members__"))
return Py_BuildValue("[ssssss]",
"appdata", "attrname", "label",
"args", "options", "syntaxid");
if (streq(attr, "appdata")) {
PyObject *data;
data = LDAP_GET_TMPLITEM_APPDATA(self->item, PyObject *);
if (data == NULL)
data = Py_None;
Py_INCREF(data);
return data;
}
if (streq(attr, "attrname"))
return makestring(self->item->ti_attrname);
if (streq(attr, "label"))
return makestring(self->item->ti_label);
if (streq(attr, "args")) {
int i;
PyObject *tuple;
for (i = 0; self->item->ti_args[i]; i++)
;
tuple = PyTuple_New(i);
for (i = 0; self->item->ti_args[i]; i++)
PyTuple_SetItem(tuple, i, PyString_FromString(
self->item->ti_args[i]));
return tuple;
}
if (streq(attr, "options")) {
int i, len;
PyObject *tuple;
for (len = i = 0; i < nanam; i++)
if (LDAP_IS_TMPLITEM_OPTION_SET(self->item, anam[i].attr))
len++;
tuple = PyTuple_New(len);
for (len = i = 0; i < nanam; i++)
if (LDAP_IS_TMPLITEM_OPTION_SET(self->item, anam[i].attr)) {
PyTuple_SetItem(tuple, len, anam[i].intern);
Py_INCREF(anam[i].intern);
len++;
}
return tuple;
}
if (streq(attr, "syntaxid"))
return PyInt_FromLong(self->item->ti_syntaxid);
PyErr_SetString(PyExc_AttributeError, attr);
return NULL;
}
/* set an attribute */
static int
DispTmplItem_setattr(self, attr, value)
DispTmplItemObject *self;
char *attr;
PyObject *value;
{
if (streq(attr, "appdata")) {
Py_XDECREF(LDAP_GET_TMPLITEM_APPDATA(self->item, PyObject *));
LDAP_SET_TMPLITEM_APPDATA(self->item, value);
Py_INCREF(value);
return 0;
}
PyErr_SetString(PyExc_AttributeError, attr);
return -1;
}
static PyTypeObject DispTmplItem_Type = {
#ifdef WIN32
PyObject_HEAD_INIT(NULL)
#else /* ! WIN32 */
PyObject_HEAD_INIT(&PyType_Type)
#endif /* ! WIN32 */
sizeof(DispTmplItemObject),/*ob_size*/
"DispTmplItem", /*tp_name*/
0, /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)DispTmplItem_dealloc,/*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)DispTmplItem_getattr, /*tp_getattr*/
(setattrfunc)DispTmplItem_setattr, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)DispTmplItem_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
};
static PyObject *
DispTmplItem_new(tmplobj, item)
DispTmplObject *tmplobj;
struct ldap_tmplitem *item;
{
DispTmplItemObject *obj;
obj = PyObject_NEW(DispTmplItemObject, &DispTmplItem_Type);
obj->tmplobj = tmplobj;
Py_INCREF(tmplobj);
obj->item = item;
return (PyObject *)obj;
}
/*------------------------------------------------------------
* Template
*/
/* deallocate item */
static void
DispTmpl_dealloc(self)
DispTmplObject *self;
{
/* Note: appdata is released later */
Py_DECREF(self->tmplseqobj);
PyMem_DEL((PyObject *)self);
}
static PyObject *
DispTmpl_tmplattrs(self, args)
PyObject *self, *args;
{
PyErr_SetNone(PyExc_NotImplementedError);
return NULL;
}
static char DispTmpl_tmplattrs_doc[] =
"tmplattrs() -> \n"
"Do stuff.";
static PyMethodDef DispTmpl_methods[] = {
{ "tmplattrs", (PyCFunction)DispTmpl_tmplattrs,
METH_VARARGS, DispTmpl_tmplattrs_doc },
{ NULL, NULL }
};
static struct { long attr; char *name; PyObject *intern; } tnam[] = {
{ LDAP_DTMPL_OPT_ADDABLE, "addable" },
{ LDAP_DTMPL_OPT_ALLOWMODRDN, "allowmodrdn" },
{ LDAP_DTMPL_OPT_ALTVIEW, "altview" },
};
static int ntnam = sizeof tnam / sizeof tnam[0];
/* get an attribute */
static PyObject *
DispTmpl_getattr(self, attr)
DispTmplObject *self;
char *attr;
{
if (streq(attr, "__members__"))
return Py_BuildValue("[sssssssssss]",
"items", "appdata", "options",
"name", "pluralname", "iconname",
"authattrname", "defrdnattrname", "defaddlocation",
"oclist", "adddeflist");
if (streq(attr, "items"))
return DispTmplRowSeq_new(self);
if (streq(attr, "appdata")) {
PyObject *data;
data = LDAP_GET_DISPTMPL_APPDATA(self->disptmpl, PyObject *);
if (data == NULL)
data = Py_None;
Py_INCREF(data);
return data;
}
if (streq(attr, "options")) {
int i, len;
PyObject *tuple;
for (len = i = 0; i < ntnam; i++)
if (LDAP_IS_DISPTMPL_OPTION_SET(self->disptmpl,
tnam[i].attr))
len++;
tuple = PyTuple_New(len);
for (len = i = 0; i < ntnam; i++)
if (LDAP_IS_DISPTMPL_OPTION_SET(self->disptmpl,
tnam[i].attr)) {
PyTuple_SetItem(tuple, len, tnam[i].intern);
Py_INCREF(tnam[i].intern);
len++;
}
return tuple;
}
if (streq(attr, "name"))
return makestring(self->disptmpl->dt_name);
if (streq(attr, "pluralname"))
return makestring(self->disptmpl->dt_pluralname);
if (streq(attr, "iconname"))
return makestring(self->disptmpl->dt_iconname);
if (streq(attr, "authattrname"))
return makestring(self->disptmpl->dt_authattrname);
if (streq(attr, "defrdnattrname"))
return makestring(self->disptmpl->dt_defrdnattrname);
if (streq(attr, "defaddlocation"))
return makestring(self->disptmpl->dt_defaddlocation);
if (streq(attr, "oclist")) {
struct ldap_oclist *ocl = self->disptmpl->dt_oclist;
struct ldap_oclist *o;
int i;
PyObject *tuple;
for (i = 0, o = ocl; o; i++, o = o->oc_next)
i++;
tuple = PyTuple_New(i);
for (i = 0, o = ocl; o; i++, o = o->oc_next) {
PyObject *names;
int j;
for (j = 0; o->oc_objclasses[j]; j++)
;
names = PyTuple_New(j);
for (j = 0; o->oc_objclasses[j]; j++)
PyTuple_SetItem(names, j,
PyString_FromString(o->oc_objclasses[j]));
PyTuple_SetItem(tuple, i, names);
}
return tuple;
}
if (streq(attr, "adddeflist")) {
}
return Py_FindMethod(DispTmpl_methods, (PyObject *)self, attr);
}
/* set an attribute */
static int
DispTmpl_setattr(self, attr, value)
DispTmplObject *self;
char *attr;
PyObject *value;
{
if (streq(attr, "appdata")) {
Py_XDECREF(LDAP_GET_DISPTMPL_APPDATA(self->disptmpl,
PyObject *));
LDAP_SET_DISPTMPL_APPDATA(self->disptmpl, value);
Py_INCREF(value);
return 0;
}
PyErr_SetString(PyExc_AttributeError, attr);
return -1;
}
static PyTypeObject DispTmpl_Type = {
#ifdef WIN32
PyObject_HEAD_INIT(NULL)
#else /* ! WIN32 */
PyObject_HEAD_INIT(&PyType_Type)
#endif /* ! WIN32 */
sizeof(DispTmplObject), /*ob_size*/
"DispTmpl", /*tp_name*/
0, /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)DispTmpl_dealloc,/*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)DispTmpl_getattr, /*tp_getattr*/
(setattrfunc)DispTmpl_setattr, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
};
static PyObject *
DispTmpl_new(disptmpl, tmplseq)
struct ldap_disptmpl *disptmpl;
DispTmplSeqObject *tmplseq;
{
DispTmplObject *obj;
obj = PyObject_NEW(DispTmplObject, &DispTmpl_Type);
obj->tmplseqobj = tmplseq;
Py_INCREF(tmplseq);
obj->disptmpl = disptmpl;
return (PyObject *)obj;
}
/*------------------------------------------------------------
* module-level methods
*/
/* create a sequence of templates */
PyObject *
l_init_templates(self, args)
PyObject *self, *args;
{
struct ldap_disptmpl *tmpllist;
PyObject *bufobj;
const void *buf;
int buflen;
int err;
if (!PyArg_ParseTuple(args, "O", &bufobj))
return NULL;
if (PyObject_AsReadBuffer(bufobj, &buf, &buflen) == -1)
return NULL;
err = ldap_init_templates_buf((char *)buf, buflen, &tmpllist);
switch (err) {
case LDAP_TMPL_ERR_MEM:
return PyErr_NoMemory();
case 0:
return DispTmplSeq_new(tmpllist);
case LDAP_TMPL_ERR_SYNTAX:
PyErr_SetNone(DispTmpl_VersionError);
return NULL;
case LDAP_TMPL_ERR_VERSION:
PyErr_SetNone(DispTmpl_VersionError);
return NULL;
default:
PyErr_SetString(PyExc_SystemError,
"unexpected return value from ldap_init_templates_buf");
return NULL;
}
}
char l_init_templates_doc[] =
"init_templates_buf(buffer) -> templates\n"
"Do stuff.";
void
LDAPinit_template(dict)
PyObject *dict;
{
int i;
LinkedList_inittype(&DispTmplSeq_Type, "DispTmplSeq",
sizeof (DispTmplSeqObject),
(firstfunc)DispTmplSeq_first,
(nextfunc)DispTmplSeq_next,
(itemfunc)DispTmplSeq_item);
DispTmplSeq_Type.llt_type.tp_dealloc = DispTmplSeq_dealloc;
DispTmplSeq_Type.llt_type.tp_getattr = DispTmplSeq_getattr;
LinkedList_inittype(&DispTmplRowSeq_Type, "DispTmplRowSeq",
sizeof (DispTmplRowSeqObject),
(firstfunc)DispTmplRowSeq_first,
(nextfunc)DispTmplRowSeq_next,
(itemfunc)DispTmplRowSeq_item);
DispTmplRowSeq_Type.llt_type.tp_dealloc = DispTmplRowSeq_dealloc;
LinkedList_inittype(&DispTmplColSeq_Type, "DispTmplColSeq",
sizeof (DispTmplColSeqObject),
(firstfunc)DispTmplColSeq_first,
(nextfunc)DispTmplColSeq_next,
(itemfunc)DispTmplColSeq_item);
DispTmplColSeq_Type.llt_type.tp_dealloc = DispTmplColSeq_dealloc;
DispTmpl_Error = PyErr_NewException("ldap.TemplateError",
NULL, NULL);
PyDict_SetItemString(dict, "TemplateError", DispTmpl_Error);
DispTmpl_VersionError = PyErr_NewException(
"ldap.TemplateVersionError", DispTmpl_Error, NULL);
PyDict_SetItemString(dict, "TemplateVersionError",
DispTmpl_VersionError);
DispTmpl_SyntaxError = PyErr_NewException(
"ldap.TemplateSyntaxError", DispTmpl_Error, NULL);
PyDict_SetItemString(dict, "TemplateSyntaxError",
DispTmpl_SyntaxError);
for (i = 0; i < nanam; i++)
anam[i].intern = PyString_FromString(anam[i].name);
for (i = 0; i < ntnam; i++)
tnam[i].intern = PyString_FromString(tnam[i].name);
#define setval(n) PyDict_SetItemString(dict, #n, PyInt_FromLong(LDAP_##n))
setval(SYN_TYPE_TEXT);
setval(SYN_TYPE_IMAGE);
setval(SYN_TYPE_BOOLEAN);
setval(SYN_TYPE_BUTTON);
setval(SYN_TYPE_ACTION);
setval(SYN_OPT_DEFER);
setval(SYN_CASEIGNORESTR);
setval(SYN_MULTILINESTR);
setval(SYN_DN);
setval(SYN_BOOLEAN);
setval(SYN_JPEGIMAGE);
setval(SYN_JPEGBUTTON);
setval(SYN_FAXIMAGE);
setval(SYN_FAXBUTTON);
setval(SYN_AUDIOBUTTON);
setval(SYN_TIME);
setval(SYN_DATE);
setval(SYN_LABELEDURL);
setval(SYN_SEARCHACTION);
setval(SYN_LINKACTION);
setval(SYN_ADDDNACTION);
setval(SYN_VERIFYDNACTION);
setval(SYN_RFC822ADDR);
}
#endif /* ! HAVE_LDAP_INIT_TEMPLATES */
/*
* To Do:
* implement comparison between objects. someone is bound to
* want to compare two row/cell/template objects.
*/
--
David Leonard Dav...@cs...
Dept of Comp. Sci. and Elec. Engg _ Room:78-640 Ph:+61 7 336 51187
The University of Queensland |+| http://www.csee.uq.edu.au/~leonard/
QLD 4072 AUSTRALIA ~` '~ E2A24DC6446E5779D7AFC41AA04E6401
Curses! - Mojo Jojo
|