Implement sk_deep_copy.
[openssl.git] / crypto / stack / stack.c
index 76cf1a1168973ec8313896fa28ab2a7f2d5f65a1..980bb684428fc655a2172600eed6608f2bed5e62 100644 (file)
@@ -112,6 +112,43 @@ err:
        return(NULL);
        }
 
+_STACK *sk_deep_copy(_STACK *sk, void *(*copy_func)(void *),
+                        void (*free_func)(void *))
+       {
+       _STACK *ret;
+       int i;
+
+       if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL)
+               return ret;
+       ret->comp = sk->comp;
+       ret->sorted = sk->sorted;
+       ret->num = sk->num;
+       ret->num_alloc = sk->num > MIN_NODES ? sk->num : MIN_NODES;
+       ret->data = OPENSSL_malloc(sizeof(char *) * ret->num_alloc);
+       if (ret->data == NULL)
+               {
+               OPENSSL_free(ret);
+               return NULL;
+               }
+       for (i = 0; i < ret->num_alloc; i++)
+               ret->data[i] = NULL;
+
+       for (i = 0; i < ret->num; ++i)
+               {
+               if (sk->data[i] == NULL)
+                       continue;
+               if ((ret->data[i] = copy_func(sk->data[i])) == NULL)
+                       {
+                       while (--i >= 0)
+                               if (ret->data[i] != NULL)
+                                       free_func(ret->data[i]);
+                       sk_free(ret);
+                       return NULL;
+                       }
+               }
+       return ret;
+       }
+
 _STACK *sk_new_null(void)
        {
        return sk_new((int (*)(const void *, const void *))0);