coan 4.2.4
|
00001 /*************************************************************************** 00002 * Copyright (C) 2004, 2006 Symbian Software Ltd. * 00003 * All rights reserved. * 00004 * * 00005 * Contributed originally by Mike Kinghan, imk@strudl.org * 00006 * * 00007 * Redistribution and use in source and binary forms, with or without * 00008 * modification, are permitted provided that the following conditions * 00009 * are met: * 00010 * * 00011 * Redistributions of source code must retain the above copyright * 00012 * notice, this list of conditions and the following disclaimer. * 00013 * * 00014 * Redistributions in binary form must reproduce the above copyright * 00015 * notice, this list of conditions and the following disclaimer in the * 00016 * documentation and/or other materials provided with the distribution. * 00017 * * 00018 * Neither the name of Symbian Software Ltd. nor the names of its * 00019 * contributors may be used to endorse or promote products derived from * 00020 * this software without specific prior written permission. * 00021 * * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 00028 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * 00029 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * 00030 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* 00031 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * 00032 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 00033 * DAMAGE. * 00034 * * 00035 **************************************************************************/ 00036 #include "ptr_vector.h" 00037 #include "report.h" 00038 #include "swiss_army.h" 00039 00047 00049 struct ptr_vector { 00052 size_t tranch; 00054 size_t count; 00057 size_t cap; 00059 dtor_t dtor; 00061 cloner_t cloner; 00063 void **ptrs; 00064 }; 00065 00071 static void * 00072 default_cloner(void const * src) 00073 { 00074 return clone(src,0); 00075 } 00076 00086 static void 00087 ptr_vector_init(ptr_vector_h pv, dtor_t dtor, cloner_t cloner) 00088 { 00089 pv->cap = pv->count = 0; 00090 pv->tranch = 16 * sizeof(void *); 00091 pv->dtor = dtor ? dtor : free; 00092 pv->cloner = cloner ? cloner : default_cloner; 00093 pv->ptrs = NULL; 00094 } 00095 00103 static void 00104 ptr_vector_copy_init(ptr_vector_h dest, ptr_vector_const_h src) 00105 { 00106 void const ** begin = ptr_vector_begin_const(src); 00107 void const **end = ptr_vector_end_const(src); 00108 cloner_t cloner = src->cloner; 00109 ptr_vector_init(dest,src->dtor,src->cloner); 00110 begin = ptr_vector_begin_const(src); 00111 end = ptr_vector_end_const(src); 00112 for ( ; begin != end; ++begin) { 00113 ptr_vector_append(dest,cloner(*begin)); 00114 } 00115 } 00116 00120 static void 00121 ptr_vector_finis(ptr_vector_h pv) 00122 { 00123 if (pv->ptrs) { 00124 void **begin = pv->ptrs; 00125 void **end = pv->ptrs + pv->count; 00126 for ( ; begin != end; ++begin) { 00127 pv->dtor(*begin); 00128 } 00129 free(pv->ptrs); 00130 pv->ptrs = NULL; 00131 } 00132 } 00133 00136 /* API **************************************************************/ 00137 00140 00141 ptr_vector_h 00142 ptr_vector_new(dtor_t dtor, cloner_t cloner) 00143 { 00144 ptr_vector_h pv = zallocate(sizeof(struct ptr_vector)); 00145 ptr_vector_init(pv,dtor,cloner); 00146 return pv; 00147 } 00148 00149 void 00150 ptr_vector_dispose(ptr_vector_h pv) 00151 { 00152 if (pv) { 00153 ptr_vector_finis(pv); 00154 free(pv); 00155 } 00156 } 00157 00158 void 00159 ptr_vector_drop(ptr_vector_h pv) 00160 { 00161 if (pv) { 00162 free(pv); 00163 } 00164 } 00165 00166 ptr_vector_h 00167 ptr_vector_copy(ptr_vector_const_h src) 00168 { 00169 ptr_vector_h pv; 00170 assert(src); 00171 pv = zallocate(sizeof(struct ptr_vector)); 00172 ptr_vector_copy_init(pv,src); 00173 return pv; 00174 } 00175 00176 void 00177 ptr_vector_swap(ptr_vector_h lhs, ptr_vector_h rhs) 00178 { 00179 assert(lhs); 00180 assert(rhs); 00181 PODSWAP(size_t,&lhs->tranch,&rhs->tranch); 00182 PODSWAP(size_t,&lhs->count,&rhs->count); 00183 PODSWAP(size_t,&lhs->cap,&rhs->cap); 00184 PODSWAP(dtor_t,&lhs->dtor,&rhs->dtor); 00185 PODSWAP(cloner_t,&lhs->cloner,&rhs->cloner); 00186 PODSWAP(void **,&lhs->ptrs,&rhs->ptrs); 00187 } 00188 00189 void 00190 ptr_vector_assign(ptr_vector_h dest, ptr_vector_const_h src) 00191 { 00192 if (dest != src) { 00193 ptr_vector_h tmp = ptr_vector_copy(src); 00194 ptr_vector_swap(dest,tmp); 00195 ptr_vector_dispose(tmp); 00196 } 00197 } 00198 00199 void 00200 ptr_vector_insert(ptr_vector_h pv, size_t pos, void const *ptr) 00201 { 00202 if (pv->count == pv->cap) { 00203 pv->cap += pv->tranch; 00204 pv->ptrs = reallocate(pv->ptrs,pv->cap * sizeof(void *)); 00205 pv->tranch <<= 1; 00206 } 00207 if (pos >= pv->count) { 00208 pv->ptrs[pv->count++] = (void*)ptr; 00209 } else { 00210 memmove(pv->ptrs + pos + 1, 00211 pv->ptrs + pos, 00212 ((pv->count - pos) * sizeof(void *))); 00213 pv->ptrs[pos] = (void *)ptr; 00214 ++pv->count; 00215 } 00216 } 00217 00218 bool 00219 ptr_vector_delete(ptr_vector_h pv, size_t pos) 00220 { 00221 if (pos < pv->count) { 00222 memmove(pv->ptrs + pos, 00223 pv->ptrs + pos + 1, 00224 ((pv->count - 1 + pos) * sizeof(void *))); 00225 --pv->count; 00226 return true; 00227 } 00228 return false; 00229 } 00230 00231 bool 00232 ptr_vector_equal( ptr_vector_const_h lhs, 00233 ptr_vector_const_h rhs, 00234 comparator_t compare) 00235 { 00236 if (lhs != rhs) { 00237 assert(lhs); 00238 assert(rhs); 00239 if (lhs->dtor == rhs->dtor && lhs->cloner == rhs->cloner) { 00240 if (ptr_vector_count(lhs) == ptr_vector_count(rhs)) { 00241 void const ** lh_iter = ptr_vector_begin_const(lhs); 00242 void const ** rh_iter = ptr_vector_begin_const(rhs); 00243 void const ** lh_end = ptr_vector_end_const(lhs); 00244 for ( ; lh_iter != lh_end; ++lh_iter,++rh_iter) { 00245 if (compare(*lh_iter,*rh_iter,0)) { 00246 return false; 00247 } 00248 } 00249 return true; 00250 } 00251 } 00252 return false; 00253 } 00254 return true; 00255 } 00256 00257 dtor_t 00258 ptr_vector_dtor(ptr_vector_const_h pv) 00259 { 00260 assert(pv); 00261 return pv->dtor; 00262 } 00263 00264 cloner_t 00265 ptr_vector_cloner(ptr_vector_const_h pv) 00266 { 00267 assert(pv); 00268 return pv->cloner; 00269 } 00270 00271 00272 void 00273 ptr_vector_append(ptr_vector_h pv, void *ptr) 00274 { 00275 ptr_vector_insert(pv,(size_t)-1,ptr); 00276 } 00277 00278 size_t 00279 ptr_vector_count(ptr_vector_const_h pv) 00280 { 00281 return pv->count; 00282 } 00283 00284 void ** 00285 ptr_vector_begin(ptr_vector_h pv) 00286 { 00287 return pv->ptrs; 00288 } 00289 00290 void const ** 00291 ptr_vector_begin_const(ptr_vector_const_h pv) 00292 { 00293 return (void const **)ptr_vector_begin((ptr_vector_h)pv); 00294 } 00295 00296 void ** 00297 ptr_vector_end(ptr_vector_h pv) 00298 { 00299 return pv->ptrs + pv->count; 00300 } 00301 00302 void const ** 00303 ptr_vector_end_const(ptr_vector_const_h pv) 00304 { 00305 return (void const **)ptr_vector_end((ptr_vector_h)pv); 00306 } 00307 00308 void * 00309 ptr_vector_at(ptr_vector_h pv, size_t pos) 00310 { 00311 return (pos < pv->count) ? pv->ptrs[pos] : 0; 00312 } 00313 00314 void const * 00315 ptr_vector_at_const(ptr_vector_const_h pv, size_t pos) 00316 { 00317 return (void const *)ptr_vector_at((ptr_vector_h)pv,pos); 00318 } 00319 00320 locator_t 00321 ptr_vector_search( ptr_vector_const_h pv, 00322 void const *key, 00323 locator_t keylen, 00324 comparator_t compare, 00325 bool ordered) 00326 { 00327 locator_t comp = 1; 00328 void const ** begin = ptr_vector_begin_const(pv); 00329 void const ** end = ptr_vector_end_const(pv); 00330 void const ** iter = begin; 00331 if (!ordered) { 00332 for ( iter = begin; iter != end; ++iter) { 00333 comp = compare(*iter,key,keylen); 00334 if (!comp) { 00335 break; 00336 } 00337 } 00338 } else { 00339 for ( iter = begin; iter != end; ++iter) { 00340 comp = compare(*iter,key,keylen); 00341 if (comp >= 0) { 00342 break; 00343 } 00344 } 00345 } 00346 comp = comp ? ~(iter - begin) : iter - begin; 00347 return comp; 00348 } 00349 00352 /* EOF*/