libnl 3.7.0
data.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
4 */
5
6/**
7 * @ingroup core_types
8 * @defgroup data Abstract Data
9 *
10 * Abstract data type representing a binary data blob.
11 *
12 * Related sections in the development guide:
13 * - @core_doc{_abstract_data, Abstract Data}
14 *
15 * @{
16 *
17 * Header
18 * ------
19 * ~~~~{.c}
20 * #include <netlink/data.h>
21 * ~~~~
22 */
23
24#include <netlink-private/netlink.h>
25#include <netlink/netlink.h>
26#include <netlink/utils.h>
27#include <linux/socket.h>
28
29/**
30 * @name General
31 * @{
32 */
33
34/**
35 * Allocate a new abstract data object.
36 * @arg buf Data buffer containing the actual data.
37 * @arg size Size of data buffer.
38 *
39 * Allocates a new abstract data and copies the specified data
40 * buffer into the new handle.
41 *
42 * @return Newly allocated data handle or NULL
43 */
44struct nl_data *nl_data_alloc(const void *buf, size_t size)
45{
46 struct nl_data *data;
47
48 data = calloc(1, sizeof(*data));
49 if (!data)
50 goto errout;
51
52 data->d_data = calloc(1, size);
53 if (!data->d_data) {
54 free(data);
55 goto errout;
56 }
57
58 data->d_size = size;
59
60 if (buf)
61 memcpy(data->d_data, buf, size);
62
63 return data;
64errout:
65 return NULL;
66}
67
68/**
69 * Allocate abstract data object based on netlink attribute.
70 * @arg nla Netlink attribute of unspecific type.
71 *
72 * Allocates a new abstract data and copies the payload of the
73 * attribute to the abstract data object.
74 *
75 * @see nla_data_alloc
76 * @return Newly allocated data handle or NULL
77 */
78struct nl_data *nl_data_alloc_attr(const struct nlattr *nla)
79{
80 return nl_data_alloc(nla_data(nla), nla_len(nla));
81}
82
83/**
84 * Clone an abstract data object.
85 * @arg src Abstract data object
86 *
87 * @return Cloned object or NULL
88 */
89struct nl_data *nl_data_clone(const struct nl_data *src)
90{
91 return nl_data_alloc(src->d_data, src->d_size);
92}
93
94/**
95 * Append data to an abstract data object.
96 * @arg data Abstract data object.
97 * @arg buf Data buffer containing the data to be appended.
98 * @arg size Size of data to be apppended.
99 *
100 * Reallocates an abstract data and copies the specified data
101 * buffer into the new handle.
102 *
103 * @return 0 on success or a negative error code
104 */
105int nl_data_append(struct nl_data *data, const void *buf, size_t size)
106{
107 if (size > 0) {
108 char *d_data = realloc(data->d_data, data->d_size + size);
109 if (!d_data)
110 return -NLE_NOMEM;
111
112 if (buf)
113 memcpy(d_data + data->d_size, buf, size);
114 else
115 memset(d_data + data->d_size, 0, size);
116
117 data->d_data = d_data;
118 data->d_size += size;
119 }
120
121 return 0;
122}
123
124/**
125 * Free an abstract data object.
126 * @arg data Abstract data object.
127 */
128void nl_data_free(struct nl_data *data)
129{
130 if (data)
131 free(data->d_data);
132
133 free(data);
134}
135
136/** @} */
137
138/**
139 * @name Attribute Access
140 * @{
141 */
142
143/**
144 * Get data buffer of abstract data object.
145 * @arg data Abstract data object.
146 * @return Data buffer or NULL if empty.
147 */
148void *nl_data_get(const struct nl_data *data)
149{
150 if (data->d_size > 0)
151 return (void*)data->d_data;
152 return NULL;
153}
154
155/**
156 * Get size of data buffer of abstract data object.
157 * @arg data Abstract data object.
158 * @return Size of data buffer.
159 */
160size_t nl_data_get_size(const struct nl_data *data)
161{
162 return data->d_size;
163}
164
165/** @} */
166
167/**
168 * @name Misc
169 * @{
170 */
171
172/**
173 * Compare two abstract data objects.
174 * @arg a Abstract data object.
175 * @arg b Another abstract data object.
176 * @return An integer less than, equal to, or greater than zero if
177 * a is found, respectively, to be less than, to match, or
178 * be greater than b.
179 */
180int nl_data_cmp(const struct nl_data *a, const struct nl_data *b)
181{
182 const void *a_ = nl_data_get(a);
183 const void *b_ = nl_data_get(b);
184
185 if (a_ && b_)
186 return memcmp(a_, b_, nl_data_get_size(a));
187 else
188 return -1;
189}
190
191/** @} */
192/** @} */
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:114
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:125
struct nl_data * nl_data_clone(const struct nl_data *src)
Clone an abstract data object.
Definition: data.c:89
void nl_data_free(struct nl_data *data)
Free an abstract data object.
Definition: data.c:128
int nl_data_append(struct nl_data *data, const void *buf, size_t size)
Append data to an abstract data object.
Definition: data.c:105
struct nl_data * nl_data_alloc(const void *buf, size_t size)
Allocate a new abstract data object.
Definition: data.c:44
size_t nl_data_get_size(const struct nl_data *data)
Get size of data buffer of abstract data object.
Definition: data.c:160
struct nl_data * nl_data_alloc_attr(const struct nlattr *nla)
Allocate abstract data object based on netlink attribute.
Definition: data.c:78
void * nl_data_get(const struct nl_data *data)
Get data buffer of abstract data object.
Definition: data.c:148
int nl_data_cmp(const struct nl_data *a, const struct nl_data *b)
Compare two abstract data objects.
Definition: data.c:180