1 /*************************************************************************/ 2 /* module: XLT Decoder Stack */ 3 /* file: XLTUtilStack.c */ 4 /* target system: all */ 5 /* target OS: all */ 6 /*************************************************************************/ 7 8 /* 9 * Copyright Notice 10 * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication 11 * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., 12 * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). 13 * All Rights Reserved. 14 * Implementation of all or part of any Specification may require 15 * licenses under third party intellectual property rights, 16 * including without limitation, patent rights (such a third party 17 * may or may not be a Supporter). The Sponsors of the Specification 18 * are not responsible and shall not be held responsible in any 19 * manner for identifying or failing to identify any or all such 20 * third party intellectual property rights. 21 * 22 * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED 23 * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, 24 * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, 25 * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML 26 * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 27 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 28 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 29 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 30 * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., 31 * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY 32 * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF 33 * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF 34 * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, 35 * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH 36 * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED 37 * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. 38 * 39 * The above notice and this paragraph must be included on all copies 40 * of this document that are made. 41 * 42 */ 43 44 /** 45 * A simple array-based stack implementation. 46 */ 47 48 /*************************************************************************/ 49 /* Definitions */ 50 /*************************************************************************/ 51 52 #include "xltdeccom.h" 53 #include "xltutilstack.h" 54 55 #include <smlerr.h> 56 57 #include <libmem.h> 58 59 struct ArrayStack_s; 60 typedef struct ArrayStack_s *ArrayStackPtr_t, ArrayStack_t; 61 struct ArrayStack_s 62 { 63 /* public */ 64 Ret_t (*top)(const XltUtilStackPtr_t, XltUtilStackItem_t *); 65 Ret_t (*pop)(XltUtilStackPtr_t, XltUtilStackItem_t *); 66 Ret_t (*push)(XltUtilStackPtr_t, const XltUtilStackItem_t); 67 Ret_t (*destroy)(XltUtilStackPtr_t); 68 69 /* private */ 70 Long_t topidx; // index of the top of the stack 71 Long_t size; // size of the stack (multiple of chunksize) 72 Long_t chunksize; // size of memory chunks allocated at a time 73 XltUtilStackItem_t *array; // the stack itself 74 }; 75 76 static Ret_t _top(const XltUtilStackPtr_t, XltUtilStackItem_t *); 77 static Ret_t _pop(XltUtilStackPtr_t, XltUtilStackItem_t *); 78 static Ret_t _push(XltUtilStackPtr_t, const XltUtilStackItem_t); 79 static Ret_t _destroy(XltUtilStackPtr_t); 80 81 /*************************************************************************/ 82 /* External Functions */ 83 /*************************************************************************/ 84 85 Ret_t 86 xltUtilCreateStack(XltUtilStackPtr_t *ppStack, const Long_t size) 87 { 88 ArrayStackPtr_t pStack; 89 90 if (size <= 0) 91 return SML_ERR_WRONG_PARAM; 92 if ((pStack = (ArrayStackPtr_t)smlLibMalloc(sizeof(ArrayStack_t))) == NULL) { 93 *ppStack = NULL; 94 return SML_ERR_NOT_ENOUGH_SPACE; 95 } 96 97 pStack->top = _top; 98 pStack->pop = _pop; 99 pStack->push = _push; 100 pStack->destroy = _destroy; 101 pStack->topidx = -1; 102 pStack->size = size; 103 pStack->chunksize = size; 104 pStack->array = NULL; 105 if ((pStack->array = (XltUtilStackItem_t*)smlLibMalloc(size * sizeof(XltUtilStackItem_t))) == NULL) { 106 *ppStack = NULL; 107 smlLibFree(pStack); 108 return SML_ERR_NOT_ENOUGH_SPACE; 109 } 110 111 *ppStack = (XltUtilStackPtr_t)pStack; 112 113 114 115 return SML_ERR_OK; 116 } 117 118 /*************************************************************************/ 119 /* Internal Functions */ 120 /*************************************************************************/ 121 122 static Ret_t 123 _top(const XltUtilStackPtr_t pStack, XltUtilStackItem_t *itemPtr) 124 { 125 ArrayStackPtr_t pStackPriv = (ArrayStackPtr_t)pStack; 126 127 if (pStackPriv->topidx == -1) 128 return SML_ERR_WRONG_USAGE; 129 130 *itemPtr = pStackPriv->array[pStackPriv->topidx]; 131 132 return SML_ERR_OK; 133 } 134 135 static Ret_t 136 _pop(XltUtilStackPtr_t pStack, XltUtilStackItem_t *itemPtr) 137 { 138 ArrayStackPtr_t pStackPriv = (ArrayStackPtr_t)pStack; 139 XltUtilStackItem_t item; 140 141 if (pStackPriv->topidx == -1) 142 return SML_ERR_WRONG_USAGE; 143 144 item = pStackPriv->array[pStackPriv->topidx]; 145 pStackPriv->topidx--; 146 147 if ((pStackPriv->topidx >= 0) && 148 (pStackPriv->topidx < pStackPriv->size - pStackPriv->chunksize)) { 149 Long_t newsize; 150 XltUtilStackItem_t *newarray; 151 152 newsize = pStackPriv->size - pStackPriv->chunksize; 153 if ((newarray = (XltUtilStackItem_t*)smlLibRealloc(pStackPriv->array, 154 newsize * sizeof(XltUtilStackItem_t))) != NULL) { 155 pStackPriv->size = newsize; 156 pStackPriv->array = newarray; 157 } else { 158 return SML_ERR_NOT_ENOUGH_SPACE; 159 } 160 } 161 162 *itemPtr = item; 163 164 return SML_ERR_OK; 165 } 166 167 static Ret_t 168 _push(XltUtilStackPtr_t pStack, const XltUtilStackItem_t item) 169 { 170 ArrayStackPtr_t pStackPriv = (ArrayStackPtr_t)pStack; 171 172 if (pStackPriv->topidx == pStackPriv->size - 1) { 173 Long_t newsize; 174 XltUtilStackItem_t *newarray; 175 176 newsize = pStackPriv->size + pStackPriv->chunksize; 177 if ((newarray = (XltUtilStackItem_t*)smlLibRealloc(pStackPriv->array, 178 newsize * sizeof(XltUtilStackItem_t))) != NULL) { 179 pStackPriv->size = newsize; 180 pStackPriv->array = newarray; 181 } else { 182 return SML_ERR_NOT_ENOUGH_SPACE; 183 } 184 } 185 186 pStackPriv->topidx++; 187 pStackPriv->array[pStackPriv->topidx] = item; 188 189 return SML_ERR_OK; 190 } 191 192 static Ret_t 193 _destroy(XltUtilStackPtr_t pStack) 194 { 195 ArrayStackPtr_t pStackPriv; 196 197 if (pStack == NULL) 198 return SML_ERR_OK; 199 200 pStackPriv = (ArrayStackPtr_t)pStack; 201 202 smlLibFree(pStackPriv->array); 203 smlLibFree(pStackPriv); 204 return SML_ERR_OK; 205 } 206