MBED port of https://github.com/ys1382/filagree . The only change is adding #define MBED

Dependents:   filagree_test

Committer:
yusufx
Date:
Wed May 30 21:13:01 2012 +0000
Revision:
0:1a89e28dea91

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yusufx 0:1a89e28dea91 1 /* struct.c
yusufx 0:1a89e28dea91 2 *
yusufx 0:1a89e28dea91 3 * implements array, byte_array, lifo and map
yusufx 0:1a89e28dea91 4 */
yusufx 0:1a89e28dea91 5
yusufx 0:1a89e28dea91 6 #include <stdio.h>
yusufx 0:1a89e28dea91 7 #include <stdlib.h>
yusufx 0:1a89e28dea91 8 #include <string.h>
yusufx 0:1a89e28dea91 9 #include <stdarg.h>
yusufx 0:1a89e28dea91 10 #include <assert.h>
yusufx 0:1a89e28dea91 11 #include <ctype.h>
yusufx 0:1a89e28dea91 12
yusufx 0:1a89e28dea91 13 #include "vm.h"
yusufx 0:1a89e28dea91 14 #include "struct.h"
yusufx 0:1a89e28dea91 15 #include "util.h"
yusufx 0:1a89e28dea91 16
yusufx 0:1a89e28dea91 17 #define BYTE_ARRAY_MAX_LEN 10000
yusufx 0:1a89e28dea91 18 #define ERROR_BYTE_ARRAY_LEN "byte array too long"
yusufx 0:1a89e28dea91 19
yusufx 0:1a89e28dea91 20
yusufx 0:1a89e28dea91 21 // array ///////////////////////////////////////////////////////////////////
yusufx 0:1a89e28dea91 22
yusufx 0:1a89e28dea91 23 struct array *array_new() {
yusufx 0:1a89e28dea91 24 return array_new_size(0);
yusufx 0:1a89e28dea91 25 }
yusufx 0:1a89e28dea91 26
yusufx 0:1a89e28dea91 27 struct array *array_new_size(uint32_t size) {
yusufx 0:1a89e28dea91 28 struct array *a = (struct array*)malloc(sizeof(struct array));
yusufx 0:1a89e28dea91 29 a->data = a->current = NULL;
yusufx 0:1a89e28dea91 30 a->length = 0;
yusufx 0:1a89e28dea91 31 return a;
yusufx 0:1a89e28dea91 32 }
yusufx 0:1a89e28dea91 33
yusufx 0:1a89e28dea91 34 void array_del(struct array *a) {
yusufx 0:1a89e28dea91 35 for (int i=0; i<a->length; i++)
yusufx 0:1a89e28dea91 36 free(array_get(a, i));
yusufx 0:1a89e28dea91 37 free(a->data);
yusufx 0:1a89e28dea91 38 free(a);
yusufx 0:1a89e28dea91 39 }
yusufx 0:1a89e28dea91 40
yusufx 0:1a89e28dea91 41 void array_resize(struct array *a, uint32_t length) {
yusufx 0:1a89e28dea91 42 a->data = (void**)realloc(a->data, length * sizeof(void*));
yusufx 0:1a89e28dea91 43 null_check(a->data);
yusufx 0:1a89e28dea91 44 memset(&a->data[a->length], 0, length-a->length);
yusufx 0:1a89e28dea91 45 a->length = length;
yusufx 0:1a89e28dea91 46 }
yusufx 0:1a89e28dea91 47
yusufx 0:1a89e28dea91 48 uint32_t array_add(struct array *a, void *datum) {
yusufx 0:1a89e28dea91 49 a->data = (void**)realloc(a->data, (a->length+1) * sizeof(void*));
yusufx 0:1a89e28dea91 50 a->data[a->length++] = datum;
yusufx 0:1a89e28dea91 51 return a->length-1;
yusufx 0:1a89e28dea91 52 }
yusufx 0:1a89e28dea91 53
yusufx 0:1a89e28dea91 54 void array_insert(struct array *a, uint32_t index, void *datum)
yusufx 0:1a89e28dea91 55 {
yusufx 0:1a89e28dea91 56 a->data = (void**)realloc(a->data, (a->length+1) * sizeof(void*));
yusufx 0:1a89e28dea91 57 uint32_t i;
yusufx 0:1a89e28dea91 58 for (i=a->length; i>index; i--)
yusufx 0:1a89e28dea91 59 a->data[i] = a->data[i-1];
yusufx 0:1a89e28dea91 60 a->data[i] = datum;
yusufx 0:1a89e28dea91 61 a->length++;
yusufx 0:1a89e28dea91 62 }
yusufx 0:1a89e28dea91 63
yusufx 0:1a89e28dea91 64 void* array_get(const struct array *a, uint32_t index) {
yusufx 0:1a89e28dea91 65 assert_message(a && index < a->length, ERROR_INDEX);
yusufx 0:1a89e28dea91 66 //DEBUGPRINT("array_get %d = %x\n", index, a->data[index]);
yusufx 0:1a89e28dea91 67 return a->data[index];
yusufx 0:1a89e28dea91 68 }
yusufx 0:1a89e28dea91 69
yusufx 0:1a89e28dea91 70 void array_set(struct array *a, uint32_t index, void* datum) {
yusufx 0:1a89e28dea91 71 null_check(a);
yusufx 0:1a89e28dea91 72 null_check(datum);
yusufx 0:1a89e28dea91 73 if (a->length <= index)
yusufx 0:1a89e28dea91 74 array_resize(a, index+1);
yusufx 0:1a89e28dea91 75 //DEBUGPRINT("array_set %d %x\n", index, datum);
yusufx 0:1a89e28dea91 76 a->data[index] = datum;
yusufx 0:1a89e28dea91 77 }
yusufx 0:1a89e28dea91 78
yusufx 0:1a89e28dea91 79 void *list_remove(void *data, uint32_t *end, uint32_t start, int32_t length, size_t width)
yusufx 0:1a89e28dea91 80 {
yusufx 0:1a89e28dea91 81 null_check(data);
yusufx 0:1a89e28dea91 82 null_check(end);
yusufx 0:1a89e28dea91 83 length = length < 0 ? *end - start : length;
yusufx 0:1a89e28dea91 84 assert_message(start < *end && start+length <= *end, "index out of bounds");
yusufx 0:1a89e28dea91 85
yusufx 0:1a89e28dea91 86 memmove((uint8_t*)data+start*width, (uint8_t*)data+(start+length)*width, (*end-start-length)*width);
yusufx 0:1a89e28dea91 87 *end -= (uint32_t)length;
yusufx 0:1a89e28dea91 88 return realloc(data, *end * width);
yusufx 0:1a89e28dea91 89 }
yusufx 0:1a89e28dea91 90
yusufx 0:1a89e28dea91 91 void array_remove(struct array *self, uint32_t start, int32_t length) {
yusufx 0:1a89e28dea91 92 self->data = (void**)list_remove(self->data, &self->length, start, length, sizeof(void*));
yusufx 0:1a89e28dea91 93 }
yusufx 0:1a89e28dea91 94
yusufx 0:1a89e28dea91 95 struct array *array_copy(const struct array* original) {
yusufx 0:1a89e28dea91 96 if (!original)
yusufx 0:1a89e28dea91 97 return NULL;
yusufx 0:1a89e28dea91 98 struct array* copy = (struct array*)malloc(sizeof(struct array));
yusufx 0:1a89e28dea91 99 copy->data = (void**)malloc(original->length);
yusufx 0:1a89e28dea91 100 memcpy(copy->data, original->data, original->length);
yusufx 0:1a89e28dea91 101 copy->length = original->length;
yusufx 0:1a89e28dea91 102 copy->current = copy->data + (original->current - original->data);
yusufx 0:1a89e28dea91 103 return copy;
yusufx 0:1a89e28dea91 104 }
yusufx 0:1a89e28dea91 105
yusufx 0:1a89e28dea91 106 struct array *array_part(struct array *within, uint32_t start, uint32_t length)
yusufx 0:1a89e28dea91 107 {
yusufx 0:1a89e28dea91 108 struct array *p = array_copy(within);
yusufx 0:1a89e28dea91 109 array_remove(p, start+length, within->length-start-length);
yusufx 0:1a89e28dea91 110 array_remove(p, 0, start);
yusufx 0:1a89e28dea91 111 return p;
yusufx 0:1a89e28dea91 112 }
yusufx 0:1a89e28dea91 113
yusufx 0:1a89e28dea91 114 void array_append(struct array *a, const struct array* b)
yusufx 0:1a89e28dea91 115 {
yusufx 0:1a89e28dea91 116 null_check(a);
yusufx 0:1a89e28dea91 117 null_check(b);
yusufx 0:1a89e28dea91 118 array_resize(a, a->length + b->length);
yusufx 0:1a89e28dea91 119 memcpy(&a->data[a->length], b->data, b->length);
yusufx 0:1a89e28dea91 120 a->current = a->data + a->length;
yusufx 0:1a89e28dea91 121 }
yusufx 0:1a89e28dea91 122
yusufx 0:1a89e28dea91 123 // byte_array ///////////////////////////////////////////////////////////////
yusufx 0:1a89e28dea91 124
yusufx 0:1a89e28dea91 125 struct byte_array *byte_array_new() {
yusufx 0:1a89e28dea91 126 struct byte_array* ba = (struct byte_array*)malloc(sizeof(struct byte_array));
yusufx 0:1a89e28dea91 127 ba->data = ba->current = 0;
yusufx 0:1a89e28dea91 128 ba->length = 0;
yusufx 0:1a89e28dea91 129 return ba;
yusufx 0:1a89e28dea91 130 }
yusufx 0:1a89e28dea91 131
yusufx 0:1a89e28dea91 132 void byte_array_del(struct byte_array* ba) {
yusufx 0:1a89e28dea91 133 if (ba->data)
yusufx 0:1a89e28dea91 134 free(ba->data);
yusufx 0:1a89e28dea91 135 free(ba);
yusufx 0:1a89e28dea91 136 }
yusufx 0:1a89e28dea91 137
yusufx 0:1a89e28dea91 138 struct byte_array *byte_array_new_size(uint32_t size) {
yusufx 0:1a89e28dea91 139 struct byte_array* ba = (struct byte_array*)malloc(sizeof(struct byte_array));
yusufx 0:1a89e28dea91 140 ba->data = ba->current = (uint8_t*)malloc(size);
yusufx 0:1a89e28dea91 141 ba->length = size;
yusufx 0:1a89e28dea91 142 return ba;
yusufx 0:1a89e28dea91 143 }
yusufx 0:1a89e28dea91 144
yusufx 0:1a89e28dea91 145 void byte_array_resize(struct byte_array* ba, uint32_t size) {
yusufx 0:1a89e28dea91 146 assert_message(ba->current >= ba->data, "byte_array corrupt");
yusufx 0:1a89e28dea91 147 uint32_t delta = ba->current - ba->data;
yusufx 0:1a89e28dea91 148 ba->data = (uint8_t*)realloc(ba->data, size);
yusufx 0:1a89e28dea91 149 assert(ba->data);
yusufx 0:1a89e28dea91 150 ba->current = ba->data + delta;
yusufx 0:1a89e28dea91 151 ba->length = size;
yusufx 0:1a89e28dea91 152 }
yusufx 0:1a89e28dea91 153
yusufx 0:1a89e28dea91 154 bool byte_array_equals(const struct byte_array *a, const struct byte_array* b) {
yusufx 0:1a89e28dea91 155 if (a==b)
yusufx 0:1a89e28dea91 156 return true;
yusufx 0:1a89e28dea91 157 if (!a != !b) // one is null and the other is not
yusufx 0:1a89e28dea91 158 return false;
yusufx 0:1a89e28dea91 159 if (a->length != b->length)
yusufx 0:1a89e28dea91 160 return false;
yusufx 0:1a89e28dea91 161
yusufx 0:1a89e28dea91 162 int i;
yusufx 0:1a89e28dea91 163 for (i = 0; i<a->length; i++)
yusufx 0:1a89e28dea91 164 if (a->data[i] != b->data[i])
yusufx 0:1a89e28dea91 165 return false;
yusufx 0:1a89e28dea91 166 return true;
yusufx 0:1a89e28dea91 167 }
yusufx 0:1a89e28dea91 168
yusufx 0:1a89e28dea91 169 struct byte_array *byte_array_copy(const struct byte_array* original) {
yusufx 0:1a89e28dea91 170 if (!original)
yusufx 0:1a89e28dea91 171 return NULL;
yusufx 0:1a89e28dea91 172 struct byte_array* copy = (struct byte_array*)malloc(sizeof(struct byte_array));
yusufx 0:1a89e28dea91 173 copy->data = (uint8_t*)malloc(original->length);
yusufx 0:1a89e28dea91 174 memcpy(copy->data, original->data, original->length);
yusufx 0:1a89e28dea91 175 copy->length = original->length;
yusufx 0:1a89e28dea91 176 copy->current = copy->data + (original->current - original->data);
yusufx 0:1a89e28dea91 177 return copy;
yusufx 0:1a89e28dea91 178 }
yusufx 0:1a89e28dea91 179
yusufx 0:1a89e28dea91 180 void byte_array_append(struct byte_array *a, const struct byte_array* b) {
yusufx 0:1a89e28dea91 181 null_check(a);
yusufx 0:1a89e28dea91 182 null_check(b);
yusufx 0:1a89e28dea91 183 uint32_t offset = a->length;
yusufx 0:1a89e28dea91 184 byte_array_resize(a, a->length + b->length);
yusufx 0:1a89e28dea91 185 memcpy(&a->data[offset], b->data, b->length);
yusufx 0:1a89e28dea91 186 a->current = a->data + a->length;
yusufx 0:1a89e28dea91 187 }
yusufx 0:1a89e28dea91 188
yusufx 0:1a89e28dea91 189 void byte_array_remove(struct byte_array *self, uint32_t start, int32_t length) {
yusufx 0:1a89e28dea91 190 self->data = (uint8_t*)list_remove(self->data, &self->length, start, length, sizeof(uint8_t));
yusufx 0:1a89e28dea91 191 }
yusufx 0:1a89e28dea91 192
yusufx 0:1a89e28dea91 193 struct byte_array *byte_array_part(struct byte_array *within, uint32_t start, uint32_t length)
yusufx 0:1a89e28dea91 194 {
yusufx 0:1a89e28dea91 195 struct byte_array *p = byte_array_copy(within);
yusufx 0:1a89e28dea91 196 byte_array_remove(p, start+length, within->length-start-length);
yusufx 0:1a89e28dea91 197 byte_array_remove(p, 0, start);
yusufx 0:1a89e28dea91 198 return p;
yusufx 0:1a89e28dea91 199 }
yusufx 0:1a89e28dea91 200
yusufx 0:1a89e28dea91 201 struct byte_array *byte_array_from_string(const char* str)
yusufx 0:1a89e28dea91 202 {
yusufx 0:1a89e28dea91 203 int len = strlen(str);
yusufx 0:1a89e28dea91 204 struct byte_array* ba = byte_array_new_size(len);
yusufx 0:1a89e28dea91 205 memcpy(ba->data, str, len);
yusufx 0:1a89e28dea91 206 return ba;
yusufx 0:1a89e28dea91 207 }
yusufx 0:1a89e28dea91 208
yusufx 0:1a89e28dea91 209 char* byte_array_to_string(const struct byte_array* ba)
yusufx 0:1a89e28dea91 210 {
yusufx 0:1a89e28dea91 211 int len = ba->length;
yusufx 0:1a89e28dea91 212 char* s = (char*)malloc(len+1);
yusufx 0:1a89e28dea91 213 memcpy(s, ba->data, len);
yusufx 0:1a89e28dea91 214 s[len] = 0;
yusufx 0:1a89e28dea91 215 return s;
yusufx 0:1a89e28dea91 216 }
yusufx 0:1a89e28dea91 217
yusufx 0:1a89e28dea91 218 void byte_array_reset(struct byte_array* ba) {
yusufx 0:1a89e28dea91 219 ba->current = ba->data;
yusufx 0:1a89e28dea91 220 }
yusufx 0:1a89e28dea91 221
yusufx 0:1a89e28dea91 222 struct byte_array *byte_array_concatenate(int n, const struct byte_array* ba, ...)
yusufx 0:1a89e28dea91 223 {
yusufx 0:1a89e28dea91 224 struct byte_array* result = byte_array_copy(ba);
yusufx 0:1a89e28dea91 225
yusufx 0:1a89e28dea91 226 va_list argp;
yusufx 0:1a89e28dea91 227 for(va_start(argp, ba); --n;) {
yusufx 0:1a89e28dea91 228 struct byte_array* parameter = va_arg(argp, struct byte_array* );
yusufx 0:1a89e28dea91 229 if (!parameter)
yusufx 0:1a89e28dea91 230 continue;
yusufx 0:1a89e28dea91 231 assert_message(result->length + parameter->length < BYTE_ARRAY_MAX_LEN, ERROR_BYTE_ARRAY_LEN);
yusufx 0:1a89e28dea91 232 byte_array_append(result, parameter);
yusufx 0:1a89e28dea91 233 }
yusufx 0:1a89e28dea91 234
yusufx 0:1a89e28dea91 235 va_end(argp);
yusufx 0:1a89e28dea91 236
yusufx 0:1a89e28dea91 237 if (result)
yusufx 0:1a89e28dea91 238 result->current = result->data + result->length;
yusufx 0:1a89e28dea91 239 return result;
yusufx 0:1a89e28dea91 240 }
yusufx 0:1a89e28dea91 241
yusufx 0:1a89e28dea91 242 struct byte_array *byte_array_add_byte(struct byte_array *a, uint8_t b) {
yusufx 0:1a89e28dea91 243 byte_array_resize(a, a->length+1);
yusufx 0:1a89e28dea91 244 a->current = a->data + a->length;
yusufx 0:1a89e28dea91 245 a->data[a->length-1] = b;
yusufx 0:1a89e28dea91 246 return a;
yusufx 0:1a89e28dea91 247 }
yusufx 0:1a89e28dea91 248
yusufx 0:1a89e28dea91 249 void byte_array_print(const char* text, const struct byte_array* ba) {
yusufx 0:1a89e28dea91 250 int offset = ba->current-ba->data;
yusufx 0:1a89e28dea91 251 if (text)
yusufx 0:1a89e28dea91 252 printf("%s @%d\n", text, offset);
yusufx 0:1a89e28dea91 253 for (int i=0; i<ba->length; i++)
yusufx 0:1a89e28dea91 254 printf("\t%s%d\n", i==offset?">":" ", ba->data[i]);
yusufx 0:1a89e28dea91 255 }
yusufx 0:1a89e28dea91 256
yusufx 0:1a89e28dea91 257 int32_t byte_array_find(struct byte_array *within, struct byte_array *sought, uint32_t start)
yusufx 0:1a89e28dea91 258 {
yusufx 0:1a89e28dea91 259 null_check(within);
yusufx 0:1a89e28dea91 260 null_check(sought);
yusufx 0:1a89e28dea91 261
yusufx 0:1a89e28dea91 262 uint32_t ws = within->length;
yusufx 0:1a89e28dea91 263 uint32_t ss = sought->length;
yusufx 0:1a89e28dea91 264 assert_message(start < within->length, "out of bounds");
yusufx 0:1a89e28dea91 265
yusufx 0:1a89e28dea91 266 uint8_t *wd = within->data;
yusufx 0:1a89e28dea91 267 uint8_t *sd = sought->data;
yusufx 0:1a89e28dea91 268 for (int32_t i=start; i<ws-ss+1; i++)
yusufx 0:1a89e28dea91 269 if (!memcmp(wd + i, sd, ss))
yusufx 0:1a89e28dea91 270 return i;
yusufx 0:1a89e28dea91 271
yusufx 0:1a89e28dea91 272 return -1;
yusufx 0:1a89e28dea91 273 }
yusufx 0:1a89e28dea91 274
yusufx 0:1a89e28dea91 275 struct byte_array *byte_array_replace(struct byte_array *within, struct byte_array *replacement, uint32_t start, int32_t length)
yusufx 0:1a89e28dea91 276 {
yusufx 0:1a89e28dea91 277 null_check(within);
yusufx 0:1a89e28dea91 278 null_check(replacement);
yusufx 0:1a89e28dea91 279 uint32_t ws = within->length;
yusufx 0:1a89e28dea91 280 assert_message(start < ws, "index out of bounds");
yusufx 0:1a89e28dea91 281 if (length < 0)
yusufx 0:1a89e28dea91 282 length = ws - start;
yusufx 0:1a89e28dea91 283
yusufx 0:1a89e28dea91 284 int32_t new_length = within->length - length + replacement->length;
yusufx 0:1a89e28dea91 285 struct byte_array *replaced = byte_array_new_size(new_length);
yusufx 0:1a89e28dea91 286
yusufx 0:1a89e28dea91 287 memcpy(replaced->data, within->data, start);
yusufx 0:1a89e28dea91 288 memcpy(replaced->data + start, replacement->data, replacement->length);
yusufx 0:1a89e28dea91 289 memcpy(replaced->data + start + replacement->length, within->data + start + length, within->length - start - length);
yusufx 0:1a89e28dea91 290
yusufx 0:1a89e28dea91 291 return replaced;
yusufx 0:1a89e28dea91 292 }
yusufx 0:1a89e28dea91 293
yusufx 0:1a89e28dea91 294
yusufx 0:1a89e28dea91 295 // stack ////////////////////////////////////////////////////////////////////
yusufx 0:1a89e28dea91 296
yusufx 0:1a89e28dea91 297 struct stack* stack_new() {
yusufx 0:1a89e28dea91 298 return (struct stack*)calloc(sizeof(struct stack), 1);
yusufx 0:1a89e28dea91 299 }
yusufx 0:1a89e28dea91 300
yusufx 0:1a89e28dea91 301 struct stack_node* stack_node_new() {
yusufx 0:1a89e28dea91 302 return (struct stack_node*)calloc(sizeof(struct stack_node), 1);
yusufx 0:1a89e28dea91 303 }
yusufx 0:1a89e28dea91 304
yusufx 0:1a89e28dea91 305 void stack_push(struct stack* stack, void* data)
yusufx 0:1a89e28dea91 306 {
yusufx 0:1a89e28dea91 307 null_check(data);
yusufx 0:1a89e28dea91 308 if (!stack->head)
yusufx 0:1a89e28dea91 309 stack->head = stack->tail = stack_node_new();
yusufx 0:1a89e28dea91 310 else {
yusufx 0:1a89e28dea91 311 struct stack_node* old_head = stack->head;
yusufx 0:1a89e28dea91 312 stack->head = stack_node_new();
yusufx 0:1a89e28dea91 313 null_check(stack->head);
yusufx 0:1a89e28dea91 314 stack->head->next = old_head;
yusufx 0:1a89e28dea91 315 }
yusufx 0:1a89e28dea91 316 stack->head->data = data;
yusufx 0:1a89e28dea91 317 }
yusufx 0:1a89e28dea91 318
yusufx 0:1a89e28dea91 319 void* stack_pop(struct stack* stack)
yusufx 0:1a89e28dea91 320 {
yusufx 0:1a89e28dea91 321 if (!stack->head)
yusufx 0:1a89e28dea91 322 return NULL;
yusufx 0:1a89e28dea91 323 void* data = stack->head->data;
yusufx 0:1a89e28dea91 324 stack->head = stack->head->next;
yusufx 0:1a89e28dea91 325 null_check(data);
yusufx 0:1a89e28dea91 326 return data;
yusufx 0:1a89e28dea91 327 }
yusufx 0:1a89e28dea91 328
yusufx 0:1a89e28dea91 329 void* stack_peek(const struct stack* stack, uint8_t index)
yusufx 0:1a89e28dea91 330 {
yusufx 0:1a89e28dea91 331 null_check(stack);
yusufx 0:1a89e28dea91 332 struct stack_node*p = stack->head;
yusufx 0:1a89e28dea91 333 for (; index && p; index--, p=p->next);
yusufx 0:1a89e28dea91 334 return p ? p->data : NULL;
yusufx 0:1a89e28dea91 335 }
yusufx 0:1a89e28dea91 336
yusufx 0:1a89e28dea91 337 bool stack_empty(const struct stack* stack)
yusufx 0:1a89e28dea91 338 {
yusufx 0:1a89e28dea91 339 null_check(stack);
yusufx 0:1a89e28dea91 340 return stack->head == NULL;// && stack->tail == NULL;
yusufx 0:1a89e28dea91 341 }
yusufx 0:1a89e28dea91 342
yusufx 0:1a89e28dea91 343 // map /////////////////////////////////////////////////////////////////////
yusufx 0:1a89e28dea91 344
yusufx 0:1a89e28dea91 345 static size_t def_hash_func(const struct byte_array* key)
yusufx 0:1a89e28dea91 346 {
yusufx 0:1a89e28dea91 347 size_t hash = 0;
yusufx 0:1a89e28dea91 348 int i = 0;
yusufx 0:1a89e28dea91 349 for (i = 0; i<key->length; i++)
yusufx 0:1a89e28dea91 350 hash += key->data[i];
yusufx 0:1a89e28dea91 351 return hash;
yusufx 0:1a89e28dea91 352 }
yusufx 0:1a89e28dea91 353
yusufx 0:1a89e28dea91 354 struct map* map_new()
yusufx 0:1a89e28dea91 355 {
yusufx 0:1a89e28dea91 356 struct map* m;
yusufx 0:1a89e28dea91 357 if (!(m =(struct map*)malloc(sizeof(struct map)))) return NULL;
yusufx 0:1a89e28dea91 358 m->size = 16;
yusufx 0:1a89e28dea91 359 m->hash_func = def_hash_func;
yusufx 0:1a89e28dea91 360
yusufx 0:1a89e28dea91 361 if (!(m->nodes = (struct hash_node**)calloc(m->size, sizeof(struct hash_node*)))) {
yusufx 0:1a89e28dea91 362 free(m);
yusufx 0:1a89e28dea91 363 return NULL;
yusufx 0:1a89e28dea91 364 }
yusufx 0:1a89e28dea91 365
yusufx 0:1a89e28dea91 366 return m;
yusufx 0:1a89e28dea91 367 }
yusufx 0:1a89e28dea91 368
yusufx 0:1a89e28dea91 369 void map_del(struct map* m)
yusufx 0:1a89e28dea91 370 {
yusufx 0:1a89e28dea91 371 DEBUGPRINT("map_destroy\n");
yusufx 0:1a89e28dea91 372 size_t n;
yusufx 0:1a89e28dea91 373 struct hash_node *node, *oldnode;
yusufx 0:1a89e28dea91 374
yusufx 0:1a89e28dea91 375 for(n = 0; n<m->size; ++n) {
yusufx 0:1a89e28dea91 376 node = m->nodes[n];
yusufx 0:1a89e28dea91 377 while (node) {
yusufx 0:1a89e28dea91 378 byte_array_del(node->key);
yusufx 0:1a89e28dea91 379 oldnode = node;
yusufx 0:1a89e28dea91 380 node = node->next;
yusufx 0:1a89e28dea91 381 free(oldnode);
yusufx 0:1a89e28dea91 382 }
yusufx 0:1a89e28dea91 383 }
yusufx 0:1a89e28dea91 384 free(m->nodes);
yusufx 0:1a89e28dea91 385 free(m);
yusufx 0:1a89e28dea91 386 }
yusufx 0:1a89e28dea91 387
yusufx 0:1a89e28dea91 388 int map_insert(struct map* m, const struct byte_array* key, void *data)
yusufx 0:1a89e28dea91 389 {
yusufx 0:1a89e28dea91 390 struct hash_node *node;
yusufx 0:1a89e28dea91 391 size_t hash = m->hash_func(key) % m->size;
yusufx 0:1a89e28dea91 392
yusufx 0:1a89e28dea91 393 node = m->nodes[hash];
yusufx 0:1a89e28dea91 394 while (node) {
yusufx 0:1a89e28dea91 395 if (byte_array_equals(node->key, key)) {
yusufx 0:1a89e28dea91 396 node->data = data;
yusufx 0:1a89e28dea91 397 return 0;
yusufx 0:1a89e28dea91 398 }
yusufx 0:1a89e28dea91 399 node = node->next;
yusufx 0:1a89e28dea91 400 }
yusufx 0:1a89e28dea91 401
yusufx 0:1a89e28dea91 402 if (!(node = (struct hash_node*)malloc(sizeof(struct hash_node))))
yusufx 0:1a89e28dea91 403 return -1;
yusufx 0:1a89e28dea91 404 if (!(node->key = byte_array_copy(key))) {
yusufx 0:1a89e28dea91 405 free(node);
yusufx 0:1a89e28dea91 406 return -1;
yusufx 0:1a89e28dea91 407 }
yusufx 0:1a89e28dea91 408 node->data = data;
yusufx 0:1a89e28dea91 409 node->next = m->nodes[hash];
yusufx 0:1a89e28dea91 410 m->nodes[hash] = node;
yusufx 0:1a89e28dea91 411
yusufx 0:1a89e28dea91 412 return 0;
yusufx 0:1a89e28dea91 413 }
yusufx 0:1a89e28dea91 414
yusufx 0:1a89e28dea91 415 struct array* map_keys(const struct map* m) {
yusufx 0:1a89e28dea91 416 struct array *a = array_new();
yusufx 0:1a89e28dea91 417 for (int i=0; i<m->size; i++)
yusufx 0:1a89e28dea91 418 for (const struct hash_node* n = m->nodes[i]; n; n=n->next)
yusufx 0:1a89e28dea91 419 if (n->data)
yusufx 0:1a89e28dea91 420 array_add(a, n->key);
yusufx 0:1a89e28dea91 421 return a;
yusufx 0:1a89e28dea91 422 }
yusufx 0:1a89e28dea91 423
yusufx 0:1a89e28dea91 424 struct array* map_values(const struct map* m) {
yusufx 0:1a89e28dea91 425 struct array *a = array_new();
yusufx 0:1a89e28dea91 426 for (int i=0; i<m->size; i++)
yusufx 0:1a89e28dea91 427 for (const struct hash_node* n = m->nodes[i]; n; n=n->next)
yusufx 0:1a89e28dea91 428 if (n->data)
yusufx 0:1a89e28dea91 429 array_add(a, n->data);
yusufx 0:1a89e28dea91 430 return a;
yusufx 0:1a89e28dea91 431 }
yusufx 0:1a89e28dea91 432
yusufx 0:1a89e28dea91 433 int map_remove(struct map* m, const struct byte_array* key)
yusufx 0:1a89e28dea91 434 {
yusufx 0:1a89e28dea91 435 struct hash_node *node, *prevnode = NULL;
yusufx 0:1a89e28dea91 436 size_t hash = m->hash_func(key)%m->size;
yusufx 0:1a89e28dea91 437
yusufx 0:1a89e28dea91 438 node = m->nodes[hash];
yusufx 0:1a89e28dea91 439 while(node) {
yusufx 0:1a89e28dea91 440 if (byte_array_equals(node->key, key)) {
yusufx 0:1a89e28dea91 441 byte_array_del(node->key);
yusufx 0:1a89e28dea91 442 if (prevnode) prevnode->next = node->next;
yusufx 0:1a89e28dea91 443 else m->nodes[hash] = node->next;
yusufx 0:1a89e28dea91 444 free(node);
yusufx 0:1a89e28dea91 445 return 0;
yusufx 0:1a89e28dea91 446 }
yusufx 0:1a89e28dea91 447 prevnode = node;
yusufx 0:1a89e28dea91 448 node = node->next;
yusufx 0:1a89e28dea91 449 }
yusufx 0:1a89e28dea91 450 return -1;
yusufx 0:1a89e28dea91 451 }
yusufx 0:1a89e28dea91 452
yusufx 0:1a89e28dea91 453 bool map_has(const struct map* m, const struct byte_array* key) {
yusufx 0:1a89e28dea91 454 struct hash_node *node;
yusufx 0:1a89e28dea91 455 size_t hash = m->hash_func(key) % m->size;
yusufx 0:1a89e28dea91 456 node = m->nodes[hash];
yusufx 0:1a89e28dea91 457 while (node) {
yusufx 0:1a89e28dea91 458 if (byte_array_equals(node->key, key))
yusufx 0:1a89e28dea91 459 return true;
yusufx 0:1a89e28dea91 460 node = node->next;
yusufx 0:1a89e28dea91 461 }
yusufx 0:1a89e28dea91 462 return false;
yusufx 0:1a89e28dea91 463 }
yusufx 0:1a89e28dea91 464
yusufx 0:1a89e28dea91 465 void *map_get(const struct map* m, const struct byte_array* key)
yusufx 0:1a89e28dea91 466 {
yusufx 0:1a89e28dea91 467 struct hash_node *node;
yusufx 0:1a89e28dea91 468 size_t hash = m->hash_func(key) % m->size;
yusufx 0:1a89e28dea91 469 node = m->nodes[hash];
yusufx 0:1a89e28dea91 470 while (node) {
yusufx 0:1a89e28dea91 471 if (byte_array_equals(node->key, key))
yusufx 0:1a89e28dea91 472 return node->data;
yusufx 0:1a89e28dea91 473 node = node->next;
yusufx 0:1a89e28dea91 474 }
yusufx 0:1a89e28dea91 475 return NULL;
yusufx 0:1a89e28dea91 476 }
yusufx 0:1a89e28dea91 477
yusufx 0:1a89e28dea91 478 int map_resize(struct map* m, size_t size)
yusufx 0:1a89e28dea91 479 {
yusufx 0:1a89e28dea91 480 DEBUGPRINT("map_resize\n");
yusufx 0:1a89e28dea91 481 struct map newtbl;
yusufx 0:1a89e28dea91 482 size_t n;
yusufx 0:1a89e28dea91 483 struct hash_node *node,*next;
yusufx 0:1a89e28dea91 484
yusufx 0:1a89e28dea91 485 newtbl.size = size;
yusufx 0:1a89e28dea91 486 newtbl.hash_func = m->hash_func;
yusufx 0:1a89e28dea91 487
yusufx 0:1a89e28dea91 488 if (!(newtbl.nodes = (struct hash_node**)calloc(size, sizeof(struct hash_node*))))
yusufx 0:1a89e28dea91 489 return -1;
yusufx 0:1a89e28dea91 490
yusufx 0:1a89e28dea91 491 for(n = 0; n<m->size; ++n) {
yusufx 0:1a89e28dea91 492 for(node = m->nodes[n]; node; node = next) {
yusufx 0:1a89e28dea91 493 next = node->next;
yusufx 0:1a89e28dea91 494 map_insert(&newtbl, node->key, node->data);
yusufx 0:1a89e28dea91 495 map_remove(m, node->key);
yusufx 0:1a89e28dea91 496
yusufx 0:1a89e28dea91 497 }
yusufx 0:1a89e28dea91 498 }
yusufx 0:1a89e28dea91 499
yusufx 0:1a89e28dea91 500 free(m->nodes);
yusufx 0:1a89e28dea91 501 m->size = newtbl.size;
yusufx 0:1a89e28dea91 502 m->nodes = newtbl.nodes;
yusufx 0:1a89e28dea91 503
yusufx 0:1a89e28dea91 504 return 0;
yusufx 0:1a89e28dea91 505 }
yusufx 0:1a89e28dea91 506
yusufx 0:1a89e28dea91 507 // in case of intersection, a wins
yusufx 0:1a89e28dea91 508 void map_update(struct map *a, const struct map *b)
yusufx 0:1a89e28dea91 509 {
yusufx 0:1a89e28dea91 510 const struct array *keys = map_keys(b);
yusufx 0:1a89e28dea91 511 for (int i=0; i<keys->length; i++) {
yusufx 0:1a89e28dea91 512 const struct byte_array *key = (const struct byte_array*)array_get(keys, i);
yusufx 0:1a89e28dea91 513 if (!map_has(a, key))
yusufx 0:1a89e28dea91 514 map_insert(a, key, map_get(b, key));
yusufx 0:1a89e28dea91 515 }
yusufx 0:1a89e28dea91 516 }