root/lib/util/data_blob.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. data_blob_named
  2. data_blob_talloc_named
  3. data_blob_talloc_reference
  4. data_blob_talloc_zero
  5. data_blob_free
  6. data_blob_clear
  7. data_blob_clear_free
  8. data_blob_cmp
  9. data_blob_hex_string
  10. data_blob_string_const
  11. data_blob_string_const_null
  12. data_blob_const
  13. data_blob_realloc
  14. data_blob_append

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    Easy management of byte-length data
   4    Copyright (C) Andrew Tridgell 2001
   5    Copyright (C) Andrew Bartlett 2001
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 
  23 const DATA_BLOB data_blob_null = { NULL, 0 };
  24 
  25 /**
  26  * @file
  27  * @brief Manipulation of arbitrary data blobs
  28  **/
  29 
  30 /**
  31  construct a data blob, must be freed with data_blob_free()
  32  you can pass NULL for p and get a blank data blob
  33 **/
  34 _PUBLIC_ DATA_BLOB data_blob_named(const void *p, size_t length, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  35 {
  36         DATA_BLOB ret;
  37 
  38         if (p == NULL && length == 0) {
  39                 ZERO_STRUCT(ret);
  40                 return ret;
  41         }
  42 
  43         if (p) {
  44                 ret.data = (uint8_t *)talloc_memdup(NULL, p, length);
  45         } else {
  46                 ret.data = talloc_array(NULL, uint8_t, length);
  47         }
  48         if (ret.data == NULL) {
  49                 ret.length = 0;
  50                 return ret;
  51         }
  52         talloc_set_name_const(ret.data, name);
  53         ret.length = length;
  54         return ret;
  55 }
  56 
  57 /**
  58  construct a data blob, using supplied TALLOC_CTX
  59 **/
  60 _PUBLIC_ DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  61 {
  62         DATA_BLOB ret = data_blob_named(p, length, name);
  63 
  64         if (ret.data) {
  65                 talloc_steal(mem_ctx, ret.data);
  66         }
  67         return ret;
  68 }
  69 
  70 
  71 /**
  72  reference a data blob, to the supplied TALLOC_CTX.  
  73  Returns a NULL DATA_BLOB on failure
  74 **/
  75 _PUBLIC_ DATA_BLOB data_blob_talloc_reference(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
     /* [<][>][^][v][top][bottom][index][help] */
  76 {
  77         DATA_BLOB ret = *blob;
  78 
  79         ret.data = talloc_reference(mem_ctx, blob->data);
  80 
  81         if (!ret.data) {
  82                 return data_blob(NULL, 0);
  83         }
  84         return ret;
  85 }
  86 
  87 /**
  88  construct a zero data blob, using supplied TALLOC_CTX. 
  89  use this sparingly as it initialises data - better to initialise
  90  yourself if you want specific data in the blob
  91 **/
  92 _PUBLIC_ DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length)
     /* [<][>][^][v][top][bottom][index][help] */
  93 {
  94         DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length);
  95         data_blob_clear(&blob);
  96         return blob;
  97 }
  98 
  99 /**
 100 free a data blob
 101 **/
 102 _PUBLIC_ void data_blob_free(DATA_BLOB *d)
     /* [<][>][^][v][top][bottom][index][help] */
 103 {
 104         if (d) {
 105                 talloc_free(d->data);
 106                 d->data = NULL;
 107                 d->length = 0;
 108         }
 109 }
 110 
 111 /**
 112 clear a DATA_BLOB's contents
 113 **/
 114 _PUBLIC_ void data_blob_clear(DATA_BLOB *d)
     /* [<][>][^][v][top][bottom][index][help] */
 115 {
 116         if (d->data) {
 117                 memset(d->data, 0, d->length);
 118         }
 119 }
 120 
 121 /**
 122 free a data blob and clear its contents
 123 **/
 124 _PUBLIC_ void data_blob_clear_free(DATA_BLOB *d)
     /* [<][>][^][v][top][bottom][index][help] */
 125 {
 126         data_blob_clear(d);
 127         data_blob_free(d);
 128 }
 129 
 130 
 131 /**
 132 check if two data blobs are equal
 133 **/
 134 _PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
     /* [<][>][^][v][top][bottom][index][help] */
 135 {
 136         int ret;
 137         if (d1->data == NULL && d2->data != NULL) {
 138                 return -1;
 139         }
 140         if (d1->data != NULL && d2->data == NULL) {
 141                 return 1;
 142         }
 143         if (d1->data == d2->data) {
 144                 return d1->length - d2->length;
 145         }
 146         ret = memcmp(d1->data, d2->data, MIN(d1->length, d2->length));
 147         if (ret == 0) {
 148                 return d1->length - d2->length;
 149         }
 150         return ret;
 151 }
 152 
 153 /**
 154 print the data_blob as hex string
 155 **/
 156 _PUBLIC_ char *data_blob_hex_string(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
     /* [<][>][^][v][top][bottom][index][help] */
 157 {
 158         int i;
 159         char *hex_string;
 160 
 161         hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
 162         if (!hex_string) {
 163                 return NULL;
 164         }
 165 
 166         for (i = 0; i < blob->length; i++)
 167                 slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
 168 
 169         hex_string[(blob->length*2)] = '\0';
 170         return hex_string;
 171 }
 172 
 173 /**
 174   useful for constructing data blobs in test suites, while
 175   avoiding const warnings
 176 **/
 177 _PUBLIC_ DATA_BLOB data_blob_string_const(const char *str)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179         DATA_BLOB blob;
 180         blob.data = discard_const_p(uint8_t, str);
 181         blob.length = str ? strlen(str) : 0;
 182         return blob;
 183 }
 184 
 185 /**
 186   useful for constructing data blobs in test suites, while
 187   avoiding const warnings
 188 **/
 189 _PUBLIC_ DATA_BLOB data_blob_string_const_null(const char *str)
     /* [<][>][^][v][top][bottom][index][help] */
 190 {
 191         DATA_BLOB blob;
 192         blob.data = discard_const_p(uint8_t, str);
 193         blob.length = str ? strlen(str)+1 : 0;
 194         return blob;
 195 }
 196 
 197 /**
 198  * Create a new data blob from const data 
 199  */
 200 
 201 _PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length)
     /* [<][>][^][v][top][bottom][index][help] */
 202 {
 203         DATA_BLOB blob;
 204         blob.data = discard_const_p(uint8_t, p);
 205         blob.length = length;
 206         return blob;
 207 }
 208 
 209 
 210 /**
 211   realloc a data_blob
 212 **/
 213 _PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length)
     /* [<][>][^][v][top][bottom][index][help] */
 214 {
 215         blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, length);
 216         if (blob->data == NULL)
 217                 return false;
 218         blob->length = length;
 219         return true;
 220 }
 221 
 222 
 223 /**
 224   append some data to a data blob
 225 **/
 226 _PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
     /* [<][>][^][v][top][bottom][index][help] */
 227                                    const void *p, size_t length)
 228 {
 229         size_t old_len = blob->length;
 230         size_t new_len = old_len + length;
 231         if (new_len < length || new_len < old_len) {
 232                 return false;
 233         }
 234 
 235         if ((const uint8_t *)p + length < (const uint8_t *)p) {
 236                 return false;
 237         }
 238         
 239         if (!data_blob_realloc(mem_ctx, blob, new_len)) {
 240                 return false;
 241         }
 242 
 243         memcpy(blob->data + old_len, p, length);
 244         return true;
 245 }
 246 

/* [<][>][^][v][top][bottom][index][help] */