r4327: add usefull function if you don't want that the data will talloc_memdup()'ed
[samba.git] / source / lib / data_blob.c
index d51cffbca46858f2140fb9c9f2b4f0fdad82d003..18ecc2793ac7e14eab1dc417ee70fcedb391065a 100644 (file)
 
 #include "includes.h"
 
-/*******************************************************************
- free() a data blob
-*******************************************************************/
-static void free_data_blob(DATA_BLOB *d)
-{
-       if ((d) && (d->free)) {
-               SAFE_FREE(d->data);
-       }
-}
-
 /*******************************************************************
  construct a data blob, must be freed with data_blob_free()
  you can pass NULL for p and get a blank data blob
 *******************************************************************/
-DATA_BLOB data_blob(const void *p, size_t length)
+DATA_BLOB data_blob_named(const void *p, size_t length, const char *name)
 {
        DATA_BLOB ret;
 
-       if (!length) {
+       if (length == 0) {
                ZERO_STRUCT(ret);
                return ret;
        }
 
        if (p) {
-               ret.data = smb_xmemdup(p, length);
+               ret.data = talloc_memdup(NULL, p, length);
        } else {
-               ret.data = smb_xmalloc(length);
+               ret.data = talloc(NULL, length);
+       }
+       if (ret.data == NULL) {
+               ret.length = 0;
+               return ret;
        }
+       talloc_set_name_const(ret.data, name);
        ret.length = length;
-       ret.free = free_data_blob;
        return ret;
 }
 
 /*******************************************************************
  construct a data blob, using supplied TALLOC_CTX
 *******************************************************************/
-DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
+DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name)
 {
-       DATA_BLOB ret;
+       DATA_BLOB ret = data_blob_named(p, length, name);
 
-       if (length == 0) {
-               ZERO_STRUCT(ret);
-               return ret;
+       if (ret.data) {
+               talloc_steal(mem_ctx, ret.data);
        }
+       return ret;
+}
 
-       if (p == NULL) {
-               ret.data = talloc(mem_ctx, length);
-               if (ret.data == NULL) {
-                       smb_panic("data_blob_talloc: talloc_memdup failed.\n");
-               }
-               ret.length = length;
-               memset(ret.data, 0, ret.length);
-               return ret;
-       }
 
-       ret.data = talloc_memdup(mem_ctx, p, length);
-       if (ret.data == NULL) {
-               smb_panic("data_blob_talloc: talloc_memdup failed.\n");
-       }
+/*******************************************************************
+ reference a data blob, to the supplied TALLOC_CTX.  
+ Returns a NULL DATA_BLOB on failure
+*******************************************************************/
+DATA_BLOB data_blob_talloc_reference(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
+{
+       DATA_BLOB ret = *blob;
 
-       ret.length = length;
-       ret.free = NULL;
+       ret.data = talloc_reference(mem_ctx, blob->data);
+
+       if (!ret.data) {
+               return data_blob(NULL, 0);
+       }
        return ret;
 }
 
+/*******************************************************************
+ construct a zero data blob, using supplied TALLOC_CTX. 
+ use this sparingly as it initialises data - better to initialise
+ yourself if you want specific data in the blob
+*******************************************************************/
+DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length)
+{
+       DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length);
+       data_blob_clear(&blob);
+       return blob;
+}
+
 /*******************************************************************
 free a data blob
 *******************************************************************/
 void data_blob_free(DATA_BLOB *d)
 {
-       return;
-
        if (d) {
-               if (d->free) {
-                       (d->free)(d);
-               }
+               talloc_free(d->data);
+               d->data = NULL;
                d->length = 0;
        }
 }
@@ -124,7 +125,7 @@ void data_blob_clear_free(DATA_BLOB *d)
 /*******************************************************************
 check if two data blobs are equal
 *******************************************************************/
-BOOL data_blob_equal(DATA_BLOB *d1, DATA_BLOB *d2)
+BOOL data_blob_equal(const DATA_BLOB *d1, const DATA_BLOB *d2)
 {
        if (d1->length != d2->length) {
                return False;
@@ -141,3 +142,41 @@ BOOL data_blob_equal(DATA_BLOB *d1, DATA_BLOB *d2)
        return False;
 }
 
+/*******************************************************************
+print the data_blob as hex string
+*******************************************************************/
+char *data_blob_hex_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
+{
+       int i;
+       char *hex_string;
+
+       hex_string = talloc_array_p(mem_ctx, char, (blob->length*2)+1);
+       if (!hex_string) {
+               return NULL;
+       }
+
+       for (i = 0; i < blob->length; i++)
+               slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
+
+       return hex_string;
+}
+
+/*
+  useful for constructing data blobs in test suites, while
+  avoiding const warnings
+*/
+DATA_BLOB data_blob_string_const(const char *str)
+{
+       DATA_BLOB blob;
+       blob.data = discard_const(str);
+       blob.length = strlen(str);
+       return blob;
+}
+
+DATA_BLOB data_blob_const(const void *p, size_t length)
+{
+       DATA_BLOB blob;
+       blob.data = discard_const(p);
+       blob.length = length;
+       return blob;
+}