Merge data_blob_hex_string from Samba4.
[kai/samba.git] / source3 / lib / data_blob.c
index 250c3ade88e57eb9ab375db1ad6c88dbaabece03..66c5daf363af67b5ffbb1f90281b178074bb1892 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
+const DATA_BLOB data_blob_null = { NULL, 0, NULL };
+
 /*******************************************************************
- free() a data blob
+ Free() a data blob.
 *******************************************************************/
+
 static void free_data_blob(DATA_BLOB *d)
 {
        if ((d) && (d->free)) {
@@ -32,9 +34,10 @@ static void free_data_blob(DATA_BLOB *d)
 }
 
 /*******************************************************************
- construct a data blob, must be freed with data_blob_free()
you can pass NULL for p and get a blank data blob
+ 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 ret;
@@ -45,9 +48,9 @@ DATA_BLOB data_blob(const void *p, size_t length)
        }
 
        if (p) {
-               ret.data = smb_xmemdup(p, length);
+               ret.data = (uint8 *)smb_xmemdup(p, length);
        } else {
-               ret.data = smb_xmalloc(length);
+               ret.data = SMB_XMALLOC_ARRAY(uint8, length);
        }
        ret.length = length;
        ret.free = free_data_blob;
@@ -55,20 +58,27 @@ DATA_BLOB data_blob(const void *p, size_t length)
 }
 
 /*******************************************************************
- construct a data blob, using supplied TALLOC_CTX
+ 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 ret;
 
-       if (!p || !length) {
+       if (!length) {
                ZERO_STRUCT(ret);
                return ret;
        }
 
-       ret.data = talloc_memdup(mem_ctx, p, length);
-       if (ret.data == NULL)
-               smb_panic("data_blob_talloc: talloc_memdup failed.\n");
+       if (p) {
+               ret.data = (uint8 *)TALLOC_MEMDUP(mem_ctx, p, length);
+               if (ret.data == NULL)
+                       smb_panic("data_blob_talloc: TALLOC_MEMDUP failed");
+       } else {
+               ret.data = (uint8 *)TALLOC(mem_ctx, length);
+               if (ret.data == NULL)
+                       smb_panic("data_blob_talloc: TALLOC failed");
+       }
 
        ret.length = length;
        ret.free = NULL;
@@ -76,21 +86,24 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
 }
 
 /*******************************************************************
-free a data blob
+ Free a data blob.
 *******************************************************************/
+
 void data_blob_free(DATA_BLOB *d)
 {
        if (d) {
                if (d->free) {
                        (d->free)(d);
                }
+               d->length = 0;
        }
 }
 
 /*******************************************************************
-clear a DATA_BLOB's contents
+ Clear a DATA_BLOB's contents
 *******************************************************************/
-static void data_blob_clear(DATA_BLOB *d)
+
+void data_blob_clear(DATA_BLOB *d)
 {
        if (d->data) {
                memset(d->data, 0, d->length);
@@ -98,11 +111,70 @@ static void data_blob_clear(DATA_BLOB *d)
 }
 
 /*******************************************************************
-free a data blob and clear its contents
+ Free a data blob and clear its contents
 *******************************************************************/
+
 void data_blob_clear_free(DATA_BLOB *d)
 {
        data_blob_clear(d);
        data_blob_free(d);
 }
 
+/**
+  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 = CONST_DISCARD(uint8 *, str);
+       blob.length = strlen(str) + 1;
+       blob.free = NULL;
+       return blob;
+}
+
+/**
+ * Create a new data blob from const data 
+ */
+DATA_BLOB data_blob_const(const void *p, size_t length)
+{
+       DATA_BLOB blob;
+       blob.data = CONST_DISCARD(uint8 *, p);
+       blob.length = length;
+       blob.free = NULL;
+       return blob;
+}
+
+/**
+ 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;
+}
+
+/**
+print the data_blob as hex string
+**/
+_PUBLIC_ char *data_blob_hex_string(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
+{
+       int i;
+       char *hex_string;
+
+       hex_string = talloc_array(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]);
+
+       hex_string[(blob->length*2)] = '\0';
+       return hex_string;
+}
+
+