gptrarray.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Pointer Array
  3. *
  4. * Author:
  5. * Aaron Bockover ([email protected])
  6. *
  7. * (C) 2006 Novell, Inc.
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining
  10. * a copy of this software and associated documentation files (the
  11. * "Software"), to deal in the Software without restriction, including
  12. * without limitation the rights to use, copy, modify, merge, publish,
  13. * distribute, sublicense, and/or sell copies of the Software, and to
  14. * permit persons to whom the Software is furnished to do so, subject to
  15. * the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be
  18. * included in all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. #include <stdlib.h>
  29. #include <glib.h>
  30. typedef struct _GPtrArrayPriv {
  31. gpointer *pdata;
  32. guint len;
  33. guint size;
  34. } GPtrArrayPriv;
  35. static void
  36. g_ptr_array_grow(GPtrArrayPriv *array, guint length)
  37. {
  38. guint new_length = array->len + length;
  39. g_return_if_fail(array != NULL);
  40. if(new_length <= array->size) {
  41. return;
  42. }
  43. array->size = 1;
  44. while(array->size < new_length) {
  45. array->size <<= 1;
  46. }
  47. array->size = MAX(array->size, 16);
  48. array->pdata = g_realloc(array->pdata, array->size * sizeof(gpointer));
  49. }
  50. GPtrArray *
  51. g_ptr_array_new()
  52. {
  53. return g_ptr_array_sized_new(0);
  54. }
  55. GPtrArray *
  56. g_ptr_array_sized_new(guint reserved_size)
  57. {
  58. GPtrArrayPriv *array = g_new0(GPtrArrayPriv, 1);
  59. array->pdata = NULL;
  60. array->len = 0;
  61. array->size = 0;
  62. if(reserved_size > 0) {
  63. g_ptr_array_grow(array, reserved_size);
  64. }
  65. return (GPtrArray *)array;
  66. }
  67. gpointer *
  68. g_ptr_array_free(GPtrArray *array, gboolean free_seg)
  69. {
  70. gpointer *data = NULL;
  71. g_return_val_if_fail(array != NULL, NULL);
  72. if(free_seg) {
  73. g_free(array->pdata);
  74. } else {
  75. data = array->pdata;
  76. }
  77. g_free(array);
  78. return data;
  79. }
  80. void
  81. g_ptr_array_set_size(GPtrArray *array, gint length)
  82. {
  83. g_return_if_fail(array != NULL);
  84. if((size_t)length > array->len) {
  85. g_ptr_array_grow((GPtrArrayPriv *)array, length);
  86. memset(array->pdata + array->len, 0, (length - array->len)
  87. * sizeof(gpointer));
  88. }
  89. array->len = length;
  90. }
  91. void
  92. g_ptr_array_add(GPtrArray *array, gpointer data)
  93. {
  94. g_return_if_fail(array != NULL);
  95. g_ptr_array_grow((GPtrArrayPriv *)array, 1);
  96. array->pdata[array->len++] = data;
  97. }
  98. gpointer
  99. g_ptr_array_remove_index(GPtrArray *array, guint index)
  100. {
  101. gpointer removed_node;
  102. g_return_val_if_fail(array != NULL, NULL);
  103. g_return_val_if_fail(index >= 0 || index < array->len, NULL);
  104. removed_node = array->pdata[index];
  105. if(index != array->len - 1) {
  106. g_memmove(array->pdata + index, array->pdata + index + 1,
  107. (array->len - index - 1) * sizeof(gpointer));
  108. }
  109. array->len--;
  110. array->pdata[array->len] = NULL;
  111. return removed_node;
  112. }
  113. gboolean
  114. g_ptr_array_remove(GPtrArray *array, gpointer data)
  115. {
  116. guint i;
  117. g_return_val_if_fail(array != NULL, FALSE);
  118. for(i = 0; i < array->len; i++) {
  119. if(array->pdata[i] == data) {
  120. g_ptr_array_remove_index(array, i);
  121. return TRUE;
  122. }
  123. }
  124. return FALSE;
  125. }
  126. void
  127. g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data)
  128. {
  129. guint i;
  130. for(i = 0; i < array->len; i++) {
  131. func(g_ptr_array_index(array, i), user_data);
  132. }
  133. }
  134. void
  135. g_ptr_array_sort(GPtrArray *array, GCompareFunc compare_func)
  136. {
  137. g_return_if_fail(array != NULL);
  138. qsort(array->pdata, array->len, sizeof(gpointer), compare_func);
  139. }
  140. void
  141. g_ptr_array_sort_with_data(GPtrArray *array, GCompareDataFunc compare_func,
  142. gpointer user_data)
  143. {
  144. }