#include #include #include #include "request_list.h" struct _rlist { int size; int max; request *items; }; struct _rlist_iterator { rlist *el; int curr; }; rlist *rlist_create(int max) { rlist *el = malloc(sizeof(rlist)); if (el != NULL) { // initialize size and max el->size = 0; el->max = max; // create an array big enough for max-sized list el->items = malloc(sizeof(request) * max); if (el->items == NULL) { free(el); return NULL; } } return el; } void rlist_destroy(rlist *el) { if (el != NULL) { // free the array and all the copies of the data it has // pointers to for (int i = 0; i < el->size; i++) { free(el->items[i].user); free(el->items[i].position); } free(el->items); // zero out the list to make it more obviously incorrect if // someone tries to use a destroyed list el->items = NULL; el->size = 0; // free the list free(el); } } int rlist_size(const rlist *el) { if (el != NULL) { return el->size; } else { return 0; } } bool rlist_add(rlist *el, const request *r) { if (el == NULL || el->size == el->max || r == NULL || r->user == NULL || r->position == NULL) { return false; } else { // copy the data el->items[el->size].user = malloc(sizeof(char) * (strlen(r->user) + 1)); el->items[el->size].position = malloc(sizeof(char) * (strlen(r->position) + 1)); if (el->items[el->size].user == NULL || el->items[el->size].position == NULL) { free(el->items[el->size].user); free(el->items[el->size].position); return false; } strcpy(el->items[el->size].user, r->user); strcpy(el->items[el->size].position, r->position); // update size el->size++; return true; } } void rlist_get(const rlist *el, int i, request *r) { // check preconditions if (el == NULL || r == NULL || i < 0 || i >= el->size) { return; } // copy data from index i into request pointed to by r r->user = malloc(strlen(el->items[i].user) + 1); r->position = malloc(strlen(el->items[i].position) + 1); if (r->user != NULL && r->position != NULL) { strcpy(r->position, el->items[i].position); strcpy(r->user, el->items[i].user); } else { // error allocating space for copy of data free(r->user); free(r->position); r->user = NULL; r->position = NULL; } } rlist_iterator *rlist_start(rlist *el) { // check preconditions if (el == NULL) { return NULL; } // allocate space and initialize to 1st data node (node after dummy head) rlist_iterator *i = malloc(sizeof(rlist_iterator)); if (i != NULL) { i->el = el; i->curr = 0; } return i; } rlist_iterator *rlist_iterator_copy(rlist_iterator *i) { // check preconditions if (i == NULL) { return NULL; } // allocate space and copy from existing iterator rlist_iterator *j = malloc(sizeof(rlist_iterator)); if (j != NULL) { j->el = i->el; j->curr = i->curr; } return j; } bool rlist_iterator_at_end(const rlist_iterator *i) { return i != NULL && i->curr == i->el->size; } void rlist_iterator_next(rlist_iterator *i) { if (!rlist_iterator_at_end(i)) { i->curr++; } } bool rlist_iterator_before_start(const rlist_iterator *i) { return i != NULL && i->curr < 0; } void rlist_iterator_prev(rlist_iterator *i) { if (!rlist_iterator_before_start(i)) { i->curr--; } } void rlist_iterator_destroy(rlist_iterator *i) { free(i); } void rlist_iterator_get(const rlist_iterator *i, request *r) { if (!rlist_iterator_at_end(i) && r != NULL) { r->user = malloc(strlen(i->el->items[i->curr].user) + 1); r->position = malloc(strlen(i->el->items[i->curr].position) + 1); if (r->user != NULL && r->position != NULL) { strcpy(r->user, i->el->items[i->curr].user); strcpy(r->position, i->el->items[i->curr].position); } else { // malloc failed free(r->user); free(r->position); r->user = NULL; r->position = NULL; } } } void rlist_iterator_remove(rlist_iterator *i) { if (!rlist_iterator_at_end(i)) { // free data to remove free(i->el->items[i->curr].user); free(i->el->items[i->curr].position); // copy items back one space for (int copy_from = i->curr + 1; copy_from < i->el->size; copy_from++) { i->el->items[copy_from - 1] = i->el->items[copy_from]; } i->el->size--; } }