s4-ldb: Add ldb_msg_canonicalize_ex() to accept a memory context from client
authorKamen Mazdrashki <kamenim@samba.org>
Fri, 9 Jul 2010 21:06:57 +0000 (00:06 +0300)
committerKamen Mazdrashki <kamenim@samba.org>
Sat, 10 Jul 2010 20:03:14 +0000 (23:03 +0300)
source4/lib/ldb/common/ldb_msg.c
source4/lib/ldb/include/ldb.h

index c00fa5a..ae5bc2e 100644 (file)
@@ -616,6 +616,54 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
        return msg2;
 }
 
+/**
+ * Canonicalize a message, merging elements of the same name
+ */
+int ldb_msg_canonicalize_ex(struct ldb_context *ldb,
+                           const struct ldb_message *msg,
+                           TALLOC_CTX *mem_ctx,
+                           struct ldb_message **_msg_out)
+{
+       unsigned int i;
+       struct ldb_message *msg2;
+
+       msg2 = ldb_msg_copy(mem_ctx, msg);
+       if (msg2 == NULL) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ldb_msg_sort_elements(msg2);
+
+       for (i=1; i < msg2->num_elements; i++) {
+               struct ldb_message_element *el1 = &msg2->elements[i-1];
+               struct ldb_message_element *el2 = &msg2->elements[i];
+
+               if (ldb_msg_element_compare_name(el1, el2) == 0) {
+                       el1->values = talloc_realloc(msg2->elements,
+                                                    el1->values, struct ldb_val,
+                                                    el1->num_values + el2->num_values);
+                       if (el1->num_values + el2->num_values > 0 && el1->values == NULL) {
+                               talloc_free(msg2);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       memcpy(el1->values + el1->num_values,
+                              el2->values,
+                              sizeof(struct ldb_val) * el2->num_values);
+                       el1->num_values += el2->num_values;
+                       talloc_free(discard_const_p(char, el2->name));
+                       if ((i+1) < msg2->num_elements) {
+                               memmove(el2, el2+1, sizeof(struct ldb_message_element) *
+                                       (msg2->num_elements - (i+1)));
+                       }
+                       msg2->num_elements--;
+                       i--;
+               }
+       }
+
+       *_msg_out = msg2;
+       return LDB_SUCCESS;
+}
+
 
 /*
   return a ldb_message representing the differences between msg1 and msg2. If you
index f2362c5..bcb852f 100644 (file)
@@ -1854,6 +1854,11 @@ struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx,
 struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 
                                         const struct ldb_message *msg);
 
+int ldb_msg_canonicalize_ex(struct ldb_context *ldb,
+                           const struct ldb_message *msg,
+                           TALLOC_CTX *mem_ctx,
+                           struct ldb_message **_msg_out);
+
 
 struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, 
                                 struct ldb_message *msg1,