18a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/* 28a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org> 38a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 48a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This program is free software; you can redistribute it and/or modify it 58a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * under the terms of the GNU General Public License as published by 68a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the Free Software Foundation; either version 2 of the License, or 78a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * (at your option) any later version. 88a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */ 98a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <stdio.h> 118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <stdlib.h> 128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <string.h> 138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <errno.h> 148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include "internal/stack.h" 168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 178a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct stack { 188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar int num_elems; 198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar int max_elems; 208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar size_t elem_size; 218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar char *data; 228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}; 238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 248a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct stack *stack_create(size_t elem_size, int max_elems) 258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar struct stack *s; 278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar s = calloc(sizeof(struct stack), 1); 298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar if (s == NULL) 308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return NULL; 318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar s->data = calloc(elem_size * max_elems, 1); 338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar if (s->data == NULL) { 348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar free(s); 358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return NULL; 368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar } 378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar s->elem_size = elem_size; 388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar s->max_elems = max_elems; 398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return s; 418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 438a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid stack_destroy(struct stack *s) 448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar free(s->data); 468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar free(s); 478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 498a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint stack_push(struct stack *s, void *data) 508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar if (s->num_elems >= s->max_elems) { 528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar errno = ENOSPC; 538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return -1; 548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar } 558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(s->data + (s->elem_size * s->num_elems), data, s->elem_size); 568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar s->num_elems++; 578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return 0; 588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar 608a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint stack_pop(struct stack *s, void *data) 618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{ 628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar if (s->num_elems <= 0) { 638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar errno = EINVAL; 648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return -1; 658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar } 668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar s->num_elems--; 678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar memcpy(data, s->data + (s->elem_size * s->num_elems), s->elem_size); 688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar return 0; 698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar} 70