r502: modified ldb to allow the use of an external pool memory
[kamenim/samba.git] / source4 / lib / ldb / common / ldb_msg.c
1 /* 
2    ldb database library
3
4    Copyright (C) Andrew Tridgell  2004
5
6      ** NOTE! The following LGPL license applies to the ldb
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9    
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25 /*
26  *  Name: ldb
27  *
28  *  Component: ldb message component utility functions
29  *
30  *  Description: functions for manipulating ldb_message structures
31  *
32  *  Author: Andrew Tridgell
33  */
34
35 #include "includes.h"
36
37
38 /*
39   find an element in a message by attribute name
40 */
41 struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, 
42                                                  const char *attr_name)
43 {
44         int i;
45         for (i=0;i<msg->num_elements;i++) {
46                 if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
47                         return &msg->elements[i];
48                 }
49         }
50         return NULL;
51 }
52
53 /*
54   see if two ldb_val structures contain exactly the same data
55   return 1 for a match, 0 for a mis-match
56 */
57 int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2)
58 {
59         if (v1->length != v2->length) return 0;
60
61         if (v1->length == 0) return 1;
62
63         if (memcmp(v1->data, v2->data, v1->length) == 0) {
64                 return 1;
65         }
66
67         return 0;
68 }
69
70 /*
71   find a value in an element
72   assumes case sensitive comparison
73 */
74 struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, 
75                                  struct ldb_val *val)
76 {
77         int i;
78         for (i=0;i<el->num_values;i++) {
79                 if (ldb_val_equal_exact(val, &el->values[i])) {
80                         return &el->values[i];
81                 }
82         }
83         return NULL;
84 }
85
86
87 /*
88   add an empty element to a message
89 */
90 int ldb_msg_add_empty(struct ldb_context *ldb,
91                       struct ldb_message *msg, const char *attr_name, int flags)
92 {
93         struct ldb_message_element *els;
94
95         els = ldb_realloc_p(ldb, msg->elements, 
96                             struct ldb_message_element, msg->num_elements+1);
97         if (!els) {
98                 errno = ENOMEM;
99                 return -1;
100         }
101
102         els[msg->num_elements].values = NULL;
103         els[msg->num_elements].num_values = 0;
104         els[msg->num_elements].flags = flags;
105         els[msg->num_elements].name = ldb_strdup(ldb, attr_name);
106         if (!els[msg->num_elements].name) {
107                 return -1;
108         }
109
110         msg->elements = els;
111         msg->num_elements++;
112
113         return 0;
114 }
115
116 /*
117   add an empty element to a message
118 */
119 int ldb_msg_add(struct ldb_context *ldb,
120                 struct ldb_message *msg, 
121                 const struct ldb_message_element *el, 
122                 int flags)
123 {
124         if (ldb_msg_add_empty(ldb, msg, el->name, flags) != 0) {
125                 return -1;
126         }
127
128         msg->elements[msg->num_elements-1] = *el;
129         msg->elements[msg->num_elements-1].flags = flags;
130
131         return 0;
132 }
133
134 /*
135   compare two ldb_message_element structures
136   assumes case senistive comparison
137 */
138 int ldb_msg_element_compare(struct ldb_message_element *el1, 
139                             struct ldb_message_element *el2)
140 {
141         int i;
142
143         if (el1->num_values != el2->num_values) {
144                 return el1->num_values - el2->num_values;
145         }
146
147         for (i=0;i<el1->num_values;i++) {
148                 if (!ldb_msg_find_val(el2, &el1->values[i])) {
149                         return -1;
150                 }
151         }
152
153         return 0;
154 }
155
156
157 /*
158   convenience functions to return common types from a message
159   these return the first value if the attribute is multi-valued
160 */
161 int ldb_msg_find_int(const struct ldb_message *msg, 
162                      const char *attr_name,
163                      int default_value)
164 {
165         struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
166         if (!el || el->num_values == 0) {
167                 return default_value;
168         }
169         return strtol(el->values[0].data, NULL, 0);
170 }
171
172 unsigned int ldb_msg_find_uint(const struct ldb_message *msg, 
173                                const char *attr_name,
174                                int default_value)
175 {
176         struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
177         if (!el || el->num_values == 0) {
178                 return default_value;
179         }
180         return strtoul(el->values[0].data, NULL, 0);
181 }
182
183 double ldb_msg_find_double(const struct ldb_message *msg, 
184                            const char *attr_name,
185                            double default_value)
186 {
187         struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
188         if (!el || el->num_values == 0) {
189                 return default_value;
190         }
191         return strtod(el->values[0].data, NULL);
192 }
193
194 const char *ldb_msg_find_string(const struct ldb_message *msg, 
195                                 const char *attr_name,
196                                 const char *default_value)
197 {
198         struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
199         if (!el || el->num_values == 0) {
200                 return default_value;
201         }
202         return el->values[0].data;
203 }