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