X-Git-Url: http://git.onelab.eu/?p=libnl.git;a=blobdiff_plain;f=lib%2Fdata.c;fp=lib%2Fdata.c;h=91755508f12ca24af6f71c9de37edd6e0ead6c7f;hp=0000000000000000000000000000000000000000;hb=4cee2ecb3b8afa0637e6f5fe4c57985a4bc740ff;hpb=2df2fbe518d5a221ce6e3ee88a3fb23fb1b94b27 diff --git a/lib/data.c b/lib/data.c new file mode 100644 index 0000000..9175550 --- /dev/null +++ b/lib/data.c @@ -0,0 +1,162 @@ +/* + * lib/data.c Abstract Data + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf + */ + +/** + * @ingroup utils + * @defgroup data Abstract Data + * @{ + */ + +#include +#include +#include +#include + +/** + * @name General + * @{ + */ + +/** + * Allocate a new abstract data object. + * @arg buf Data buffer containing the actual data. + * @arg size Size of data buffer. + * + * Allocates a new abstract data and copies the specified data + * buffer into the new handle. + * + * @return Newly allocated data handle or NULL + */ +struct nl_data *nl_data_alloc(void *buf, size_t size) +{ + struct nl_data *data; + + data = calloc(1, sizeof(*data)); + if (!data) + goto errout; + + data->d_data = calloc(1, size); + if (!data->d_data) { + free(data); + goto errout; + } + + data->d_size = size; + + if (buf) + memcpy(data->d_data, buf, size); + + return data; +errout: + nl_errno(ENOMEM); + return NULL; +} + +/** + * Append data to an abstract data object. + * @arg data Abstract data object. + * @arg buf Data buffer containing the data to be appended. + * @arg size Size of data to be apppended. + * + * Reallocates an abstract data and copies the specified data + * buffer into the new handle. + * + * @return 0 on success or a negative error code + */ +int nl_data_append(struct nl_data *data, void *buf, size_t size) +{ + if (size < 0) + BUG(); + + if (size > 0) { + data->d_data = realloc(data->d_data, data->d_size + size); + if (!data->d_data) + return nl_errno(ENOMEM); + + if (buf) + memcpy(data->d_data + data->d_size, buf, size); + else + memset(data->d_data + data->d_size, 0, size); + + data->d_size += size; + } + + return 0; +} + + +/** + * Free an abstract data object. + * @arg data Abstract data object. + */ +void nl_data_free(struct nl_data *data) +{ + if (data) + free(data->d_data); + + free(data); +} + +/** @} */ + +/** + * @name Attribute Access + * @{ + */ + +/** + * Get data buffer of abstract data object. + * @arg data Abstract data object. + * @return Data buffer or NULL if empty. + */ +void *nl_data_get(struct nl_data *data) +{ + return data->d_size > 0 ? data->d_data : NULL; +} + +/** + * Get size of data buffer of abstract data object. + * @arg data Abstract data object. + * @return Size of data buffer. + */ +size_t nl_data_get_size(struct nl_data *data) +{ + return data->d_size; +} + +/** @} */ + +/** + * @name Misc + * @{ + */ + +/** + * Compare two abstract data objects. + * @arg a Abstract data object. + * @arg b Another abstract data object. + * @return An integer less than, equal to, or greater than zero if + * a is found, respectively, to be less than, to match, or + * be greater than b. + */ +int nl_data_cmp(struct nl_data *a, struct nl_data *b) +{ + void *a_ = nl_data_get(a); + void *b_ = nl_data_get(b); + + if (a_ && b_) + return memcmp(a_, b_, nl_data_get_size(a)); + else + return -1; +} + +/** @} */ +/** @} */