server: intialize aux_header buffer to null if the data is missing.
[tridge/openchange.git] / branches / plugfest / pyopenchange / pymapi.c
1 /*
2    OpenChange MAPI implementation.
3
4    Python interface to openchange
5
6    Copyright (C) Julien Kerihuel 2010.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <Python.h>
23 #include "libmapi/libmapi.h"
24 #include "pyopenchange/pymapi.h"
25
26 void initmapi(void);
27
28 static PyObject *py_SPropValue_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
29 {
30         TALLOC_CTX              *mem_ctx;
31         PySPropValueObject      *SPropValue;
32
33         mem_ctx = talloc_new(NULL);
34         if (mem_ctx == NULL) {
35                 PyErr_NoMemory();
36                 return NULL;
37         }
38
39         SPropValue = PyObject_New(PySPropValueObject, &PySPropValue);
40         SPropValue->mem_ctx = mem_ctx;
41         SPropValue->SPropValue = talloc_array(mem_ctx, struct SPropValue, 2);
42         SPropValue->cValues = 0;
43
44         return (PyObject *) SPropValue;
45 }
46
47 static void py_SPropValue_dealloc(PyObject *_self)
48 {
49         PySPropValueObject      *self = (PySPropValueObject *)_self;
50
51         talloc_free(self->mem_ctx);
52         PyObject_Del(_self);
53 }
54
55 static PyObject *py_SPropValue_add(PySPropValueObject *self, PyObject *args)
56 {
57         uint32_t        proptag;
58         PyObject        *data;
59         int             i;
60         NTTIME          nt;
61
62         if (!PyArg_ParseTuple(args, "lO", &proptag, &data)) {
63                 return NULL;
64         }
65
66         /* Ensure this tag has not already been added to the list */
67         for (i = 0; i < self->cValues; i++) {
68                 if (self->SPropValue[i].ulPropTag == proptag) {
69                         return NULL;
70                 }
71         }
72
73         self->SPropValue = talloc_realloc(self->mem_ctx, self->SPropValue, struct SPropValue, self->cValues + 2);
74
75         switch (proptag & 0xFFFF) {
76         case PT_SHORT:
77                 if (!PyInt_Check(data)) {
78                         PyErr_SetString(PyExc_TypeError, "Property Tag requires long");
79                         return NULL;
80                 }
81                 self->SPropValue[self->cValues].value.i = (uint16_t) PyInt_AsLong(data);
82                 break;
83         case PT_LONG:
84                 if (!PyInt_Check(data)) {
85                         PyErr_SetString(PyExc_TypeError, "Property Tag requires long");
86                         return NULL;
87                 }
88                 self->SPropValue[self->cValues].value.l = PyInt_AsLong(data);
89                 break;
90         case PT_DOUBLE:
91                 if (!PyFloat_Check(data)) {
92                         PyErr_SetString(PyExc_TypeError, "Property Tag requires double");
93                         return NULL;
94                 }
95                 self->SPropValue[self->cValues].value.dbl = PyFloat_AsDouble(data);
96                 break;
97         case PT_BOOLEAN:
98                 if (!PyBool_Check(data)) {
99                         PyErr_SetString(PyExc_TypeError, "Property Tag requires long");
100                         return NULL;
101                 }
102                 self->SPropValue[self->cValues].value.b = PyInt_AsLong(data);
103                 break;
104         case PT_I8:
105                 if (!PyInt_Check(data)) {
106                         PyErr_SetString(PyExc_TypeError, "Property Tag requires long long int");
107                         return NULL;
108                 }
109                 self->SPropValue[self->cValues].value.d = PyLong_AsLongLong(data);
110                 break;
111         case PT_STRING8:
112                 if (!PyString_Check(data)) {
113                         PyErr_SetString(PyExc_TypeError, "Property Tag requires string");
114                         return NULL;
115                 }
116                 self->SPropValue[self->cValues].value.lpszA = talloc_strdup(self->mem_ctx, PyString_AsString(data));
117                 break;
118         case PT_UNICODE:
119                 if (!PyString_Check(data)) {
120                         PyErr_SetString(PyExc_TypeError, "Property Tag requires string");
121                         return NULL;
122                 }
123                 self->SPropValue[self->cValues].value.lpszW = talloc_strdup(self->mem_ctx, PyString_AsString(data));
124                 break;
125         case PT_SYSTIME:
126                 if (!PyFloat_Check(data)) {
127                         PyErr_SetString(PyExc_TypeError, "Property Tag requires float");
128                         return NULL;
129                 }
130                 unix_to_nt_time(&nt, PyFloat_AsDouble(data));
131                 self->SPropValue[self->cValues].value.ft.dwLowDateTime = (nt << 32) >> 32;
132                 self->SPropValue[self->cValues].value.ft.dwHighDateTime = nt >> 32;
133                 break;
134         case PT_ERROR:
135                 if (!PyInt_Check(data)) {
136                         PyErr_SetString(PyExc_TypeError, "Property Tag requires long");
137                         return NULL;
138                 }
139                 self->SPropValue[self->cValues].value.err = PyInt_AsLong(data);
140                 break;
141         default:
142                 printf("Missing support for 0x%.4x type\n", (proptag & 0xFFFF));
143                 Py_RETURN_NONE;
144         }
145
146         self->SPropValue[self->cValues].ulPropTag = proptag;
147         self->cValues += 1;
148         Py_RETURN_NONE;
149 }
150
151 static PyObject *py_SPropValue_dump(PySPropValueObject *self, PyObject *args)
152 {
153         int     i;
154         char    *sep;
155
156         if (!PyArg_ParseTuple(args, "s", &sep)) {
157                 return NULL;
158         }
159
160         for (i = 0; i < self->cValues; i++) {
161                 mapidump_SPropValue(self->SPropValue[i], sep);
162         }
163         
164         Py_RETURN_NONE;
165 }
166
167 static PyMethodDef mapi_SPropValue_methods[] = {
168         { "add", (PyCFunction)py_SPropValue_add, METH_VARARGS },
169         { "dump", (PyCFunction)py_SPropValue_dump, METH_VARARGS },
170         { NULL },
171 };
172
173 static PyGetSetDef mapi_SPropValue_getsetters[] = {
174         { NULL }
175 };
176
177 PyTypeObject PySPropValue = {
178         PyObject_HEAD_INIT(NULL) 0,
179         .tp_name = "SPropValue",
180         .tp_basicsize = sizeof (PySPropValueObject),
181         .tp_methods = mapi_SPropValue_methods,
182         .tp_getset = mapi_SPropValue_getsetters,
183         .tp_doc = "SPropValue MAPI structure",
184         .tp_new = py_SPropValue_new,
185         .tp_dealloc = (destructor)py_SPropValue_dealloc,
186         .tp_flags = Py_TPFLAGS_DEFAULT,
187 };
188
189 static PyMethodDef py_mapi_global_methods[] = {
190         { NULL }
191 };
192
193 void initmapi(void)
194 {
195         PyObject        *m;
196
197         if (PyType_Ready(&PySPropValue) < 0) {
198                 return;
199         }
200
201         m = Py_InitModule3("mapi", py_mapi_global_methods,
202                            "An interface to OpenChange MAPI");
203         if (m == NULL) {
204                 return;
205         }
206
207         /* Add all properties - generated by mparse.pl */
208         pymapi_add_properties(m);
209
210         Py_INCREF(&PySPropValue);
211         
212         PyModule_AddObject(m, "SPropValue", (PyObject *)&PySPropValue);
213