1 /* $NetBSD: data.c,v 1.2 2017/01/28 21:31:45 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2011 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "baselocl.h" 37 #include <string.h> 38 39 static void 40 data_dealloc(void *ptr) 41 { 42 heim_data_t d = ptr; 43 heim_octet_string *os = (heim_octet_string *)d; 44 heim_data_free_f_t *deallocp; 45 heim_data_free_f_t dealloc; 46 47 if (os->data == NULL) 48 return; 49 50 /* Possible string ref */ 51 deallocp = _heim_get_isaextra(os, 0); 52 dealloc = *deallocp; 53 if (dealloc != NULL) 54 dealloc(os->data); 55 } 56 57 static int 58 data_cmp(void *a, void *b) 59 { 60 heim_octet_string *osa = a, *osb = b; 61 if (osa->length != osb->length) 62 return osa->length - osb->length; 63 return memcmp(osa->data, osb->data, osa->length); 64 } 65 66 static unsigned long 67 data_hash(void *ptr) 68 { 69 heim_octet_string *os = ptr; 70 const unsigned char *s = os->data; 71 72 if (os->length < 4) 73 return os->length; 74 return s[0] | (s[1] << 8) | 75 (s[os->length - 2] << 16) | (s[os->length - 1] << 24); 76 } 77 78 struct heim_type_data _heim_data_object = { 79 HEIM_TID_DATA, 80 "data-object", 81 NULL, 82 data_dealloc, 83 NULL, 84 data_cmp, 85 data_hash, 86 NULL 87 }; 88 89 /** 90 * Create a data object 91 * 92 * @param string the string to create, must be an utf8 string 93 * 94 * @return string object 95 */ 96 97 heim_data_t 98 heim_data_create(const void *data, size_t length) 99 { 100 heim_octet_string *os; 101 102 os = _heim_alloc_object(&_heim_data_object, sizeof(*os) + length); 103 if (os) { 104 os->data = (uint8_t *)os + sizeof(*os); 105 os->length = length; 106 memcpy(os->data, data, length); 107 } 108 return (heim_data_t)os; 109 } 110 111 heim_data_t 112 heim_data_ref_create(const void *data, size_t length, 113 heim_data_free_f_t dealloc) 114 { 115 heim_octet_string *os; 116 heim_data_free_f_t *deallocp; 117 118 os = _heim_alloc_object(&_heim_data_object, sizeof(*os) + length); 119 if (os) { 120 os->data = (void *)data; 121 os->length = length; 122 deallocp = _heim_get_isaextra(os, 0); 123 *deallocp = dealloc; 124 } 125 return (heim_data_t)os; 126 } 127 128 129 /** 130 * Return the type ID of data objects 131 * 132 * @return type id of data objects 133 */ 134 135 heim_tid_t 136 heim_data_get_type_id(void) 137 { 138 return HEIM_TID_DATA; 139 } 140 141 /** 142 * Get the data value of the content. 143 * 144 * @param data the data object to get the value from 145 * 146 * @return a heim_octet_string 147 */ 148 149 const heim_octet_string * 150 heim_data_get_data(heim_data_t data) 151 { 152 /* Note that this works for data and data_ref objects */ 153 return (const heim_octet_string *)data; 154 } 155 156 const void * 157 heim_data_get_ptr(heim_data_t data) 158 { 159 /* Note that this works for data and data_ref objects */ 160 return ((const heim_octet_string *)data)->data; 161 } 162 163 size_t heim_data_get_length(heim_data_t data) 164 { 165 /* Note that this works for data and data_ref objects */ 166 return ((const heim_octet_string *)data)->length; 167 } 168