1 /* 2 * lib/data.c Abstract Data 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2003-2008 Thomas Graf <tgraf (at) suug.ch> 10 */ 11 12 /** 13 * @ingroup core 14 * @defgroup data Abstract Data 15 * @{ 16 */ 17 18 #include <netlink-local.h> 19 #include <netlink/netlink.h> 20 #include <netlink/utils.h> 21 #include <linux/socket.h> 22 23 /** 24 * @name General 25 * @{ 26 */ 27 28 /** 29 * Allocate a new abstract data object. 30 * @arg buf Data buffer containing the actual data. 31 * @arg size Size of data buffer. 32 * 33 * Allocates a new abstract data and copies the specified data 34 * buffer into the new handle. 35 * 36 * @return Newly allocated data handle or NULL 37 */ 38 struct nl_data *nl_data_alloc(void *buf, size_t size) 39 { 40 struct nl_data *data; 41 42 data = calloc(1, sizeof(*data)); 43 if (!data) 44 goto errout; 45 46 data->d_data = calloc(1, size); 47 if (!data->d_data) { 48 free(data); 49 goto errout; 50 } 51 52 data->d_size = size; 53 54 if (buf) 55 memcpy(data->d_data, buf, size); 56 57 return data; 58 errout: 59 return NULL; 60 } 61 62 /** 63 * Allocate abstract data object based on netlink attribute. 64 * @arg nla Netlink attribute of unspecific type. 65 * 66 * Allocates a new abstract data and copies the payload of the 67 * attribute to the abstract data object. 68 * 69 * @see nla_data_alloc 70 * @return Newly allocated data handle or NULL 71 */ 72 struct nl_data *nl_data_alloc_attr(struct nlattr *nla) 73 { 74 return nl_data_alloc(nla_data(nla), nla_len(nla)); 75 } 76 77 /** 78 * Clone an abstract data object. 79 * @arg src Abstract data object 80 * 81 * @return Cloned object or NULL 82 */ 83 struct nl_data *nl_data_clone(struct nl_data *src) 84 { 85 return nl_data_alloc(src->d_data, src->d_size); 86 } 87 88 /** 89 * Append data to an abstract data object. 90 * @arg data Abstract data object. 91 * @arg buf Data buffer containing the data to be appended. 92 * @arg size Size of data to be apppended. 93 * 94 * Reallocates an abstract data and copies the specified data 95 * buffer into the new handle. 96 * 97 * @return 0 on success or a negative error code 98 */ 99 int nl_data_append(struct nl_data *data, void *buf, size_t size) 100 { 101 if (size < 0) 102 BUG(); 103 104 if (size > 0) { 105 data->d_data = realloc(data->d_data, data->d_size + size); 106 if (!data->d_data) 107 return -NLE_NOMEM; 108 109 if (buf) 110 memcpy(data->d_data + data->d_size, buf, size); 111 else 112 memset(data->d_data + data->d_size, 0, size); 113 114 data->d_size += size; 115 } 116 117 return 0; 118 } 119 120 /** 121 * Free an abstract data object. 122 * @arg data Abstract data object. 123 */ 124 void nl_data_free(struct nl_data *data) 125 { 126 if (data) 127 free(data->d_data); 128 129 free(data); 130 } 131 132 /** @} */ 133 134 /** 135 * @name Attribute Access 136 * @{ 137 */ 138 139 /** 140 * Get data buffer of abstract data object. 141 * @arg data Abstract data object. 142 * @return Data buffer or NULL if empty. 143 */ 144 void *nl_data_get(struct nl_data *data) 145 { 146 return data->d_size > 0 ? data->d_data : NULL; 147 } 148 149 /** 150 * Get size of data buffer of abstract data object. 151 * @arg data Abstract data object. 152 * @return Size of data buffer. 153 */ 154 size_t nl_data_get_size(struct nl_data *data) 155 { 156 return data->d_size; 157 } 158 159 /** @} */ 160 161 /** 162 * @name Misc 163 * @{ 164 */ 165 166 /** 167 * Compare two abstract data objects. 168 * @arg a Abstract data object. 169 * @arg b Another abstract data object. 170 * @return An integer less than, equal to, or greater than zero if 171 * a is found, respectively, to be less than, to match, or 172 * be greater than b. 173 */ 174 int nl_data_cmp(struct nl_data *a, struct nl_data *b) 175 { 176 void *a_ = nl_data_get(a); 177 void *b_ = nl_data_get(b); 178 179 if (a_ && b_) 180 return memcmp(a_, b_, nl_data_get_size(a)); 181 else 182 return -1; 183 } 184 185 /** @} */ 186 /** @} */ 187