This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
[samba.git] / source / python / py_conv.c
1 /* 
2    Python wrappers for DCERPC/SMB client routines.
3
4    Copyright (C) Tim Potter, 2002
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "Python.h"
23 #include "py_conv.h"
24
25 /* Helper for rpcstr_pull() function */
26
27 static void fstr_pull(fstring str, UNISTR *uni)
28 {
29         rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
30 }
31
32 /* Convert a structure to a Python dict */
33
34 PyObject *from_struct(void *s, struct pyconv *conv)
35 {
36         PyObject *obj, *item;
37         int i;
38
39         obj = PyDict_New();
40
41         for (i = 0; conv[i].name; i++) {
42                 switch (conv[i].type) {
43                 case PY_UNISTR: {
44                         UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
45                         fstring s = "";
46
47                         if (u->buffer)
48                                 fstr_pull(s, u);
49
50                         item = PyString_FromString(s);
51                         PyDict_SetItemString(obj, conv[i].name, item);
52
53                         break;
54                 }
55                 case PY_UINT32: {
56                         uint32 *u = (uint32 *)((char *)s + conv[i].offset);
57
58                         item = PyInt_FromLong(*u);
59                         PyDict_SetItemString(obj, conv[i].name, item);
60                         
61                         break;
62                 }
63                 case PY_UINT16: {
64                         uint16 *u = (uint16 *)((char *)s + conv[i].offset);
65
66                         item = PyInt_FromLong(*u);
67                         PyDict_SetItemString(obj, conv[i].name, item);
68
69                         break;
70                 }
71                 case PY_STRING: {
72                         char *str = (char *)s + conv[i].offset;
73
74                         item = PyString_FromString(str);
75                         PyDict_SetItemString(obj, conv[i].name, item);
76
77                         break;
78                 }
79                 case PY_UID: {
80                         uid_t *uid = (uid_t *)((char *)s + conv[i].offset);
81
82                         item = PyInt_FromLong(*uid);
83                         PyDict_SetItemString(obj, conv[i].name, item);
84
85                         break;
86                 }
87                 case PY_GID: {
88                         gid_t *gid = (gid_t *)((char *)s + conv[i].offset);
89
90                         item = PyInt_FromLong(*gid);
91                         PyDict_SetItemString(obj, conv[i].name, item);
92
93                         break;
94                 }
95                 default:
96                         
97                         break;
98                 }
99         }
100
101         return obj;
102 }
103
104 /* Convert a Python dict to a structure */
105
106 BOOL to_struct(void *s, PyObject *dict, struct pyconv *conv)
107 {
108         PyObject *visited, *key, *value;
109         BOOL result = False;
110         int i;
111
112         visited = PyDict_New();
113
114         for (i = 0; conv[i].name; i++) {
115                 PyObject *obj;
116                 
117                 obj = PyDict_GetItemString(dict, conv[i].name);
118
119                 if (!obj)
120                         goto done;
121                 
122                 switch (conv[i].type) {
123                 case PY_UNISTR: {
124                         UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
125                         char *s = "";
126
127                         if (!PyString_Check(obj))
128                                 goto done;
129
130                         s = PyString_AsString(obj);
131                         init_unistr(u, s);
132                         
133                         break;
134                 }
135                 case PY_UINT32: {
136                         uint32 *u = (uint32 *)((char *)s + conv[i].offset);
137
138                         if (!PyInt_Check(obj))
139                                 goto done;
140
141                         *u = PyInt_AsLong(obj);
142
143                         break;
144                 }
145                 case PY_UINT16: {
146                         uint16 *u = (uint16 *)((char *)s + conv[i].offset);
147
148                         if (!PyInt_Check(obj)) 
149                                 goto done;
150
151                         *u = PyInt_AsLong(obj);
152                         break;
153                 }
154                 default:
155                         break;
156                 }
157
158                 /* Mark as visited */
159
160                 PyDict_SetItemString(visited, conv[i].name, 
161                                      PyInt_FromLong(1));
162         }
163
164         /* Iterate over each item in the input dictionary and see if it was
165            visited.  If it wasn't then the user has added some extra crap
166            to the dictionary. */
167
168         i = 0;
169
170         while (PyDict_Next(dict, &i, &key, &value)) {
171                 if (!PyDict_GetItem(visited, key))
172                         goto done;
173         }
174
175         result = True;
176
177 done:
178         /* We must decrement the reference count here or the visited
179            dictionary will not be freed. */
180                
181         Py_DECREF(visited);
182
183         return result;
184 }