data.c 3.8 KB

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