Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Related Pages

bytevector.c

00001 /* 00002 00003 The BLAH library, a container library 00004 Copyright (C) 1997-2004 The CDG Team <cdg@nats.informatik.uni-hamburg.de> 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 00020 Contact: blah@nats.informatik.uni-hamburg.de 00021 00022 $Id: bytevector.c,v 1.5 2004/03/30 10:07:59 foth Exp $ 00023 00024 */ 00025 00026 /* ---------------------------------------------------------------------- 00027 @defgroup ByteVector ByteVectors 00028 00029 A bytevector is a variant of vector with char instead of Pointer as 00030 its element type. There are no other differences. 00031 00032 @{ 00033 */ 00034 00035 /* ---INCLUDES-------------------------------------------------------- */ 00036 #include <stdio.h> 00037 #include <string.h> 00038 #include "blah.h" 00039 00040 /* ------------------------------------------------------------------- */ 00041 #define RESIZEFACTOR 2 00042 00043 /* -- TYPE DEFINITIONS ----------------------------------------------- */ 00044 /* ---------------------------------------------------------------------- 00045 * internal representation of a bit vector 00046 */ 00047 struct ByteVectorStruct 00048 { 00049 #ifdef BITVECTOR_DEBUG 00050 int magic; /**< identification string */ 00051 #endif 00052 int count; /**< number of entries */ 00053 int capacity; /**< capacity of table */ 00054 char *entries; /**< table of entries */ 00055 }; 00056 00057 /* -- VARIABLES ------------------------------------------------------ */ 00058 /* ------------------------------------------------------------------- */ 00059 #ifdef BITVECTOR_DEBUG 00060 static int magic_constant=8755156; 00061 #endif 00062 00063 /* -- FUNCTIONS ------------------------------------------------------ */ 00064 #ifdef BITVECTOR_DEBUG 00065 static void check_magic_function(ByteVector v, char *file, int no) 00066 { 00067 if (!v) 00068 { 00069 fprintf(stderr, "%s:%d: ByteVector must not be NULL\n", file, no); 00070 abort(); 00071 } 00072 if (v->magic!=magic_constant) 00073 { 00074 fprintf(stderr, "%s:%d: not a ByteVector\n", file, no); 00075 abort(); 00076 } 00077 } 00078 #define check_magic(v) check_magic_function(v, __FILE__, __LINE__) 00079 #else /* #ifdef BITVECTOR_DEBUG */ 00080 #define check_magic(v) 00081 #endif /* #ifdef BITVECTOR_DEBUG */ 00082 00083 /* ---------------------------------------------------------------------- 00084 * doubles capacity of ByteVector. 00085 * 00086 * @param v the bitvector that has to be resized. 00087 * @returns the bitvector after increasing its capacity. 00088 */ 00089 static void resize(ByteVector v) 00090 { 00091 check_magic(v); 00092 00093 v->capacity=(int)(RESIZEFACTOR*v->capacity); 00094 v->entries=(char *)memRealloc(v->entries, sizeof(char)*v->capacity); 00095 memset(&v->entries[v->count], 0, (v->capacity-v->count)*sizeof(char)); 00096 } 00097 00098 /* ---------------------------------------------------------------------- 00099 * creates a new empty bitvector with an initial capacity. 00100 * 00101 * Specifying a correct or nearly correct capacity slightly improves the 00102 * efficiency. The bitvector roughly needs capacity bytes. 00103 * 00104 * @param capacity the capacity of the new vector to be created. 00105 * @returns a new and empty bit vector of the specified capacity. 00106 */ 00107 ByteVector bvNew(int capacity) 00108 { 00109 ByteVector v; 00110 00111 if (capacity<8) { capacity=8; } 00112 v=(ByteVector)memMalloc(sizeof(ByteVectorStruct)); 00113 #ifdef BITVECTOR_DEBUG 00114 v->magic=magic_constant; 00115 #endif 00116 v->count=0; 00117 v->capacity=capacity; 00118 v->entries=(char *)memMalloc(sizeof(char)*capacity); 00119 00120 memset(v->entries, 0, capacity*sizeof(char)); 00121 00122 return(v); 00123 } 00124 00125 /* ---------------------------------------------------------------------- 00126 * deletes a bitvector and frees the associated memory. 00127 * 00128 * note that nothing user-defined is stored in a bitvector. 00129 * therefore, the user does not need to free anything himself. 00130 * 00131 * @param v the bitvector that has to be deleted. 00132 */ 00133 void bvDelete(ByteVector v) 00134 { 00135 check_magic(s); 00136 00137 memFree(v->entries); 00138 memFree(v); 00139 } 00140 00141 /* ---------------------------------------------------------------------- 00142 * adds a new element to the end of the ByteVector. 00143 * 00144 * automatically increases the capacity of the ByteVector if necessary 00145 * 00146 * @param v the vector to which the new element has to be added. 00147 * @param element the element that has to be added to the end of the bitvector v 00148 * @returns index of the vector 00149 */ 00150 int bvAddElement(ByteVector v, char element) 00151 { 00152 check_magic(v); 00153 00154 /* The number of entries exceeds the capacity. Resize the table. */ 00155 while (v->count>=v->capacity) { resize(v); } 00156 00157 v->entries[v->count]=element; 00158 return v->count++; 00159 } 00160 00161 /* ---------------------------------------------------------------------- 00162 * sets the element at the specific index to a new element. 00163 * 00164 * if necessary the bitVector automatically increases its capacity. 00165 * 00166 * @param v the bitvector in which the specified element has to be set to a new element. 00167 * @param index the index of the element that has to be set. 00168 * @returns the old element or \a False at the specified index. 00169 */ 00170 char bvElement(ByteVector v, int index) 00171 { 00172 check_magic(v); 00173 00174 if (index>=0 && index<v->count) { return v->entries[index]; } 00175 00176 fprintf(stderr, "ERROR: bvElement: index %d out of range\n", index); 00177 abort(); 00178 } 00179 00180 /* ---------------------------------------------------------------------- 00181 * removes element at the specified index. 00182 * 00183 * size decreases and all later elements move one position to the front. 00184 * inefficient method, not recommended. 00185 * 00186 * @param v the bitvector from which the element has to be removed. 00187 * @param index the index at which the element to be removed is present. 00188 * @returns old element at the specified index. 00189 */ 00190 char bvRemoveElement(ByteVector v, int index) 00191 { 00192 char p; 00193 00194 check_magic(v); 00195 00196 if (index<0 || index>=v->count) 00197 { 00198 fprintf(stderr, 00199 "ERROR: bvRemoveElement: index %d out of range\n", 00200 index); 00201 abort(); 00202 } 00203 00204 p=v->entries[index]; 00205 /* TODO: check boundaries */ 00206 if (v->count-index>1) 00207 { 00208 memmove(&v->entries[index], 00209 &v->entries[index+1], 00210 (v->count-index)*sizeof(char)); 00211 } 00212 v->count--; 00213 return p; 00214 } 00215 00216 /* ---------------------------------------------------------------------- 00217 * inserts a new element at the given index. 00218 * 00219 * if necessary the bitvector automatically increases its capacity. 00220 * inefficient method,not recommended. 00221 * 00222 * @param v the bitvector into which the new element has to be inserted. 00223 * @param element the new element that has to be inserted into the bitvector v. 00224 * @param index the index at which the new element has to be inserted in the bitvector v. 00225 * @returns the old element at the index. 00226 */ 00227 char bvInsertElement(ByteVector v, char element, int index) 00228 { 00229 char p; 00230 00231 check_magic(v); 00232 00233 if (index<0) 00234 { 00235 fprintf(stderr, 00236 "ERROR: bvInsertElement: index %d out of range\n", 00237 index); 00238 abort(); 00239 } 00240 00241 /* 00242 * v->capacity==index is too small because index is counted 00243 * from zero. 00244 */ 00245 while (v->capacity<=index) { resize(v); } 00246 00247 /* 00248 * if v->count==v->capacity then the vector is 00249 * completely full; v->count>v->capacity shouldn't be possible. 00250 */ 00251 if (v->count>=v->capacity) { resize(v); } 00252 00253 if (v->count-index>0) 00254 { 00255 memmove(&v->entries[index+1], 00256 &v->entries[index], 00257 (v->count-index)*sizeof(char)); 00258 } 00259 00260 p=v->entries[index]; 00261 v->entries[index]=element; 00262 v->count=max(v->count+1, index+1); 00263 00264 return p; 00265 } 00266 00267 /* ---------------------------------------------------------------------- 00268 * sets element at the given index. 00269 * 00270 * if necessary the vector automatically increases its capacity. 00271 * 00272 * @param v the vector in which the element has to be set at the specified index. 00273 * @param element the element that has to be set in the bitvector. 00274 * @param index the index at which the element to be set is present. 00275 * @returns The old element at the index. 00276 */ 00277 char bvSetElement(ByteVector v, char element, int index) 00278 { 00279 char p; 00280 00281 check_magic(v); 00282 00283 if (index<0) 00284 { 00285 fprintf(stderr, 00286 "ERROR: bvSetElement: index %d out of range\n", 00287 index); 00288 abort(); 00289 } 00290 00291 /* TODO: check boundaries */ 00292 while (v->capacity<=index) { resize(v); } 00293 00294 p=v->entries[index]; 00295 v->entries[index]=element; 00296 v->count=max(v->count, index+1); 00297 return p; 00298 } 00299 00300 /* ---------------------------------------------------------------------- 00301 * sets all the elements between index \a from and \a to (excluding to) to a new value. 00302 * 00303 * if necessary the bit vector automatically increases in capacity. 00304 * 00305 * @param v the bitvector in which the elements have to be set. 00306 * @param element the value of the bits at the corresponding indices. 00307 * @param from the source index from which all the elements in the bitvector have to be set. 00308 * @param to the destination index until which all the elements in the bitvector have to be set. 00309 * @returns the bitvector v after setting all the elements at the specified indices. 00310 * 00311 */ 00312 void bvSetElements(ByteVector v, char element, int from, int to) 00313 { 00314 check_magic(v); 00315 00316 if (from<0 || to<0) 00317 { 00318 fprintf(stderr, 00319 "ERROR: bvSetElement: index %d out of range\n", 00320 from<0 ? from : to); 00321 abort(); 00322 } 00323 00324 if (from>to) { int tmp=from; from=to; to=tmp; } 00325 00326 /* TODO: check boundaries */ 00327 /* to is excluded, so v->capacity==to is enough */ 00328 while (v->capacity<to) { resize(v); } 00329 00330 memset(&v->entries[from], element, (to-from)*sizeof(char)); 00331 v->count=max(v->count, to); 00332 } 00333 00334 /* ---------------------------------------------------------------------- 00335 * sets all the elements to a new value. 00336 * 00337 * the size increases to the current capacity of the bit vector. 00338 * 00339 * @param v the bitvector in which all the elements have to be set. 00340 * @param element the elements at the specified indices. 00341 * 00342 * @returns the bitvector after setting all the elements. 00343 */ 00344 void bvSetAllElements(ByteVector v, char element) 00345 { 00346 memset(v->entries, element, v->capacity*sizeof(char)); 00347 v->count=v->capacity; 00348 } 00349 00350 /* ---------------------------------------------------------------------- 00351 * finds the current capacity of bitvector. 00352 * 00353 * @param v the bitvector whose capacity has to be retrieved. 00354 * @returns the capacity of the bitvector v. 00355 */ 00356 int bvCapacity(ByteVector v) 00357 { 00358 check_magic(v); 00359 00360 return v->capacity; 00361 } 00362 00363 /* ---------------------------------------------------------------------- 00364 * finds the number of entries(size) in the bitvector. 00365 * 00366 * @param v the bitvector whose size has to be retrieved. 00367 * @returns the size of the bitvector v. 00368 */ 00369 int bvSize(ByteVector v) 00370 { 00371 check_magic(v); 00372 00373 return v->count; 00374 } 00375 00376 /* ---------------------------------------------------------------------- 00377 * finds if the bit vector is empty or not. 00378 * 00379 * @param v the bitvector for which emptiness is checked. 00380 * @returns \a TRUE if bitvector is empty and \a FALSE otherwise. 00381 */ 00382 Boolean bvIsEmpty(ByteVector v) 00383 { 00384 check_magic(v); 00385 00386 return v->count==0 ? TRUE : FALSE; 00387 } 00388 00389 /* ---------------------------------------------------------------------- 00390 * creates an exact copy of the specified bitvector. 00391 * 00392 * @param v the bitvector for which cloning has to be performed. 00393 * @returns a complete independent \a CLONE of the bit vector v. 00394 */ 00395 ByteVector bvClone(ByteVector v) 00396 { 00397 ByteVector new; 00398 00399 check_magic(v); 00400 00401 new=bvNew(bvCapacity(v)); 00402 bvCopy(new, v); 00403 return new; 00404 } 00405 00406 /* ---------------------------------------------------------------------- 00407 * 00408 * copies entries of one bitvector to another. 00409 * 00410 * copying is done from bitVector \a src to the bitvector \a dst. 00411 * \a dst vector automatically increases its capacity. 00412 * @param src source index or the index from which copying has to be initiated. 00413 * @param dst destination index or the index until which the copying has to be done. 00414 * @returns the new \a dst vector with the elements copied into it. 00415 */ 00416 ByteVector bvCopy(ByteVector dst, ByteVector src) 00417 { 00418 if (dst->capacity<src->capacity) 00419 { 00420 dst->entries=(char *)memRealloc(dst->entries, sizeof(char)*src->capacity); 00421 } 00422 00423 memcpy(dst->entries, src->entries, sizeof(char)*src->capacity); 00424 00425 dst->count=src->count; 00426 dst->capacity=src->capacity; 00427 00428 return dst; 00429 } 00430 00431 /* ---------------------------------------------------------------------- 00432 * computes AND to the element at the given index. 00433 * 00434 * if necessary the vector automatically increases its capacity. 00435 * 00436 * @param v the vector in which the element has to be set at the specified index. 00437 * @param element the element that has to be set in the bitvector. 00438 * @param index the index at which the element to be set is present. 00439 * @returns The new value at the index. 00440 */ 00441 char bvAndElement(ByteVector v, char element, int index) 00442 { 00443 check_magic(v); 00444 00445 if (index < 0) { 00446 fprintf(stderr, "ERROR: bvSetElement: index %d out of range\n", index); 00447 abort(); 00448 } 00449 00450 /* TODO: check boundaries */ 00451 while (v->capacity <= index) { 00452 resize(v); 00453 } 00454 00455 return (v->entries[index] &= element); 00456 } 00457 00458 /* ---------------------------------------------------------------------- 00459 * computes OR to the element at the given index. 00460 * 00461 * if necessary the vector automatically increases its capacity. 00462 * 00463 * @param v the vector in which the element has to be set at the specified index. 00464 * @param element the element that has to be set in the bitvector. 00465 * @param index the index at which the element to be set is present. 00466 * @returns The new value at the index. 00467 */ 00468 char bvOrElement(ByteVector v, char element, int index) 00469 { 00470 check_magic(v); 00471 00472 if (index < 0) { 00473 fprintf(stderr, "ERROR: bvSetElement: index %d out of range\n", index); 00474 abort(); 00475 } 00476 00477 /* TODO: check boundaries */ 00478 while (v->capacity <= index) { 00479 resize(v); 00480 } 00481 00482 return (v->entries[index] |= element); 00483 } 00484 00485 /* ---------------------------------------------------------------------- 00486 * computes NOT to the element at the given index. 00487 * 00488 * if necessary the vector automatically increases its capacity. 00489 * 00490 * @param v the vector in which the element has to be set at the specified index. 00491 * @param index the index at which the element to be set is present. 00492 * @returns The new value at the index. 00493 */ 00494 char bvNotElement(ByteVector v, int index) 00495 { 00496 check_magic(v); 00497 00498 if (index < 0) { 00499 fprintf(stderr, "ERROR: bvSetElement: index %d out of range\n", index); 00500 abort(); 00501 } 00502 00503 /* TODO: check boundaries */ 00504 while (v->capacity <= index) { 00505 resize(v); 00506 } 00507 00508 return (v->entries[index] = ~v->entries[index]); 00509 } 00510 00511 00512 /* ---------------------------------------------------------------------- */ 00513 /* ---------------------------------------------------------------------- */ 00514 /** @} */

BLAH 0.95 (20 Oct 2004)