/*Noam Litman $Id: listmap.c,v 1.1 2007-05-29-07 nlitman - $*/ /* * DESCRIPTION * Map and iterator represented as a list. */ #include #include #include #include #include "auxdefs.h" #include "listmap.h" #define xprintf (void) printf static char *listmap_tag = "struct listmap"; static char *listmap_itor_tag = "struct listmap_itor"; static char *listmap_node_tag = "struct listmap_node"; typedef struct listmap_node *listmap_node_ref; struct listmap { char *tag; listmap_node_ref head; }; struct listmap_itor { char *tag; listmap_node_ref curr; }; struct listmap_node { char *tag; map_key_t key; map_value_t value; listmap_node_ref link; }; static bool is_listmap (listmap_ref map) { return map != NULL && map->tag == listmap_tag; } static bool isempty_listmap(listmap_ref map){ return map->head == NULL; } listmap_ref new_listmap (void) { listmap_ref map = malloc (sizeof (struct listmap)); assert (map != NULL); map->tag = listmap_tag; map->head = NULL; return map; } void free_listmap (listmap_ref map) { listmap_node_ref curr; listmap_node_ref temp; assert (is_listmap (map)); curr = map->head; while(curr != NULL){ temp = curr->link; free(curr->key); free(curr->value); free(curr); curr = temp; } bzero(map, sizeof(struct listmap)); free(map); } map_value_t get_listmap (listmap_ref map, map_key_t key) { listmap_node_ref current; assert (is_listmap (map)); current = map->head; while(current!= NULL){ if(strcmp(current->key, key)==0){ return current->value; }else{ current = current->link; } } return NULL; } map_value_t get_listmap (listmap_ref map, map_key_t key) { listmap_node_ref current; assert (is_listmap (map)); current = map->head; while(current!= NULL){ if(strcmp(current->key, key)==0){ return current->value; }else{ current = current->link; } } return NULL; } map_value_t put_listmap (listmap_ref map, map_key_t key, map_value_t value) { /*set prev curr and new nodes */ listmap_node_ref curr = NULL; listmap_node_ref prev = NULL; listmap_node_ref new; assert (is_listmap (map)); /*assert the map is actually a map*/ /*if the map is empty allocate a new node and insert it into the list *you must set its tag key and value and return NULL because there is *nothing to be found*/ if(map->head == NULL && value != NULL){ listmap_node_ref new = malloc(sizeof(struct listmap_node)); assert(new != NULL); map->head = new; new->link = NULL; new->tag = listmap_node_tag; new->key = strdup(key); new->value = strdup(value); return NULL; } /*have curr point at the head of the map and while its not equal to null *compare the keys if its great then 0 break and insert if its equal *replace curr's value and duplicate the new value and set it too curr. *then return curr's old value*/ curr = map->head; while (curr != NULL){ if(strcmp(curr->key, key)>0){ break; } if(strcmp(curr->key, key)==0){ if(value == NULL){ char *oldvalue; if(prev!=NULL){ prev ->link = curr->link; }else{ map->head = curr->link; } oldvalue = curr->value; free(curr->key); free(curr); return oldvalue; }else{ char *oldval = curr->value; curr->value = strdup(value); return oldval; } } prev = curr; curr = curr->link; } if(value == NULL){ return NULL; } /*have new's link point to curr allocate it and set its key value and tag *if previous points to nothing then have the head of map point to new *otherwise the link of previous is goign to point to new. Return NULL *if nothing is found*/ new = malloc(sizeof(struct listmap_node)); new->key = strdup(key); new->tag = listmap_node_tag; new->value = strdup(value); new->link = curr; if(prev == NULL){ map->head = new; }else{ prev->link = new; } return NULL; } static bool is_listmap_itor (listmap_itor_ref itor) { return itor != NULL && itor->tag == listmap_itor_tag; } listmap_itor_ref new_listmap_itor (listmap_ref map) { listmap_itor_ref itor = malloc (sizeof (struct listmap_itor)); assert (itor != NULL); itor->tag = listmap_itor_tag; itor->curr = map->head; return itor; } void free_listmap_itor (listmap_itor_ref itor) { assert (is_listmap_itor (itor)); bzero (itor, sizeof (struct listmap_itor)); free (itor); } bool hascurr_listmap_itor (listmap_itor_ref itor) { assert (is_listmap_itor (itor)); return itor->curr != NULL; } void next_listmap_itor (listmap_itor_ref itor) { assert (is_listmap_itor (itor)); itor->curr = itor->curr->link; } map_key_t get_key_listmap_itor (listmap_itor_ref itor) { assert (is_listmap_itor (itor)); return itor->curr->key; } map_value_t get_value_listmap_itor (listmap_itor_ref itor) { assert (is_listmap_itor (itor)); return itor->curr->value; } RCSC(LISTMAP_C,"$Id: listmap.c,v 1.1 2007-05-27 21:04:59-07 - - $")