libnl 1.1
lib/data.c
00001 /*
00002  * lib/data.c           Abstract Data
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @ingroup utils
00014  * @defgroup data Abstract Data
00015  * @{
00016  */
00017 
00018 #include <netlink-local.h>
00019 #include <netlink/netlink.h>
00020 #include <netlink/utils.h>
00021 #include <linux/socket.h>
00022 
00023 /**
00024  * @name General
00025  * @{
00026  */
00027 
00028 /**
00029  * Allocate a new abstract data object.
00030  * @arg buf             Data buffer containing the actual data.
00031  * @arg size            Size of data buffer.
00032  *
00033  * Allocates a new abstract data and copies the specified data
00034  * buffer into the new handle.
00035  * 
00036  * @return Newly allocated data handle or NULL
00037  */
00038 struct nl_data *nl_data_alloc(void *buf, size_t size)
00039 {
00040         struct nl_data *data;
00041 
00042         data = calloc(1, sizeof(*data));
00043         if (!data)
00044                 goto errout;
00045 
00046         data->d_data = calloc(1, size);
00047         if (!data->d_data) {
00048                 free(data);
00049                 goto errout;
00050         }
00051 
00052         data->d_size = size;
00053 
00054         if (buf)
00055                 memcpy(data->d_data, buf, size);
00056 
00057         return data;
00058 errout:
00059         nl_errno(ENOMEM);
00060         return NULL;
00061 }
00062 
00063 /**
00064  * Clone an abstract data object.
00065  * @arg src             Abstract data object
00066  *
00067  * @return Cloned object or NULL
00068  */
00069 struct nl_data *nl_data_clone(struct nl_data *src)
00070 {
00071         return nl_data_alloc(src->d_data, src->d_size);
00072 }
00073 
00074 /**
00075  * Append data to an abstract data object.
00076  * @arg data            Abstract data object.
00077  * @arg buf             Data buffer containing the data to be appended.
00078  * @arg size            Size of data to be apppended.
00079  *
00080  * Reallocates an abstract data and copies the specified data
00081  * buffer into the new handle.
00082  * 
00083  * @return 0 on success or a negative error code
00084  */
00085 int nl_data_append(struct nl_data *data, void *buf, size_t size)
00086 {
00087         if (size < 0)
00088                 BUG();
00089 
00090         if (size > 0) {
00091                 data->d_data = realloc(data->d_data, data->d_size + size);
00092                 if (!data->d_data)
00093                         return nl_errno(ENOMEM);
00094 
00095                 if (buf)
00096                         memcpy(data->d_data + data->d_size, buf, size);
00097                 else
00098                         memset(data->d_data + data->d_size, 0, size);
00099 
00100                 data->d_size += size;
00101         }
00102 
00103         return 0;
00104 }
00105 
00106 /**
00107  * Free an abstract data object.
00108  * @arg data            Abstract data object.
00109  */
00110 void nl_data_free(struct nl_data *data)
00111 {
00112         if (data)
00113                 free(data->d_data);
00114 
00115         free(data);
00116 }
00117 
00118 /** @} */
00119 
00120 /**
00121  * @name Attribute Access
00122  * @{
00123  */
00124 
00125 /**
00126  * Get data buffer of abstract data object.
00127  * @arg data            Abstract data object.
00128  * @return Data buffer or NULL if empty.
00129  */
00130 void *nl_data_get(struct nl_data *data)
00131 {
00132         return data->d_size > 0 ? data->d_data : NULL;
00133 }
00134 
00135 /**
00136  * Get size of data buffer of abstract data object.
00137  * @arg data            Abstract data object.
00138  * @return Size of data buffer.
00139  */
00140 size_t nl_data_get_size(struct nl_data *data)
00141 {
00142         return data->d_size;
00143 }
00144 
00145 /** @} */
00146 
00147 /**
00148  * @name Misc
00149  * @{
00150  */
00151 
00152 /**
00153  * Compare two abstract data objects.
00154  * @arg a               Abstract data object.
00155  * @arg b               Another abstract data object.
00156  * @return An integer less than, equal to, or greater than zero if
00157  *         a is found, respectively, to be less than, to match, or
00158  *         be greater than b.
00159  */
00160 int nl_data_cmp(struct nl_data *a, struct nl_data *b)
00161 {
00162         void *a_ = nl_data_get(a);
00163         void *b_ = nl_data_get(b);
00164 
00165         if (a_ && b_)
00166                 return memcmp(a_, b_, nl_data_get_size(a));
00167         else
00168                 return -1;
00169 }
00170 
00171 /** @} */
00172 /** @} */