oops
[libnl.git] / lib / data.c
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-2006 Thomas Graf <tgraf@suug.ch>
10  */
11
12 /**
13  * @ingroup utils
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         nl_errno(ENOMEM);
60         return NULL;
61 }
62
63 /**
64  * Append data to an abstract data object.
65  * @arg data            Abstract data object.
66  * @arg buf             Data buffer containing the data to be appended.
67  * @arg size            Size of data to be apppended.
68  *
69  * Reallocates an abstract data and copies the specified data
70  * buffer into the new handle.
71  * 
72  * @return 0 on success or a negative error code
73  */
74 int nl_data_append(struct nl_data *data, void *buf, size_t size)
75 {
76         if (size < 0)
77                 BUG();
78
79         if (size > 0) {
80                 data->d_data = realloc(data->d_data, data->d_size + size);
81                 if (!data->d_data)
82                         return nl_errno(ENOMEM);
83
84                 if (buf)
85                         memcpy(data->d_data + data->d_size, buf, size);
86                 else
87                         memset(data->d_data + data->d_size, 0, size);
88
89                 data->d_size += size;
90         }
91
92         return 0;
93 }
94
95
96 /**
97  * Free an abstract data object.
98  * @arg data            Abstract data object.
99  */
100 void nl_data_free(struct nl_data *data)
101 {
102         if (data)
103                 free(data->d_data);
104
105         free(data);
106 }
107
108 /** @} */
109
110 /**
111  * @name Attribute Access
112  * @{
113  */
114
115 /**
116  * Get data buffer of abstract data object.
117  * @arg data            Abstract data object.
118  * @return Data buffer or NULL if empty.
119  */
120 void *nl_data_get(struct nl_data *data)
121 {
122         return data->d_size > 0 ? data->d_data : NULL;
123 }
124
125 /**
126  * Get size of data buffer of abstract data object.
127  * @arg data            Abstract data object.
128  * @return Size of data buffer.
129  */
130 size_t nl_data_get_size(struct nl_data *data)
131 {
132         return data->d_size;
133 }
134
135 /** @} */
136
137 /**
138  * @name Misc
139  * @{
140  */
141
142 /**
143  * Compare two abstract data objects.
144  * @arg a               Abstract data object.
145  * @arg b               Another abstract data object.
146  * @return An integer less than, equal to, or greater than zero if
147  *         a is found, respectively, to be less than, to match, or
148  *         be greater than b.
149  */
150 int nl_data_cmp(struct nl_data *a, struct nl_data *b)
151 {
152         void *a_ = nl_data_get(a);
153         void *b_ = nl_data_get(b);
154
155         if (a_ && b_)
156                 return memcmp(a_, b_, nl_data_get_size(a));
157         else
158                 return -1;
159 }
160
161 /** @} */
162 /** @} */