map.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. map.c - a map (associative array) implementation
  3. Copyright (c) 2002 - 2005 dbjh
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include "map.h"
  20. #if defined DJGPP && defined DLL
  21. #include "dxedll_priv.h"
  22. #endif
  23. st_map_t *
  24. map_create (int n_elements)
  25. {
  26. st_map_t *map;
  27. int size = sizeof (st_map_t) + n_elements * sizeof (st_map_element_t);
  28. if ((map = (st_map_t *) malloc (size)) == NULL)
  29. {
  30. fprintf (stderr, "ERROR: Not enough memory for buffer (%d bytes)\n", size);
  31. exit (1);
  32. }
  33. map->data = (st_map_element_t *) (((unsigned char *) map) + sizeof (st_map_t));
  34. memset (map->data, MAP_FREE_KEY, n_elements * sizeof (st_map_element_t));
  35. map->size = n_elements;
  36. map->cmp_key = map_cmp_key_def;
  37. return map;
  38. }
  39. st_map_t *
  40. map_resize (st_map_t *map, int n_elements)
  41. {
  42. int size = sizeof (st_map_t) + n_elements * sizeof (st_map_element_t);
  43. if ((map = (st_map_t *) realloc (map, size)) == NULL)
  44. {
  45. fprintf (stderr, "ERROR: Not enough memory for buffer (%d bytes)\n", size);
  46. exit (1);
  47. }
  48. map->data = (st_map_element_t *) (((unsigned char *) map) + sizeof (st_map_t));
  49. if (n_elements > map->size)
  50. memset (((unsigned char *) map->data) + map->size * sizeof (st_map_element_t),
  51. MAP_FREE_KEY, (n_elements - map->size) * sizeof (st_map_element_t));
  52. map->size = n_elements;
  53. return map;
  54. }
  55. void
  56. map_copy (st_map_t *dest, st_map_t *src)
  57. {
  58. memcpy (dest->data, src->data, src->size * sizeof (st_map_element_t));
  59. dest->cmp_key = src->cmp_key;
  60. }
  61. int
  62. map_cmp_key_def (void *key1, void *key2)
  63. {
  64. return key1 != key2;
  65. }
  66. st_map_t *
  67. map_put (st_map_t *map, void *key, void *object)
  68. {
  69. int n = 0;
  70. while (n < map->size && map->data[n].key != MAP_FREE_KEY &&
  71. map->cmp_key (map->data[n].key, key))
  72. n++;
  73. if (n == map->size) // current map is full
  74. map = map_resize (map, map->size + 20);
  75. map->data[n].key = key;
  76. map->data[n].object = object;
  77. return map;
  78. }
  79. void *
  80. map_get (st_map_t *map, void *key)
  81. {
  82. int n = 0;
  83. while (n < map->size && (map->data[n].key == MAP_FREE_KEY ||
  84. map->cmp_key (map->data[n].key, key)))
  85. n++;
  86. if (n == map->size)
  87. return NULL;
  88. return map->data[n].object;
  89. }
  90. void
  91. map_del (st_map_t *map, void *key)
  92. {
  93. int n = 0;
  94. while (n < map->size && (map->data[n].key == MAP_FREE_KEY ||
  95. map->cmp_key (map->data[n].key, key)))
  96. n++;
  97. if (n < map->size)
  98. map->data[n].key = MAP_FREE_KEY;
  99. }
  100. void
  101. map_dump (st_map_t *map)
  102. {
  103. int n = 0;
  104. while (n < map->size)
  105. {
  106. printf ("%p -> %p\n", map->data[n].key, map->data[n].object);
  107. n++;
  108. }
  109. }