libnl  3.4.0
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-2012 Thomas Graf <tgraf@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(const 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(const 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(const 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, const void *buf, size_t size)
112 {
113  if (size > 0) {
114  void *d_data = realloc(data->d_data, data->d_size + size);
115  if (!d_data)
116  return -NLE_NOMEM;
117 
118  if (buf)
119  memcpy(d_data + data->d_size, buf, size);
120  else
121  memset(d_data + data->d_size, 0, size);
122 
123  data->d_data = d_data;
124  data->d_size += size;
125  }
126 
127  return 0;
128 }
129 
130 /**
131  * Free an abstract data object.
132  * @arg data Abstract data object.
133  */
134 void nl_data_free(struct nl_data *data)
135 {
136  if (data)
137  free(data->d_data);
138 
139  free(data);
140 }
141 
142 /** @} */
143 
144 /**
145  * @name Attribute Access
146  * @{
147  */
148 
149 /**
150  * Get data buffer of abstract data object.
151  * @arg data Abstract data object.
152  * @return Data buffer or NULL if empty.
153  */
154 void *nl_data_get(const struct nl_data *data)
155 {
156  if (data->d_size > 0)
157  return (void*)data->d_data;
158  return NULL;
159 }
160 
161 /**
162  * Get size of data buffer of abstract data object.
163  * @arg data Abstract data object.
164  * @return Size of data buffer.
165  */
166 size_t nl_data_get_size(const struct nl_data *data)
167 {
168  return data->d_size;
169 }
170 
171 /** @} */
172 
173 /**
174  * @name Misc
175  * @{
176  */
177 
178 /**
179  * Compare two abstract data objects.
180  * @arg a Abstract data object.
181  * @arg b Another abstract data object.
182  * @return An integer less than, equal to, or greater than zero if
183  * a is found, respectively, to be less than, to match, or
184  * be greater than b.
185  */
186 int nl_data_cmp(const struct nl_data *a, const struct nl_data *b)
187 {
188  const void *a_ = nl_data_get(a);
189  const void *b_ = nl_data_get(b);
190 
191  if (a_ && b_)
192  return memcmp(a_, b_, nl_data_get_size(a));
193  else
194  return -1;
195 }
196 
197 /** @} */
198 /** @} */
void * nl_data_get(const struct nl_data *data)
Get data buffer of abstract data object.
Definition: data.c:154
size_t nl_data_get_size(const struct nl_data *data)
Get size of data buffer of abstract data object.
Definition: data.c:166
struct nl_data * nl_data_alloc_attr(const struct nlattr *nla)
Allocate abstract data object based on netlink attribute.
Definition: data.c:84
int nl_data_append(struct nl_data *data, const void *buf, size_t size)
Append data to an abstract data object.
Definition: data.c:111
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:120
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:131
struct nl_data * nl_data_clone(const struct nl_data *src)
Clone an abstract data object.
Definition: data.c:95
struct nl_data * nl_data_alloc(const void *buf, size_t size)
Allocate a new abstract data object.
Definition: data.c:50
int nl_data_cmp(const struct nl_data *a, const struct nl_data *b)
Compare two abstract data objects.
Definition: data.c:186
void nl_data_free(struct nl_data *data)
Free an abstract data object.
Definition: data.c:134