1 /* $NetBSD: prop_stack.c,v 1.2 2007/08/30 12:23:54 joerg Exp $ */ 2 3 /*- 4 * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include "prop_stack.h" 33 #include "prop_object_impl.h" 34 35 void 36 _prop_stack_init(prop_stack_t stack) 37 { 38 stack->used_intern_elems = 0; 39 SLIST_INIT(&stack->extern_elems); 40 } 41 42 bool 43 _prop_stack_push(prop_stack_t stack, prop_object_t obj, void *data1, 44 void *data2, void *data3) 45 { 46 struct _prop_stack_extern_elem *eelem; 47 struct _prop_stack_intern_elem *ielem; 48 49 if (stack->used_intern_elems == PROP_STACK_INTERN_ELEMS) { 50 eelem = _PROP_MALLOC(sizeof(*eelem), M_TEMP); 51 52 if (eelem == NULL) 53 return false; 54 55 eelem->object = obj; 56 eelem->object_data[0] = data1; 57 eelem->object_data[1] = data2; 58 eelem->object_data[2] = data3; 59 60 SLIST_INSERT_HEAD(&stack->extern_elems, eelem, stack_link); 61 62 return true; 63 } 64 65 _PROP_ASSERT(stack->used_intern_elems < PROP_STACK_INTERN_ELEMS); 66 _PROP_ASSERT(SLIST_EMPTY(&stack->extern_elems)); 67 68 ielem = &stack->intern_elems[stack->used_intern_elems]; 69 ielem->object = obj; 70 ielem->object_data[0] = data1; 71 ielem->object_data[1] = data2; 72 ielem->object_data[2] = data3; 73 74 ++stack->used_intern_elems; 75 76 return true; 77 } 78 79 bool 80 _prop_stack_pop(prop_stack_t stack, prop_object_t *obj, void **data1, 81 void **data2, void **data3) 82 { 83 struct _prop_stack_extern_elem *eelem; 84 struct _prop_stack_intern_elem *ielem; 85 86 if (stack->used_intern_elems == 0) 87 return false; 88 89 if ((eelem = SLIST_FIRST(&stack->extern_elems)) != NULL) { 90 _PROP_ASSERT(stack->used_intern_elems == PROP_STACK_INTERN_ELEMS); 91 92 SLIST_REMOVE_HEAD(&stack->extern_elems, stack_link); 93 if (obj) 94 *obj = eelem->object; 95 if (data1) 96 *data1 = eelem->object_data[0]; 97 if (data2) 98 *data2 = eelem->object_data[1]; 99 if (data3) 100 *data3 = eelem->object_data[2]; 101 _PROP_FREE(eelem, M_TEMP); 102 return true; 103 } 104 105 --stack->used_intern_elems; 106 ielem = &stack->intern_elems[stack->used_intern_elems]; 107 108 if (obj) 109 *obj = ielem->object; 110 if (data1) 111 *data1 = ielem->object_data[0]; 112 if (data2) 113 *data2 = ielem->object_data[1]; 114 if (data3) 115 *data3 = ielem->object_data[2]; 116 117 return true; 118 } 119