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-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