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