data.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. * @ingroup utils
  13. * @defgroup data Abstract Data
  14. * @{
  15. */
  16. #include <netlink-local.h>
  17. #include <netlink/netlink.h>
  18. #include <netlink/utils.h>
  19. #include <linux/socket.h>
  20. /**
  21. * @name General
  22. * @{
  23. */
  24. /**
  25. * Allocate a new abstract data object.
  26. * @arg buf Data buffer containing the actual data.
  27. * @arg size Size of data buffer.
  28. *
  29. * Allocates a new abstract data and copies the specified data
  30. * buffer into the new handle.
  31. *
  32. * @return Newly allocated data handle or NULL
  33. */
  34. struct nl_data *nl_data_alloc(void *buf, size_t size)
  35. {
  36. struct nl_data *data;
  37. data = calloc(1, sizeof(*data));
  38. if (!data)
  39. goto errout;
  40. data->d_data = calloc(1, size);
  41. if (!data->d_data) {
  42. free(data);
  43. goto errout;
  44. }
  45. data->d_size = size;
  46. if (buf)
  47. memcpy(data->d_data, buf, size);
  48. return data;
  49. errout:
  50. nl_errno(ENOMEM);
  51. return NULL;
  52. }
  53. /**
  54. * Clone an abstract data object.
  55. * @arg src Abstract data object
  56. *
  57. * @return Cloned object or NULL
  58. */
  59. struct nl_data *nl_data_clone(struct nl_data *src)
  60. {
  61. return nl_data_alloc(src->d_data, src->d_size);
  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. if (size > 0) {
  79. data->d_data = realloc(data->d_data, data->d_size + size);
  80. if (!data->d_data)
  81. return nl_errno(ENOMEM);
  82. if (buf)
  83. memcpy(data->d_data + data->d_size, buf, size);
  84. else
  85. memset(data->d_data + data->d_size, 0, size);
  86. data->d_size += size;
  87. }
  88. return 0;
  89. }
  90. /**
  91. * Free an abstract data object.
  92. * @arg data Abstract data object.
  93. */
  94. void nl_data_free(struct nl_data *data)
  95. {
  96. if (data)
  97. free(data->d_data);
  98. free(data);
  99. }
  100. /** @} */
  101. /**
  102. * @name Attribute Access
  103. * @{
  104. */
  105. /**
  106. * Get data buffer of abstract data object.
  107. * @arg data Abstract data object.
  108. * @return Data buffer or NULL if empty.
  109. */
  110. void *nl_data_get(struct nl_data *data)
  111. {
  112. return data->d_size > 0 ? data->d_data : NULL;
  113. }
  114. /**
  115. * Get size of data buffer of abstract data object.
  116. * @arg data Abstract data object.
  117. * @return Size of data buffer.
  118. */
  119. size_t nl_data_get_size(struct nl_data *data)
  120. {
  121. return data->d_size;
  122. }
  123. /** @} */
  124. /**
  125. * @name Misc
  126. * @{
  127. */
  128. /**
  129. * Compare two abstract data objects.
  130. * @arg a Abstract data object.
  131. * @arg b Another abstract data object.
  132. * @return An integer less than, equal to, or greater than zero if
  133. * a is found, respectively, to be less than, to match, or
  134. * be greater than b.
  135. */
  136. int nl_data_cmp(struct nl_data *a, struct nl_data *b)
  137. {
  138. void *a_ = nl_data_get(a);
  139. void *b_ = nl_data_get(b);
  140. if (a_ && b_)
  141. return memcmp(a_, b_, nl_data_get_size(a));
  142. else
  143. return -1;
  144. }
  145. /** @} */
  146. /** @} */