>From 97244a2521917c7770b9e5a863269ec67def0c9b Mon Sep 17 00:00:00 2001
From: Dmitri Pal <dpal@redhat.com>
Date: Sun, 25 Oct 2009 13:21:24 -0400
Subject: [PATCH] COLLECTION Create reference to the top level collection

This patch adds ability to create a reference to the top
level collection.
Previously one could get reference only to collection
inside other collection. With this change it becomes
possible to have two pointers to the same top level
collection from multiple places.
---
 common/collection/collection.c    |   42 +++++++++++++++++++++---------------
 common/collection/collection_ut.c |   13 +++++++++++
 2 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/common/collection/collection.c b/common/collection/collection.c
index 27dee83..9d5edb0 100644
--- a/common/collection/collection.c
+++ b/common/collection/collection.c
@@ -2376,29 +2376,35 @@ int col_get_collection_reference(struct collection_item *ci,
 
     if ((ci == NULL) ||
         (ci->type != COL_TYPE_COLLECTION) ||
-        (acceptor == NULL) ||
-        (collection_to_find == NULL)) {
+        (acceptor == NULL)) {
         TRACE_ERROR_NUMBER("Invalid parameter - returning error",EINVAL);
         return EINVAL;
     }
 
-    /* Find a sub collection */
-    TRACE_INFO_STRING("We are given subcollection name - search it:",
-                      collection_to_find);
-    error = col_find_item_and_do(ci, collection_to_find,
-                                 COL_TYPE_COLLECTIONREF,
-                                 COL_TRAVERSE_DEFAULT,
-                                 col_get_subcollection,
-                                 (void *)(&subcollection),
-                                 COLLECTION_ACTION_FIND);
-    if (error) {
-        TRACE_ERROR_NUMBER("Search failed returning error", error);
-        return error;
-    }
+    if (collection_to_find) {
+        /* Find a sub collection */
+        TRACE_INFO_STRING("We are given subcollection name - search it:",
+                          collection_to_find);
+        error = col_find_item_and_do(ci, collection_to_find,
+                                     COL_TYPE_COLLECTIONREF,
+                                     COL_TRAVERSE_DEFAULT,
+                                     col_get_subcollection,
+                                     (void *)(&subcollection),
+                                     COLLECTION_ACTION_FIND);
+        if (error) {
+            TRACE_ERROR_NUMBER("Search failed returning error", error);
+            return error;
+        }
 
-    if (subcollection == NULL) {
-        TRACE_ERROR_STRING("Search for subcollection returned NULL pointer", "");
-        return ENOENT;
+        if (subcollection == NULL) {
+            TRACE_ERROR_STRING("Search for subcollection returned NULL pointer", "");
+            return ENOENT;
+        }
+    }
+    else {
+        /* Create reference to the same collection */
+        TRACE_INFO_STRING("Creating reference to the top level collection.", "");
+        subcollection = ci;
     }
 
     header = (struct collection_header *)subcollection->data;
diff --git a/common/collection/collection_ut.c b/common/collection/collection_ut.c
index 1e91c23..8662055 100644
--- a/common/collection/collection_ut.c
+++ b/common/collection/collection_ut.c
@@ -33,6 +33,7 @@ int ref_collection_test(void)
 {
     struct collection_item *peer = NULL;
     struct collection_item *socket = NULL;
+    struct collection_item *socket2 = NULL;
     char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
 
     int error = EOK;
@@ -98,7 +99,19 @@ int ref_collection_test(void)
     col_destroy_collection(peer);
 
     col_debug_collection(socket, COL_TRAVERSE_DEFAULT);
+
+    error = col_get_collection_reference(socket, &socket2, NULL);
+    if (error) {
+        col_destroy_collection(socket);
+        printf("Failed to extract collection. Error %d\n", error);
+        return error;
+    }
+
+    col_debug_collection(socket2, COL_TRAVERSE_DEFAULT);
     col_destroy_collection(socket);
+    col_debug_collection(socket2, COL_TRAVERSE_DEFAULT);
+    col_destroy_collection(socket2);
+
     TRACE_FLOW_NUMBER("ref_collection_test. Returning", error);
 
     printf("\n\nEND OF REF TEST!!!.\n\n\n");
-- 
1.5.5.6

