array.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*-
  2. * Copyright (c) 2009 The NetBSD Foundation, Inc.
  3. * All rights reserved.
  4. *
  5. * This code is derived from software contributed to The NetBSD Foundation
  6. * by David A. Holland.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  19. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  21. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. * POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #define ARRAYINLINE
  30. #include <types.h>
  31. #include <kern/errno.h>
  32. #include <lib.h>
  33. #include <array.h>
  34. struct array *
  35. array_create(void)
  36. {
  37. struct array *a;
  38. a = kmalloc(sizeof(*a));
  39. if (a != NULL) {
  40. array_init(a);
  41. }
  42. return a;
  43. }
  44. void
  45. array_destroy(struct array *a)
  46. {
  47. array_cleanup(a);
  48. kfree(a);
  49. }
  50. void
  51. array_init(struct array *a)
  52. {
  53. a->num = a->max = 0;
  54. a->v = NULL;
  55. }
  56. void
  57. array_cleanup(struct array *a)
  58. {
  59. /*
  60. * Require array to be empty - helps avoid memory leaks since
  61. * we don't/can't free anything any contents may be pointing
  62. * to.
  63. */
  64. ARRAYASSERT(a->num == 0);
  65. kfree(a->v);
  66. #ifdef ARRAYS_CHECKED
  67. a->v = NULL;
  68. #endif
  69. }
  70. int
  71. array_setsize(struct array *a, unsigned num)
  72. {
  73. void **newptr;
  74. unsigned newmax;
  75. if (num > a->max) {
  76. /* Don't touch A until the allocation succeeds. */
  77. newmax = a->max;
  78. while (num > newmax) {
  79. newmax = newmax ? newmax*2 : 4;
  80. }
  81. /*
  82. * We don't have krealloc, and it wouldn't be
  83. * worthwhile to implement just for this. So just
  84. * allocate a new block and copy. (Exercise: what
  85. * about this and/or kmalloc makes it not worthwhile?)
  86. */
  87. newptr = kmalloc(newmax*sizeof(*a->v));
  88. if (newptr == NULL) {
  89. return ENOMEM;
  90. }
  91. memcpy(newptr, a->v, a->num*sizeof(*a->v));
  92. kfree(a->v);
  93. a->v = newptr;
  94. a->max = newmax;
  95. }
  96. a->num = num;
  97. return 0;
  98. }
  99. void
  100. array_remove(struct array *a, unsigned index)
  101. {
  102. unsigned num_to_move;
  103. ARRAYASSERT(a->num <= a->max);
  104. ARRAYASSERT(index < a->num);
  105. num_to_move = a->num - (index + 1);
  106. memmove(a->v + index, a->v + index+1, num_to_move*sizeof(void *));
  107. a->num--;
  108. }