00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <unistd.h>
00021 #include <string.h>
00022 #include <assert.h>
00023 #include <errno.h>
00024 #include <pthread.h>
00025 #include <sys/mman.h>
00026 #include <math.h>
00027 #include <limits.h>
00028
00029
00030 #include <xanlib.h>
00031 #include <xan-system.h>
00032 #include <config.h>
00033
00034
00035
00036 static const size_t primes[] = {
00037 53, 97, 193, 389,
00038 769, 1543, 3079, 6151,
00039 12289, 24593, 49157, 98317,
00040 196613, 393241, 786433, 1572869,
00041 3145739, 6291469, 12582917, 25165843,
00042 50331653, 100663319, 201326611, 402653189,
00043 805306457, 1610612741
00044 };
00045 #define PRIMES_TABLE_LENGTH (sizeof(primes)/sizeof(primes[0]))
00046 #define HASHTABLE_DEFAULT_LOAD_FACTOR 0.65
00047
00048
00049
00050 static inline void * varRead (XanVar *var);
00051 static inline void * _varRead (XanVar *var);
00052 static inline void varWrite (XanVar *var, void *data);
00053 static inline void _varWrite (XanVar *var, void *data);
00054 static inline void varLock (XanVar *var);
00055 static inline void varUnlock (XanVar *var);
00056 static inline void varDestroyVarAndData (XanVar *var);
00057
00058
00059 static inline void * xanStackPop (XanStack *stack);
00060 static inline void * _xanStackPop (XanStack *stack);
00061 static inline void xanStackPush (XanStack *stack, void *newElement);
00062 static inline void _xanStackPush (XanStack *stack, void *newElement);
00063 static inline int xanStackGetSize (XanStack *stack);
00064 static inline int _xanStackGetSize (XanStack *stack);
00065 static inline void _xanStackDestroyStack (XanStack *stack);
00066
00067
00068 static inline void xanListDeleteClones (XanList *list);
00069 static inline void _xanListDeleteClones (XanList *list);
00070 static inline int xanListShareSomeElements (XanList *list, XanList *otherList);
00071 static inline int _xanListShareSomeElements (XanList *list, XanList *otherList);
00072 static inline void xanListAppendList (XanList *list, XanList *listToAppend);
00073 static inline void _xanListAppendList (XanList *list, XanList *listToAppend);
00074 static inline XanListItem * xanListAppend (XanList *list, void *data);
00075 static inline XanListItem * _xanListAppend (XanList *list, void *data);
00076 static inline XanListItem * xanListInsert (XanList *list, void *data);
00077 static inline XanListItem * _xanListInsert (XanList *list, void *data);
00078 static inline XanListItem * xanListInsertBefore (XanList *list, XanListItem *prev, void *data);
00079 static inline XanListItem * _xanListInsertBefore (XanList *list, XanListItem *prev, void *data);
00080 static inline XanListItem * xanListInsertAfter (XanList *list, XanListItem *prev, void *data);
00081 static inline XanListItem * _xanListInsertAfter (XanList *list, XanListItem *prev, void *data);
00082 static inline XanListItem * xanListMoveToBegin (XanList *list, XanListItem *item);
00083 static inline XanListItem * _xanListMoveToBegin (XanList *list, XanListItem *item);
00084 static inline XanListItem * xanListFirst (XanList *list);
00085 static inline XanListItem * _xanListFirst (XanList *list);
00086 static inline XanListItem * xanListLast (XanList *list);
00087 static inline XanListItem * _xanListLast (XanList *list);
00088 static inline XanListItem * xanListFind (XanList *list, void *data);
00089 static inline XanListItem * _xanListFind (XanList *list, void *data);
00090 static inline void xanListDelete (XanList *list, void *data);
00091 static inline void _xanListDelete (XanList *list, void *data);
00092 static inline void xanListDeleteAll (XanList *list, void *data);
00093 static inline void _xanListDeleteAll (XanList *list, void *data);
00094 static inline int xanListContainsTheSameElements (XanList *list, XanList *otherList);
00095 static inline int _xanListContainsTheSameElements (XanList *list, XanList *otherList);
00096 static inline void xanListDeleteItem (XanList *list, XanListItem *item);
00097 static inline void _xanListDeleteItem (XanList *list, XanListItem *item);
00098 static inline void * xanListData(XanList *list, XanListItem *item);
00099 static inline void * _xanListData(XanList *list, XanListItem *item);
00100 static inline void ** xanListGetSlotData (XanList *list, XanListItem *item);
00101 static inline void ** _xanListGetSlotData (XanList *list, XanListItem *item);
00102 static inline XanListItem * xanListNext(XanList *list, XanListItem *item);
00103 static inline XanListItem * _xanListNext(XanList *list, XanListItem *item);
00104 static inline XanListItem * xanListPrev(XanList *list, XanListItem *item);
00105 static inline XanListItem * _xanListPrev(XanList *list, XanListItem *item);
00106 static inline void xanListDestroy (XanList *list);
00107 static inline void _xanListDestroy (XanList *list);
00108 static inline void xanListEmptyOutList (XanList *list);
00109 static inline void _xanListEmptyOutList (XanList *list);
00110 static inline int xanListLength (XanList *list);
00111 static inline int _xanListLength (XanList *list);
00112 static inline XanList * xanListCloneList (XanList *list);
00113 static inline XanList * _xanListCloneList (XanList *list);
00114 static inline void xanListSetCloneFunction (XanList *list, void * (*cloneFunction) (void *data));
00115 static inline void _xanListSetCloneFunction (XanList *list, void * (*cloneFunction) (void *data));
00116 static inline void * xanListGetCloneFunction (XanList *list);
00117 static inline void * _xanListGetCloneFunction (XanList *list);
00118 static inline void xanListDestroyListAndData (XanList *list);
00119 static inline void _xanListDestroyListAndData (XanList *list);
00120 static inline int xanListEqualsInstancesNumber (XanList *list, void *data);
00121 static inline int _xanListEqualsInstancesNumber (XanList *list, void *data);
00122 static inline XanListItem * xanListGetElementFromPositionNumber (XanList *list, int positionNumber);
00123 static inline XanListItem * _xanListGetElementFromPositionNumber (XanList *list, int positionNumber);
00124 static inline void _xanListLock (XanList *list);
00125 static inline void _xanListUnlock (XanList *list);
00126
00127
00128 static inline void * xanPipeGet (XanPipe *pipe);
00129 static inline void * _xanPipeGet (XanPipe *pipe);
00130 static inline XanListItem * xanPipePut (XanPipe *pipe, void *item);
00131 static inline XanListItem * _xanPipePut (XanPipe *pipe, void *item);
00132 static inline XanListItem * xanPipePutAtEnd (XanPipe *pipe, void *item);
00133 static inline XanListItem * _xanPipePutAtEnd (XanPipe *pipe, void *item);
00134 static inline XanListItem * xanPipeMoveToEnd (XanPipe *pipe, void *item);
00135 static inline XanListItem * _xanPipeMoveToEnd (XanPipe *pipe, void *item);
00136 static inline void xanPipeDeleteItem (XanPipe *pipe, XanListItem *item);
00137 static inline void _xanPipeDeleteItem (XanPipe *pipe, XanListItem *item);
00138 static inline int xanPipeIsEmpty (XanPipe *pipe);
00139 static inline int _xanPipeIsEmpty (XanPipe *pipe);
00140 static inline void xanPipeLock (XanPipe *pipe);
00141 static inline void xanPipeUnlock (XanPipe *pipe);
00142 static inline void _xanPipeDestroyPipe (XanPipe *pipe);
00143
00144
00145 static inline XanNode * xanNodeGetParent (XanNode *node);
00146 static inline XanNode * xanNodeGetNextChildren (XanNode *node, XanNode *child);
00147 static inline XanNode * xanNodeAddNewChildren (XanNode *node, void *childData);
00148 static inline void xanNodeAddChildren (XanNode *node, XanNode *child);
00149 static inline void xanNodeSetParent (XanNode *node, XanNode *parent);
00150 static inline void xanNodeSetData (XanNode *node, void *data);
00151 static inline void * xanNodeGetData (XanNode *node);
00152 static inline XanNode * _xanNodeGetParent (XanNode *node);
00153 static inline XanNode * _xanNodeGetNextChildren (XanNode *node, XanNode *child);
00154 static inline XanNode * _xanNodeAddNewChildren (XanNode *node, void *childData);
00155 static inline void _xanNodeAddChildren (XanNode *node, XanNode *child);
00156 static inline void _xanNodeSetParent (XanNode *node, XanNode *parent);
00157 static inline void _xanNodeSetData (XanNode *node, void *data);
00158 static inline void * _xanNodeGetData (XanNode *node);
00159 static inline XanNode * xanNodeCloneTree (XanNode *node);
00160 static inline XanNode * _xanNodeCloneTree (XanNode *node);
00161 static inline void xanNodeDeleteChildren (XanNode *node, XanNode *child);
00162 static inline void _xanNodeDeleteChildren (XanNode *node, XanNode *child);
00163 static inline XanList * xanNodeGetChildrens (XanNode *node);
00164 static inline XanList * _xanNodeGetChildrens (XanNode *node);
00165 static inline void xanNodeSetCloneFunction (XanNode *node, void * (*cloneFunction) (void *data));
00166 static inline void _xanNodeSetCloneFunction (XanNode *node, void * (*cloneFunction) (void *data));
00167 static inline void xanNodeDestroyTreeAndData (XanNode *node);
00168 static inline void _xanNodeDestroyTreeAndData (XanNode *node);
00169 static inline void xanNodeDestroyTree (XanNode *node);
00170 static inline void _xanNodeDestroyTree (XanNode *node);
00171 static inline void _xanNodeDestroyNode (XanNode *node);
00172 static inline XanList * xanNodeToPreOrderList (XanNode *node);
00173 static inline XanList * _xanNodeToPreOrderList (XanNode *node);
00174 static inline XanList * xanNodeToPostOrderList (XanNode *node);
00175 static inline XanList * _xanNodeToPostOrderList (XanNode *node);
00176 static inline XanList * xanNodeToInOrderList (XanNode *node);
00177 static inline XanList * _xanNodeToInOrderList (XanNode *node);
00178 static inline XanNode * xanNodeFind (XanNode *rootNode, void *data);
00179 static inline XanNode * _xanNodeFind (XanNode *rootNode, void *data);
00180
00181
00182 static inline void _xanHashTableLock (XanHashTable *table);
00183 static inline void _xanHashTableUnlock (XanHashTable *table);
00184 static inline unsigned int xanHashTableDefaultHashFunction (void *element);
00185 static inline int xanHashTableDefaultEqualsFunction (void *key1, void *key2);
00186 static inline void xanHashTableInsert (XanHashTable *table, void *key, void *element);
00187 static inline void _xanHashTableInsert (XanHashTable *table, void *key, void *element);
00188 static inline void * xanHashTableLookup (XanHashTable *table, void *key);
00189 static inline void * _xanHashTableLookup (XanHashTable *table, void *key);
00190 static inline void xanHashTableDelete (XanHashTable *table, void *key);
00191 static inline void _xanHashTableDelete (XanHashTable *table, void *key);
00192 static inline void xanHashTableDestroy (XanHashTable *table);
00193 static inline void _xanHashTableDestroy (XanHashTable *table);
00194 static inline XanList * xanHashTableToList (XanHashTable *table);
00195 static inline XanList * _xanHashTableToList (XanHashTable *table);
00196 static inline XanList * xanHashTableToSlotList (XanHashTable *table);
00197 static inline XanList * _xanHashTableToSlotList (XanHashTable *table);
00198 static inline int xanHashTableElementsInside (XanHashTable *table);
00199 static inline int _xanHashTableElementsInside (XanHashTable *table);
00200 static inline XanHashTable * xanHashTableCloneHashTable (XanHashTable *table);
00201 static inline XanHashTable * _xanHashTableCloneHashTable (XanHashTable *table);
00202 static inline void xanHashTableSetCloneFunction(XanHashTable *table, void * (*cloneFunction) (void *data));
00203 static inline void _xanHashTableSetCloneFunction(XanHashTable *table, void * (*cloneFunction) (void *data));
00204 static inline void * xanHashTableGetCloneFunction (XanHashTable *table);
00205 static inline void * _xanHashTableGetCloneFunction (XanHashTable *table);
00206 static inline void _xanHashTableExpand(XanHashTable* table);
00207 static inline unsigned int _xanHashTableImproveHash(XanHashTable* table, void* key);
00208
00209
00210 static inline void internalPreOrderListHelpFunction(XanNode *tree, XanList *list);
00211 static inline void internalPostOrderListHelpFunction(XanNode *tree, XanList *list);
00212 static inline void internalInOrderListHelpFunction(XanNode *tree, XanList *list);
00213
00214 static inline void ** xanListGetSlotData (XanList *list, XanListItem *item){
00215 void **data;
00216
00217
00218 assert(list != NULL);
00219 assert(item != NULL);
00220
00221 pthread_mutex_lock(&(list->itemsMutex));
00222 data = _xanListGetSlotData(list, item);
00223 pthread_mutex_unlock(&(list->itemsMutex));
00224
00225 return data;
00226 }
00227
00228 static inline void * xanListData(XanList *list, XanListItem *item){
00229 void *data;
00230
00231
00232 assert(list != NULL);
00233 assert(item != NULL);
00234
00235 pthread_mutex_lock(&(list->itemsMutex));
00236 data = _xanListData(list, item);
00237 pthread_mutex_unlock(&(list->itemsMutex));
00238
00239 return data;
00240 }
00241
00242 static inline XanListItem * xanListPrev(XanList *list, XanListItem *item){
00243 XanListItem *prevItem;
00244
00245
00246 assert(list != NULL);
00247 assert(item != NULL);
00248
00249 pthread_mutex_lock(&(list->itemsMutex));
00250 prevItem= _xanListPrev(list, item);
00251 pthread_mutex_unlock(&(list->itemsMutex));
00252
00253 return prevItem;
00254 }
00255
00256 static inline XanListItem * xanListNext(XanList *list, XanListItem *item){
00257 XanListItem *nextItem;
00258
00259
00260 assert(list != NULL);
00261 assert(item != NULL);
00262
00263 pthread_mutex_lock(&(list->itemsMutex));
00264 nextItem= _xanListNext(list, item);
00265 pthread_mutex_unlock(&(list->itemsMutex));
00266
00267 return nextItem;
00268 }
00269
00270 static inline void xanListDeleteClones (XanList *list){
00271
00272
00273 assert(list != NULL);
00274
00275 pthread_mutex_lock(&(list->itemsMutex));
00276 _xanListDeleteClones(list);
00277 pthread_mutex_unlock(&(list->itemsMutex));
00278
00279 return ;
00280 }
00281
00282 static inline int xanListShareSomeElements (XanList *list, XanList *otherList){
00283 int result;
00284
00285
00286 assert(list != NULL);
00287 assert(otherList != NULL);
00288
00289 pthread_mutex_lock(&(list->itemsMutex));
00290 result = _xanListShareSomeElements(list, otherList);
00291 pthread_mutex_unlock(&(list->itemsMutex));
00292
00293 return result;
00294 }
00295
00296 static inline void xanListAppendList (XanList *list, XanList *listToAppend){
00297
00298
00299 assert(list != NULL);
00300 assert(listToAppend != NULL);
00301
00302 pthread_mutex_lock(&(list->itemsMutex));
00303 _xanListAppendList(list, listToAppend);
00304 pthread_mutex_unlock(&(list->itemsMutex));
00305
00306 return;
00307 }
00308
00309 static inline XanListItem * xanListAppend (XanList *list, void *data){
00310 XanListItem *item;
00311
00312
00313 assert(list != NULL);
00314 assert(data != NULL);
00315
00316 pthread_mutex_lock(&(list->itemsMutex));
00317 item = _xanListAppend(list, data);
00318 pthread_mutex_unlock(&(list->itemsMutex));
00319
00320 return item;
00321 }
00322
00323 static inline XanListItem * xanListInsert (XanList *list, void *data){
00324 XanListItem *item;
00325
00326
00327 assert(list != NULL);
00328 assert(data != NULL);
00329
00330 pthread_mutex_lock(&(list->itemsMutex));
00331 item = _xanListInsert(list, data);
00332 pthread_mutex_unlock(&(list->itemsMutex));
00333
00334 return item;
00335 }
00336
00337 static inline XanListItem * xanListInsertAfter (XanList *list, XanListItem *prev, void *data){
00338 XanListItem *item;
00339
00340
00341 assert(list != NULL);
00342 assert(data != NULL);
00343 assert(prev != NULL);
00344
00345 pthread_mutex_lock(&(list->itemsMutex));
00346 item = _xanListInsertAfter(list, prev, data);
00347 pthread_mutex_unlock(&(list->itemsMutex));
00348
00349 return item;
00350 }
00351
00352 static inline XanListItem * xanListInsertBefore (XanList *list, XanListItem *prev, void *data){
00353 XanListItem *item;
00354
00355
00356 assert(list != NULL);
00357 assert(prev != NULL);
00358
00359 pthread_mutex_lock(&(list->itemsMutex));
00360 item = _xanListInsertBefore(list, prev, data);
00361 pthread_mutex_unlock(&(list->itemsMutex));
00362
00363 return item;
00364 }
00365
00366 static inline XanListItem * xanListFind (XanList *list, void *data){
00367 XanListItem *item;
00368
00369
00370 assert(list != NULL);
00371
00372 pthread_mutex_lock(&(list->itemsMutex));
00373 item = _xanListFind(list, data);
00374 pthread_mutex_unlock(&(list->itemsMutex));
00375
00376
00377 return item;
00378 }
00379
00380 static inline XanListItem * xanListLast (XanList *list){
00381 XanListItem *lastItem;
00382
00383
00384 assert(list != NULL);
00385
00386 pthread_mutex_lock(&(list->itemsMutex));
00387 lastItem = _xanListLast(list);
00388 pthread_mutex_unlock(&(list->itemsMutex));
00389
00390
00391 return lastItem;
00392 }
00393
00394 static inline XanListItem * xanListFirst (XanList *list){
00395 XanListItem *firstItem;
00396
00397
00398 assert(list != NULL);
00399
00400 pthread_mutex_lock(&(list->itemsMutex));
00401 firstItem = _xanListFirst(list);
00402 pthread_mutex_unlock(&(list->itemsMutex));
00403
00404
00405 return firstItem;
00406 }
00407
00408 static inline void xanListDeleteItem (XanList *list, XanListItem *item){
00409
00410
00411 assert(list != NULL);
00412 assert(item != NULL);
00413
00414 pthread_mutex_lock(&(list->itemsMutex));
00415 _xanListDeleteItem(list, item);
00416 pthread_mutex_unlock(&(list->itemsMutex));
00417 }
00418
00419 static inline void xanListDelete (XanList *list, void *data){
00420
00421
00422 assert(list != NULL);
00423 assert(data != NULL);
00424
00425 pthread_mutex_lock(&(list->itemsMutex));
00426 _xanListDelete(list, data);
00427 pthread_mutex_unlock(&(list->itemsMutex));
00428 }
00429
00430 static inline int xanListContainsTheSameElements (XanList *list, XanList *otherList){
00431 int result;
00432
00433
00434 assert(list != NULL);
00435
00436 pthread_mutex_lock(&(list->itemsMutex));
00437 result = 0;
00438 if (otherList != NULL){
00439 pthread_mutex_lock(&(otherList->itemsMutex));
00440 result = _xanListContainsTheSameElements(list, otherList);
00441 pthread_mutex_unlock(&(otherList->itemsMutex));
00442 }
00443 pthread_mutex_unlock(&(list->itemsMutex));
00444
00445 return result;
00446 }
00447
00448 static inline void xanListDeleteAll (XanList *list, void *data){
00449
00450
00451 assert(list != NULL);
00452 assert(data != NULL);
00453
00454 pthread_mutex_lock(&(list->itemsMutex));
00455 _xanListDeleteAll(list, data);
00456 pthread_mutex_unlock(&(list->itemsMutex));
00457 }
00458
00459 static inline XanListItem * xanListMoveToBegin (XanList *list, XanListItem *item){
00460 XanListItem *itemToMove;
00461
00462
00463 assert(list != NULL);
00464 assert(item != NULL);
00465
00466 pthread_mutex_lock(&(list->itemsMutex));
00467 itemToMove = _xanListMoveToBegin(list, item);
00468 pthread_mutex_unlock(&(list->itemsMutex));
00469
00470 return itemToMove;
00471 }
00472
00473 static inline XanListItem * xanListGetElementFromPositionNumber (XanList *list, int positionNumber){
00474 XanListItem *item;
00475
00476
00477 assert(list != NULL);
00478
00479 pthread_mutex_lock(&(list->itemsMutex));
00480 item = _xanListGetElementFromPositionNumber(list, positionNumber);
00481 pthread_mutex_unlock(&(list->itemsMutex));
00482
00483 return item;
00484 }
00485
00486 static inline int xanListEqualsInstancesNumber (XanList *list, void *data){
00487 int num;
00488
00489
00490 assert(list != NULL);
00491
00492 pthread_mutex_lock(&(list->itemsMutex));
00493 num = _xanListEqualsInstancesNumber(list, data);
00494 pthread_mutex_unlock(&(list->itemsMutex));
00495
00496 return num;
00497 }
00498
00499 static inline void xanListEmptyOutList (XanList *list){
00500
00501 assert(list != NULL);
00502
00503 pthread_mutex_lock(&(list->itemsMutex));
00504 _xanListEmptyOutList(list);
00505 pthread_mutex_unlock(&(list->itemsMutex));
00506 }
00507
00508 static inline void xanListDestroyListAndData (XanList *list){
00509
00510
00511 assert(list != NULL);
00512
00513 pthread_mutex_lock(&(list->itemsMutex));
00514 _xanListDestroyListAndData(list);
00515 pthread_mutex_unlock(&(list->itemsMutex));
00516 }
00517
00518 static inline void xanListDestroy (XanList *list){
00519
00520
00521 assert(list != NULL);
00522
00523 pthread_mutex_lock(&(list->itemsMutex));
00524 _xanListDestroy(list);
00525 pthread_mutex_unlock(&(list->itemsMutex));
00526 }
00527
00528 static inline void _xanListDeleteClones (XanList *list){
00529 void *data;
00530 void *data2;
00531 XanListItem *item;
00532 XanListItem *item2;
00533 XanListItem *item3;
00534
00535
00536 assert(list != NULL);
00537
00538 item = _xanListFirst(list);
00539 while (item != NULL){
00540 data = _xanListData(list, item);
00541 item2 = _xanListNext(list, item);
00542 while (item2 != NULL){
00543 data2 = _xanListData(list, item2);
00544 if (data == data2) {
00545 item3 = _xanListNext(list, item2);
00546 _xanListDeleteItem(list, item2);
00547 item2 = item3;
00548 } else {
00549 item2 = _xanListNext(list, item2);
00550 }
00551 }
00552 item = _xanListNext(list, item);
00553 }
00554 }
00555
00556 static inline int _xanListShareSomeElements (XanList *list, XanList *otherList){
00557 void *data;
00558 void *data2;
00559 XanListItem *item;
00560 XanListItem *item2;
00561
00562
00563 assert(list != NULL);
00564 assert(otherList != NULL);
00565
00566 item = _xanListFirst(list);
00567 while (item != NULL){
00568 data = _xanListData(list, item);
00569 item2 = _xanListFirst(otherList);
00570 while (item2 != NULL){
00571 data2 = _xanListData(otherList, item2);
00572 if (data == data2) return 1;
00573 item2 = _xanListNext(otherList, item2);
00574 }
00575 item = _xanListNext(list, item);
00576 }
00577
00578 return 0;
00579 }
00580
00581 static inline void _xanListAppendList (XanList *list, XanList *listToAppend){
00582 XanListItem *item;
00583 void *data;
00584
00585
00586 assert(listToAppend != NULL);
00587 assert(list != NULL);
00588
00589
00590 item = _xanListFirst(listToAppend);
00591 while (item != NULL){
00592 data = _xanListData(listToAppend, item);
00593 _xanListAppend(list, data);
00594 item = _xanListNext(listToAppend, item);
00595 }
00596 }
00597
00598 static inline XanListItem * _xanListAppend (XanList *list, void *data){
00599 XanListItem *item;
00600 XanListItem *itemToAppend;
00601
00602
00603 assert(list != NULL);
00604 PDEBUG("XANLIB: _xanListAppend: Start\n");
00605
00606
00607 item = NULL;
00608 itemToAppend = NULL;
00609
00610
00611 itemToAppend = (XanListItem *) list->alloc(sizeof(XanListItem));
00612 assert(itemToAppend != NULL);
00613 itemToAppend->data = data;
00614 itemToAppend->next = NULL;
00615
00616
00617 if (list->firstItem == NULL){
00618 assert(list->len == 0);
00619 list->firstItem = itemToAppend;
00620 itemToAppend->prev = NULL;
00621 } else {
00622 assert(list->len > 0);
00623 assert(list->lastItem != NULL);
00624 item = list->lastItem;
00625 item->next = itemToAppend;
00626 itemToAppend->prev = item;
00627 }
00628 (list->len)++;
00629 list->lastItem = itemToAppend;
00630 assert(list->len > 0);
00631
00632
00633 PDEBUG("XANLIB: _xanListAppend: Exit\n");
00634 return itemToAppend;
00635 }
00636
00637 XanList * xanListNew(void *(*allocFunction) (size_t size), void (*freeFunction) (void *addr), void * (*cloneFunction) (void *addr)){
00638 XanList *list;
00639
00640
00641 assert(allocFunction != NULL);
00642 assert(freeFunction != NULL);
00643 if (allocFunction == NULL) return NULL;
00644
00645
00646 list = (XanList *) allocFunction(sizeof(XanList));
00647 assert(list != NULL);
00648 list->firstItem = NULL;
00649 list->lastItem = NULL;
00650 list->len = 0;
00651 list->alloc = allocFunction;
00652 list->free = freeFunction;
00653 list->clone = cloneFunction;
00654 list->synchAppend = xanListAppend;
00655 list->synchAppendList = xanListAppendList;
00656 list->synchShareSomeElements = xanListShareSomeElements;
00657 list->synchDeleteClones = xanListDeleteClones;
00658 list->synchInsert = xanListInsert;
00659 list->synchInsertBefore = xanListInsertBefore;
00660 list->synchInsertAfter = xanListInsertAfter;
00661 list->synchDelete = xanListDelete;
00662 list->synchDeleteAll = xanListDeleteAll;
00663 list->synchDeleteItem = xanListDeleteItem;
00664 list->synchFirst = xanListFirst;
00665 list->synchLast = xanListLast;
00666 list->synchFind = xanListFind;
00667 list->synchDestroyList = xanListDestroy;
00668 list->synchDestroyListAndData = xanListDestroyListAndData;
00669 list->synchEmptyOutList = xanListEmptyOutList;
00670 list->synchEqualsInstancesNumber = xanListEqualsInstancesNumber;
00671 list->synchGetElementFromPositionNumber = xanListGetElementFromPositionNumber;
00672 list->synchMoveToBegin = xanListMoveToBegin;
00673 list->synchData = xanListData;
00674 list->synchGetSlotData = xanListGetSlotData;
00675 list->synchNext = xanListNext;
00676 list->synchPrev = xanListPrev;
00677 list->synchLength = xanListLength;
00678 list->synchCloneList = xanListCloneList;
00679 list->synchSetCloneFunction = xanListSetCloneFunction;
00680 list->synchGetCloneFunction = xanListGetCloneFunction;
00681 list->synchContainsTheSameElements = xanListContainsTheSameElements;
00682 list->append = _xanListAppend;
00683 list->appendList = _xanListAppendList;
00684 list->shareSomeElements = _xanListShareSomeElements;
00685 list->deleteClones = _xanListDeleteClones;
00686 list->insert = _xanListInsert;
00687 list->insertBefore = _xanListInsertBefore;
00688 list->insertAfter = _xanListInsertAfter;
00689 list->delete = _xanListDelete;
00690 list->deleteAll = _xanListDeleteAll;
00691 list->deleteItem = _xanListDeleteItem;
00692 list->first = _xanListFirst;
00693 list->last = _xanListLast;
00694 list->find = _xanListFind;
00695 list->data = _xanListData;
00696 list->getSlotData = _xanListGetSlotData;
00697 list->next = _xanListNext;
00698 list->destroyList = _xanListDestroy;
00699 list->prev = _xanListPrev;
00700 list->length = _xanListLength;
00701 list->cloneList = _xanListCloneList;
00702 list->setCloneFunction = _xanListSetCloneFunction;
00703 list->getCloneFunction = _xanListGetCloneFunction;
00704 list->destroyListAndData = _xanListDestroyListAndData;
00705 list->emptyOutList = _xanListEmptyOutList;
00706 list->equalsInstancesNumber = _xanListEqualsInstancesNumber;
00707 list->getElementFromPositionNumber = _xanListGetElementFromPositionNumber;
00708 list->moveToBegin = _xanListMoveToBegin;
00709 list->containsTheSameElements = _xanListContainsTheSameElements;
00710 list->lock = _xanListLock;
00711 list->unlock = _xanListUnlock;
00712 pthread_mutex_init(&(list->itemsMutex), NULL);
00713
00714
00715 return list;
00716 }
00717
00718 static inline XanList * xanListCloneList (XanList *list){
00719 XanList *clone;
00720
00721
00722 assert(list != NULL);
00723
00724
00725 pthread_mutex_lock(&(list->itemsMutex));
00726 clone = _xanListCloneList(list);
00727 pthread_mutex_unlock(&(list->itemsMutex));
00728
00729
00730 return clone;
00731 }
00732
00733 static inline XanList * _xanListCloneList (XanList *list){
00734 XanList *clone;
00735 XanListItem *item;
00736 void *cloneData;
00737
00738
00739 assert(list != NULL);
00740
00741
00742 clone = xanListNew(list->alloc, list->free, list->clone);
00743 assert(clone != NULL);
00744
00745
00746 item = _xanListFirst(list);
00747 while (item != NULL){
00748 if (list->clone != NULL){
00749 cloneData = list->clone(item->data);
00750 } else {
00751 cloneData = item->data;
00752 }
00753 _xanListAppend(clone, cloneData);
00754 item = _xanListNext(list, item);
00755 }
00756
00757
00758 return clone;
00759 }
00760
00761 static inline void * xanListGetCloneFunction (XanList *list){
00762 void *func;
00763
00764
00765 assert(list != NULL);
00766
00767 pthread_mutex_lock(&(list->itemsMutex));
00768 func = _xanListGetCloneFunction(list);
00769 pthread_mutex_unlock(&(list->itemsMutex));
00770
00771 return func;
00772 }
00773
00774 static inline void * _xanListGetCloneFunction (XanList *list){
00775
00776
00777 assert(list != NULL);
00778
00779 return list->clone;
00780 }
00781
00782 static inline void xanListSetCloneFunction (XanList *list, void * (*cloneFunction) (void *data)){
00783
00784
00785 assert(list != NULL);
00786
00787 pthread_mutex_lock(&(list->itemsMutex));
00788 _xanListSetCloneFunction(list, cloneFunction);
00789 pthread_mutex_unlock(&(list->itemsMutex));
00790 }
00791
00792 static inline void _xanListSetCloneFunction (XanList *list, void * (*cloneFunction) (void *data)){
00793
00794
00795 assert(list != NULL);
00796
00797 list->clone = cloneFunction;
00798 }
00799
00800 static inline int xanListLength (XanList *list){
00801 int length;
00802
00803
00804 assert(list != NULL);
00805
00806 pthread_mutex_lock(&(list->itemsMutex));
00807 length = _xanListLength(list);
00808 pthread_mutex_unlock(&(list->itemsMutex));
00809
00810
00811 return length;
00812 }
00813
00814 static inline int _xanListLength (XanList *list){
00815
00816
00817 assert(list != NULL);
00818
00819
00820 return list->len;
00821 }
00822
00823 static inline XanListItem * _xanListMoveToBegin (XanList *list, XanListItem *item){
00824 XanListItem *itemTemp;
00825
00826
00827 assert(list != NULL);
00828 assert(item != NULL);
00829 assert(list->length(list) > 0);
00830 assert(list->len > 0);
00831 #ifdef DEBUG
00832 void *element;
00833 element = list->data(list, item);
00834 assert(element != NULL);
00835 assert(list->find(list, element) != NULL);
00836 #endif
00837
00838
00839 if (_xanListFirst(list) != item){
00840 assert(list->len > 0);
00841 assert(list->firstItem->prev == NULL);
00842 assert(item->prev != NULL);
00843 assert(list->lastItem != NULL);
00844
00845
00846 if (list->lastItem == item){
00847 list->lastItem = item->prev;
00848 }
00849 assert(list->lastItem != NULL);
00850
00851 itemTemp = list->firstItem;
00852 assert(itemTemp != NULL);
00853 assert(itemTemp->prev == NULL);
00854 item->prev->next = item->next;
00855 assert(item->prev->next != item);
00856 if (item->next != NULL){
00857 item->next->prev = item->prev;
00858 assert(item->next->prev != item);
00859 }
00860 list->firstItem = item;
00861 item->next = itemTemp;
00862 item->prev = NULL;
00863 itemTemp->prev = list->firstItem;
00864 assert(itemTemp != item);
00865 assert(list->firstItem == item);
00866 assert(list->firstItem->next == itemTemp);
00867 assert(list->firstItem->prev == NULL);
00868 assert(itemTemp->prev == list->firstItem);
00869 }
00870 assert(list->firstItem != NULL);
00871 assert(list->firstItem == item);
00872 assert(list->firstItem->prev == NULL);
00873
00874 return list->firstItem;
00875 }
00876
00877 static inline XanListItem * _xanListGetElementFromPositionNumber (XanList *list, int positionNumber){
00878 XanListItem *item;
00879 int count;
00880
00881
00882 assert(list != NULL);
00883
00884 count = 0;
00885 if (positionNumber >= list->len) return NULL;
00886 if (positionNumber == 0) return list->firstItem;
00887 if (positionNumber == (list->len - 1)) return list->lastItem;
00888
00889 item = _xanListFirst(list);
00890 while (item != NULL){
00891 if (count == positionNumber) return item;
00892 count++;
00893 item = _xanListNext(list, item);
00894 }
00895 fprintf(stderr, "XANLIB: ERROR = The element in the position %d does not exist in the list and it should be present.\n", positionNumber);
00896 abort();
00897 }
00898
00899 static inline void _xanListLock (XanList *list){
00900
00901
00902 assert(list != NULL);
00903
00904 pthread_mutex_lock(&(list->itemsMutex));
00905 }
00906
00907 static inline void _xanListUnlock (XanList *list){
00908
00909
00910 assert(list != NULL);
00911
00912 pthread_mutex_unlock(&(list->itemsMutex));
00913 }
00914
00915 static inline int _xanListEqualsInstancesNumber (XanList *list, void *data){
00916 XanListItem *item;
00917 void *tempData;
00918 int num;
00919
00920
00921 assert(list != NULL);
00922
00923 num = 0;
00924 item = _xanListFirst(list);
00925 while (item != NULL){
00926 tempData = _xanListData(list, item);
00927 if (tempData == data) num++;
00928 item = _xanListNext(list, item);
00929 }
00930
00931
00932 return num;
00933 }
00934
00935 static inline void _xanListDestroyListAndData (XanList *list){
00936 XanListItem *item;
00937 XanListItem *itemprev;
00938
00939
00940 assert(list != NULL);
00941
00942 item = _xanListFirst(list);
00943 while (item != NULL){
00944 itemprev = item;
00945 item = _xanListNext(list, item);
00946 list->free(itemprev->data);
00947 list->free(itemprev);
00948 }
00949 list->free(list);
00950 }
00951
00952 static inline void _xanListDestroy (XanList *list){
00953 XanListItem *item;
00954 XanListItem *itemprev;
00955
00956
00957 assert(list != NULL);
00958
00959 item = _xanListFirst(list);
00960 while (item != NULL){
00961 itemprev = item;
00962 item = _xanListNext(list, item);
00963 list->free(itemprev);
00964 }
00965 list->free(list);
00966 }
00967
00968 static inline void _xanListEmptyOutList (XanList *list){
00969 XanListItem *item;
00970
00971
00972 assert(list != NULL);
00973
00974 item = _xanListFirst(list);
00975 while (item != NULL){
00976 _xanListDeleteItem(list, item);
00977 item = _xanListFirst(list);
00978 }
00979 assert(list->firstItem == NULL);
00980 assert(list->lastItem == NULL);
00981
00982
00983 return;
00984 }
00985
00986 static inline XanListItem * _xanListFind (XanList *list, void *data){
00987 XanListItem *item;
00988 XanListItem *champion;
00989 void *current_data;
00990
00991
00992 assert(list != NULL);
00993
00994 champion = NULL;
00995 current_data = NULL;
00996 item = _xanListFirst(list);
00997 while (item != NULL){
00998 current_data = _xanListData(list, item);
00999 if (current_data == data){
01000 champion = item;
01001 break;
01002 }
01003 item = _xanListNext(list, item);
01004 }
01005
01006 return champion;
01007 }
01008
01009 static inline XanListItem * _xanListLast (XanList *list){
01010
01011
01012 assert(list != NULL);
01013
01014
01015 return list->lastItem;
01016 }
01017
01018 static inline XanListItem *_xanListFirst(XanList *list){
01019
01020
01021 assert(list != NULL);
01022
01023
01024 return list->firstItem;
01025 }
01026
01027 static inline void ** _xanListGetSlotData (XanList *list, XanListItem *item){
01028
01029
01030 assert(list != NULL);
01031 assert(item != NULL);
01032 assert(item->data != NULL);
01033
01034 return &(item->data);
01035 }
01036
01037 static inline void * _xanListData(XanList *list, XanListItem *item){
01038
01039
01040 assert(list != NULL);
01041 assert(item != NULL);
01042
01043 return item->data;
01044 }
01045
01046 static inline XanListItem * _xanListNext(XanList *list, XanListItem *item){
01047
01048
01049 assert(item != NULL);
01050 assert(list != NULL);
01051
01052 return item->next;
01053 }
01054
01055 static inline XanListItem * _xanListPrev(XanList *list, XanListItem *item){
01056
01057
01058 assert(item != NULL);
01059 assert(list != NULL);
01060
01061 return item->prev;
01062 }
01063
01064 static inline XanListItem * _xanListInsert (XanList *list, void *data){
01065 XanListItem *item;
01066 XanListItem *itemToInsert;
01067
01068
01069 assert(data != NULL);
01070 assert(list != NULL);
01071
01072
01073 item = NULL;
01074 itemToInsert = NULL;
01075
01076
01077 itemToInsert = (XanListItem *) list->alloc(sizeof(XanListItem));
01078 assert(itemToInsert != NULL);
01079 itemToInsert->data = data;
01080 itemToInsert->prev = NULL;
01081
01082
01083 if (list->firstItem == NULL){
01084 assert(list->len == 0);
01085 list->firstItem = itemToInsert;
01086 list->lastItem = itemToInsert;
01087 itemToInsert->next = NULL;
01088 } else {
01089 assert(list->len > 0);
01090 item = list->firstItem;
01091 assert(item != NULL);
01092 list->firstItem = itemToInsert;
01093 itemToInsert->next = item;
01094 item->prev = list->firstItem;
01095 }
01096 (list->len)++;
01097 assert(list->len > 0);
01098 assert(list->lastItem != NULL);
01099
01100 return itemToInsert;
01101 }
01102
01103 static inline XanListItem * _xanListInsertAfter (XanList *list, XanListItem *prev, void *data){
01104 XanListItem *item;
01105 XanListItem *itemToAppend;
01106
01107
01108 assert(data != NULL);
01109 assert(list != NULL);
01110 assert(prev != NULL);
01111
01112
01113 item = NULL;
01114 itemToAppend = NULL;
01115
01116
01117 itemToAppend = (XanListItem *) list->alloc(sizeof(XanListItem));
01118 assert(itemToAppend != NULL);
01119 itemToAppend->data = data;
01120 itemToAppend->next = NULL;
01121 itemToAppend->prev = NULL;
01122
01123
01124 if ((list->len == 1) || (list->len == 0)){
01125 return _xanListAppend(list, data);
01126 }
01127 assert(list->len > 1);
01128 item = prev->next;
01129 prev->next = itemToAppend;
01130 itemToAppend->prev = prev;
01131 itemToAppend->next = item;
01132 if (item != NULL){
01133 assert(itemToAppend->next != NULL);
01134 item->prev = itemToAppend;
01135 }
01136 (list->len)++;
01137
01138 if (itemToAppend->next == NULL){
01139 list->lastItem = itemToAppend;
01140 }
01141 assert(list->lastItem != NULL);
01142
01143 return itemToAppend;
01144 }
01145
01146 static inline XanListItem * _xanListInsertBefore (XanList *list, XanListItem *prev, void *data){
01147 XanListItem *item;
01148 XanListItem *itemToAppend;
01149
01150
01151 assert(data != NULL);
01152 assert(list != NULL);
01153 assert(prev != NULL);
01154 assert(list->firstItem != NULL);
01155
01156
01157 item = NULL;
01158 itemToAppend = NULL;
01159
01160
01161 itemToAppend = (XanListItem *) list->alloc(sizeof(XanListItem));
01162 assert(itemToAppend != NULL);
01163 itemToAppend->data = data;
01164 itemToAppend->next = NULL;
01165
01166
01167 if (list->firstItem == prev){
01168 return _xanListInsert(list, data);
01169 }
01170 item = prev->prev;
01171 item->next = itemToAppend;
01172 prev->prev = itemToAppend;
01173 itemToAppend->prev = item;
01174 itemToAppend->next = prev;
01175 (list->len)++;
01176 assert(list->lastItem != NULL);
01177
01178 return itemToAppend;
01179 }
01180
01181 static inline void _xanListDeleteItem (XanList *list, XanListItem *item){
01182 XanListItem *prevItem;
01183 XanListItem *nextItem;
01184
01185
01186 assert(list != NULL);
01187 assert(item != NULL);
01188 assert(list->find(list, list->data(list, item)) != NULL);
01189
01190
01191 prevItem = _xanListPrev(list, item);
01192 nextItem = _xanListNext(list, item);
01193
01194
01195 if (nextItem == NULL){
01196
01197
01198
01199 assert(list->lastItem == item);
01200 list->lastItem = prevItem;
01201 }
01202
01203
01204 if (prevItem == NULL){
01205
01206
01207 assert(list->firstItem == item);
01208 assert(prevItem == NULL);
01209 list->free(item);
01210 list->firstItem = nextItem;
01211 if (nextItem != NULL){
01212 nextItem->prev = NULL;
01213 }
01214 } else {
01215
01216
01217 assert(list->firstItem != item);
01218 assert(prevItem != NULL);
01219 assert(_xanListNext(list, prevItem) == item);
01220 list->free(item);
01221 prevItem->next = nextItem;
01222 if (nextItem != NULL){
01223 nextItem->prev = prevItem;
01224 }
01225 }
01226 (list->len)--;
01227
01228
01229 return;
01230 }
01231
01232 static inline int _xanListContainsTheSameElements (XanList *list, XanList *otherList){
01233 XanListItem *item;
01234
01235
01236 assert(list != NULL);
01237 assert(otherList != NULL);
01238
01239
01240 if (list->len != otherList->len) return 0;
01241
01242
01243 item = _xanListFirst(list);
01244 while (item != NULL){
01245 if (_xanListFind(otherList, item->data) == NULL) return 0;
01246 item = _xanListNext(list, item);
01247 }
01248
01249
01250
01251
01252 return 1;
01253 }
01254
01255 static inline void _xanListDeleteAll (XanList *list, void *data){
01256 XanListItem *item;
01257 XanListItem *prevItem;
01258 XanListItem *nextItem;
01259
01260
01261 assert(list != NULL);
01262 assert(data != NULL);
01263
01264
01265 item = NULL;
01266 prevItem = NULL;
01267 nextItem = NULL;
01268
01269
01270 item = _xanListFind(list, data);
01271 while (item != NULL){
01272 assert(_xanListData(list, item) == data);
01273 prevItem = _xanListPrev(list, item);
01274 nextItem = _xanListNext(list, item);
01275 assert(_xanListData(list, item) == data);
01276
01277
01278 if (nextItem == NULL){
01279
01280
01281
01282 assert(list->lastItem == item);
01283 list->lastItem = prevItem;
01284 }
01285
01286
01287 if (prevItem == NULL){
01288
01289
01290 assert(list->firstItem == item);
01291 assert(prevItem == NULL);
01292 list->free(item);
01293 list->firstItem = nextItem;
01294 if (nextItem != NULL){
01295 nextItem->prev = NULL;
01296 }
01297 } else {
01298
01299
01300 assert(list->firstItem != item);
01301 assert(prevItem != NULL);
01302 assert(_xanListNext(list, prevItem) == item);
01303 list->free(item);
01304 prevItem->next = nextItem;
01305 if (nextItem != NULL){
01306 nextItem->prev = prevItem;
01307 }
01308 }
01309
01310
01311 (list->len)--;
01312
01313
01314 item = _xanListFind(list, data);
01315 }
01316
01317
01318 return;
01319 }
01320
01321 static inline void _xanListDelete (XanList *list, void *data){
01322 XanListItem *item;
01323 XanListItem *prevItem;
01324 XanListItem *nextItem;
01325
01326
01327 assert(list != NULL);
01328 assert(data != NULL);
01329
01330
01331 item = NULL;
01332 prevItem = NULL;
01333 nextItem = NULL;
01334
01335
01336 item = _xanListFind(list, data);
01337 if (item != NULL){
01338 assert(_xanListData(list, item) == data);
01339 prevItem = _xanListPrev(list, item);
01340 nextItem = _xanListNext(list, item);
01341 } else {
01342 print_err("XANLIB: ERROR = There is no the element to delete from the list. ", 0);
01343 abort();
01344 }
01345 assert(item != NULL);
01346 assert(_xanListData(list, item) == data);
01347
01348
01349 if (nextItem == NULL){
01350
01351
01352
01353 assert(list->lastItem == item);
01354 list->lastItem = prevItem;
01355 }
01356
01357
01358 if (prevItem == NULL){
01359
01360
01361 assert(list->firstItem == item);
01362 assert(prevItem == NULL);
01363 list->free(item);
01364 list->firstItem = nextItem;
01365 if (nextItem != NULL){
01366 nextItem->prev = NULL;
01367 }
01368 } else {
01369
01370
01371 assert(list->firstItem != item);
01372 assert(prevItem != NULL);
01373 assert(_xanListNext(list, prevItem) == item);
01374 list->free(item);
01375 prevItem->next = nextItem;
01376 if (nextItem != NULL){
01377 nextItem->prev = prevItem;
01378 }
01379 }
01380 (list->len)--;
01381
01382
01383 return;
01384 }
01385
01386 XanVar * xanVarNew(void *(*allocFunction) (size_t size), void (*freeFunction) (void *addr)){
01387 XanVar *var;
01388
01389
01390 assert(allocFunction != NULL);
01391 assert(freeFunction != NULL);
01392
01393
01394 var = (XanVar *) allocFunction(sizeof(XanVar));
01395 assert(var != NULL);
01396 var->data = NULL;
01397 var->alloc = allocFunction;
01398 var->free = free;
01399 var->synchRead = varRead;
01400 var->synchWrite = varWrite;
01401 var->read = _varRead;
01402 var->write = _varWrite;
01403 var->lock = varLock;
01404 var->destroyVarAndData = varDestroyVarAndData;
01405 var->unlock = varUnlock;
01406 sem_init(&(var->mutex), 0, 1);
01407
01408
01409 return var;
01410 }
01411
01412 static inline void varDestroyVarAndData (XanVar *var){
01413
01414
01415 assert(var != NULL);
01416
01417 sem_wait(&(var->mutex));
01418 if (var->data != NULL){
01419 var->free(var->data);
01420 }
01421 var->free(var);
01422 }
01423
01424 static inline void varLock (XanVar *var){
01425
01426
01427 assert(var != NULL);
01428
01429 sem_wait(&(var->mutex));
01430 }
01431
01432 static inline void varUnlock (XanVar *var){
01433
01434
01435 assert(var != NULL);
01436
01437 sem_post(&(var->mutex));
01438 }
01439
01440 static inline void * varRead (XanVar *var){
01441 void *data;
01442
01443
01444 assert(var != NULL);
01445
01446 sem_wait(&(var->mutex));
01447 data = _varRead(var);
01448 sem_post(&(var->mutex));
01449 return data;
01450 }
01451
01452 static inline void * _varRead (XanVar *var){
01453 return var->data;
01454 }
01455
01456 static inline void varWrite (XanVar *var, void *data){
01457
01458
01459 assert(var != NULL);
01460
01461 sem_wait(&(var->mutex));
01462 _varWrite(var, data);
01463 sem_post(&(var->mutex));
01464 }
01465
01466 static inline void _varWrite (XanVar *var, void *data){
01467 var->data = data;
01468 }
01469
01470 XanPipe * xanPipeNew (void *(*allocFunction) (size_t size), void (*freeFunction) (void *addr)){
01471 XanPipe *newPipe;
01472
01473
01474 assert(allocFunction != NULL);
01475 assert(freeFunction != NULL);
01476
01477
01478 newPipe = NULL;
01479
01480
01481 newPipe = allocFunction(sizeof(XanPipe));
01482 assert(newPipe != NULL);
01483
01484
01485 newPipe->alloc = allocFunction;
01486 newPipe->free = freeFunction;
01487 newPipe->synchIsEmpty = xanPipeIsEmpty;
01488 newPipe->synchGet = xanPipeGet;
01489 newPipe->synchPut = xanPipePut;
01490 newPipe->synchPutAtEnd = xanPipePutAtEnd;
01491 newPipe->synchMoveToEnd = xanPipeMoveToEnd;
01492 newPipe->synchDeleteItem = xanPipeDeleteItem;
01493 newPipe->get = _xanPipeGet;
01494 newPipe->put = _xanPipePut;
01495 newPipe->putAtEnd = _xanPipePutAtEnd;
01496 newPipe->moveToEnd = _xanPipeMoveToEnd;
01497 newPipe->deleteItem = _xanPipeDeleteItem;
01498 newPipe->isEmpty = _xanPipeIsEmpty;
01499 newPipe->destroyPipe = _xanPipeDestroyPipe;
01500 newPipe->lock = xanPipeLock;
01501 newPipe->unlock = xanPipeUnlock;
01502 newPipe->items = xanListNew(newPipe->alloc, newPipe->free, NULL);
01503 assert(newPipe->items != NULL);
01504 pthread_mutex_init(&(newPipe->itemsMutex), NULL);
01505 pthread_cond_init(&(newPipe->itemsCond), NULL);
01506
01507
01508 return newPipe;
01509 }
01510
01511 static inline int xanPipeIsEmpty (XanPipe *pipe){
01512 int result;
01513
01514
01515 assert(pipe != NULL);
01516
01517 pthread_mutex_lock(&(pipe->itemsMutex));
01518 result = _xanPipeIsEmpty(pipe);
01519 pthread_mutex_unlock(&(pipe->itemsMutex));
01520 return result;
01521 }
01522
01523 static inline void * xanPipeGet (XanPipe *pipe){
01524 XanListItem *item;
01525 XanListItem *tempItem;
01526 int count;
01527 void *data;
01528
01529
01530 assert(pipe != NULL);
01531 assert(pipe->items != NULL);
01532
01533
01534 count = 0;
01535 data = NULL;
01536 item = NULL;
01537 tempItem = NULL;
01538
01539
01540
01541 pthread_mutex_lock(&(pipe->itemsMutex));
01542 while (pipe->items->length(pipe->items) == 0){
01543 pthread_cond_wait(&(pipe->itemsCond), &(pipe->itemsMutex));
01544 }
01545 item = _xanListFirst(pipe->items);
01546 assert(item != NULL);
01547 data = _xanListData(pipe->items, item);
01548 _xanListDeleteItem(pipe->items, item);
01549
01550
01551 #ifdef DEBUG
01552 tempItem = pipe->items->first(pipe->items);
01553 for (count=0; count < pipe->items->length(pipe->items); count++){
01554 assert(tempItem != NULL);
01555 tempItem = pipe->items->next(pipe->items, tempItem);
01556 }
01557 #endif
01558 pthread_mutex_unlock(&(pipe->itemsMutex));
01559
01560
01561 return data;
01562 }
01563
01564 static inline XanListItem * xanPipeMoveToEnd (XanPipe *pipe, void *item){
01565 XanListItem *pipeItem;
01566
01567 pthread_mutex_lock(&(pipe->itemsMutex));
01568 pipeItem = _xanPipeMoveToEnd(pipe, item);
01569 pthread_mutex_unlock(&(pipe->itemsMutex));
01570
01571 return pipeItem;
01572 }
01573
01574 static inline void xanPipeDeleteItem (XanPipe *pipe, XanListItem *item){
01575
01576 pthread_mutex_lock(&(pipe->itemsMutex));
01577 _xanPipeDeleteItem(pipe, item);
01578 pthread_mutex_unlock(&(pipe->itemsMutex));
01579 }
01580
01581 static inline XanListItem * xanPipePutAtEnd (XanPipe *pipe, void *item){
01582 XanListItem *pipeItem;
01583
01584 pthread_mutex_lock(&(pipe->itemsMutex));
01585 pipeItem = _xanPipePutAtEnd(pipe, item);
01586 pthread_mutex_unlock(&(pipe->itemsMutex));
01587
01588 return pipeItem;
01589 }
01590
01591 static inline XanListItem * xanPipePut (XanPipe *pipe, void *item){
01592 XanListItem *pipeItem;
01593
01594 pthread_mutex_lock(&(pipe->itemsMutex));
01595 pipeItem = _xanPipePut(pipe, item);
01596 pthread_mutex_unlock(&(pipe->itemsMutex));
01597
01598 return pipeItem;
01599 }
01600
01601 static inline void * _xanPipeGet (XanPipe *pipe){
01602 XanListItem *item;
01603 XanListItem *tempItem;
01604 int count;
01605 void *data;
01606
01607
01608 assert(pipe != NULL);
01609 assert(pipe->items != NULL);
01610
01611
01612 count = 0;
01613 data = NULL;
01614 item = NULL;
01615 tempItem = NULL;
01616
01617
01618
01619 pthread_mutex_lock(&(pipe->itemsMutex));
01620 while (pipe->items->length(pipe->items) == 0){
01621 pthread_cond_wait(&(pipe->itemsCond), &(pipe->itemsMutex));
01622 }
01623 pthread_mutex_unlock(&(pipe->itemsMutex));
01624 item = _xanListFirst(pipe->items);
01625 assert(item != NULL);
01626 data = _xanListData(pipe->items, item);
01627 _xanListDeleteItem(pipe->items, item);
01628
01629
01630 #ifdef DEBUG
01631 tempItem = pipe->items->first(pipe->items);
01632 for (count=0; count < pipe->items->length(pipe->items); count++){
01633 assert(tempItem != NULL);
01634 assert(pipe->items->data(pipe->items, tempItem) != NULL);
01635 tempItem = pipe->items->next(pipe->items, tempItem);
01636 }
01637 #endif
01638
01639
01640 return data;
01641 }
01642
01643 static inline XanListItem * _xanPipeMoveToEnd (XanPipe *pipe, void *item){
01644 XanListItem *itemList;
01645
01646
01647 assert(pipe != NULL);
01648 assert(pipe->items != NULL);
01649 assert(item != NULL);
01650 PDEBUG("XANLIB: xanPipeMoveToEnd: Start\n");
01651
01652
01653
01654 PDEBUG("XANLIB: xanPipeMoveToEnd: Move to the end of the pipe the element\n");
01655 itemList = _xanListFind(pipe->items, item);
01656 if (itemList != NULL){
01657 assert(pipe->items->equalsInstancesNumber(pipe->items, item) == 1);
01658 assert(pipe->items->length(pipe->items) > 0);
01659 assert(pipe->items->data(pipe->items, itemList) == item);
01660 itemList = _xanListMoveToBegin(pipe->items, itemList);
01661 assert(pipe->items->data(pipe->items, itemList) == item);
01662 assert(pipe->items->length(pipe->items) > 0);
01663 assert(pipe->items->equalsInstancesNumber(pipe->items, item) == 1);
01664 }
01665
01666
01667 PDEBUG("XANLIB: xanPipeMoveToEnd: Exit\n");
01668 return itemList;
01669 }
01670
01671 static inline void _xanPipeDeleteItem (XanPipe *pipe, XanListItem *item){
01672
01673
01674 assert(pipe != NULL);
01675 assert(item != NULL);
01676
01677 _xanListDeleteItem(pipe->items, item);
01678 }
01679
01680 static inline void xanPipeLock (XanPipe *pipe){
01681
01682
01683 assert(pipe != NULL);
01684
01685 pthread_mutex_lock(&(pipe->itemsMutex));
01686 }
01687
01688 static inline void xanPipeUnlock (XanPipe *pipe){
01689
01690
01691 assert(pipe != NULL);
01692
01693 pthread_mutex_unlock(&(pipe->itemsMutex));
01694 }
01695
01696 static inline XanListItem * _xanPipePutAtEnd (XanPipe *pipe, void *item){
01697 XanListItem *pipeItem;
01698
01699
01700 assert(pipe != NULL);
01701 assert(pipe->items != NULL);
01702 assert(pipe->items->synchAppend != NULL);
01703 assert(item != NULL);
01704 PDEBUG("XANLIB: xanPipePutAtEnd: Start\n");
01705
01706
01707
01708 PDEBUG("XANLIB: xanPipePutAtEnd: Inserted the new element\n");
01709 pipeItem = _xanListInsert(pipe->items, item);
01710 assert(pipeItem != NULL);
01711 assert(pipe->items->data(pipe->items, pipeItem) == item);
01712 pthread_cond_signal(&(pipe->itemsCond));
01713
01714
01715 PDEBUG("XANLIB: xanPipePutAtEnd: Exit\n");
01716 return pipeItem;
01717 }
01718
01719 static inline void _xanPipeDestroyPipe (XanPipe *pipe){
01720
01721
01722 assert(pipe != NULL);
01723 assert(pipe->items != NULL);
01724
01725 _xanListDestroy(pipe->items);
01726 }
01727
01728 static inline XanListItem * _xanPipePut (XanPipe *pipe, void *item){
01729 XanListItem *pipeItem;
01730
01731
01732 assert(pipe != NULL);
01733 assert(pipe->items != NULL);
01734 assert(pipe->items->synchAppend != NULL);
01735 PDEBUG("XANLIB: xanPipePut: Start\n");
01736
01737
01738
01739 PDEBUG("XANLIB: xanPipePut: Inserted the new element\n");
01740 pipeItem = _xanListAppend(pipe->items, item);
01741 assert(pipeItem != NULL);
01742 assert(pipe->items->data(pipe->items, pipeItem) == item);
01743 pthread_cond_signal(&(pipe->itemsCond));
01744
01745
01746 PDEBUG("XANLIB: xanPipePut: Exit\n");
01747 return pipeItem;
01748 }
01749
01750 static inline int _xanPipeIsEmpty (XanPipe *pipe){
01751
01752
01753 assert(pipe != NULL);
01754
01755 return (_xanListLength(pipe->items) == 0);
01756 }
01757
01758 XanStack * xanStackNew (void *(*allocFunction) (size_t size), void (*freeFunction) (void *addr), void * (*cloneFunction) (void *data)){
01759 XanStack *stack;
01760
01761
01762 assert(allocFunction != NULL);
01763 assert(freeFunction != NULL);
01764
01765
01766 stack = allocFunction(sizeof(XanStack));
01767 assert(stack != NULL);
01768
01769
01770 stack->internalList = xanListNew(allocFunction, freeFunction, cloneFunction);
01771 assert(stack->internalList != NULL);
01772 sem_init(&(stack->mutex), 0, 1);
01773 stack->synchPop = xanStackPop;
01774 stack->synchPush = xanStackPush;
01775 stack->synchGetSize = xanStackGetSize;
01776 stack->pop = _xanStackPop;
01777 stack->push = _xanStackPush;
01778 stack->getSize = _xanStackGetSize;
01779 stack->destroyStack = _xanStackDestroyStack;
01780
01781
01782 return stack;
01783 }
01784
01785 XanNode * xanNodeNew (void *(*allocFunction) (size_t size), void (*freeFunction) (void *addr), void * (*cloneFunction) (void *data)){
01786 XanNode *newNode;
01787
01788
01789 assert(allocFunction != NULL);
01790 assert(freeFunction != NULL);
01791
01792
01793 newNode = NULL;
01794
01795
01796 newNode = allocFunction(sizeof(XanNode));
01797 assert(newNode != NULL);
01798
01799
01800 newNode->alloc = allocFunction;
01801 newNode->free = freeFunction;
01802 newNode->clone = cloneFunction;
01803 newNode->synchGetParent = xanNodeGetParent;
01804 newNode->synchGetNextChildren = xanNodeGetNextChildren;
01805 newNode->synchAddNewChildren = xanNodeAddNewChildren;
01806 newNode->synchAddChildren = xanNodeAddChildren;
01807 newNode->synchSetParent = xanNodeSetParent;
01808 newNode->synchSetData = xanNodeSetData;
01809 newNode->synchGetData = xanNodeGetData;
01810 newNode->synchCloneTree = xanNodeCloneTree;
01811 newNode->synchDeleteChildren = xanNodeDeleteChildren;
01812 newNode->synchGetChildrens = xanNodeGetChildrens;
01813 newNode->synchSetCloneFunction = xanNodeSetCloneFunction;
01814 newNode->synchDestroyTreeAndData= xanNodeDestroyTreeAndData;
01815 newNode->synchDestroyTree = xanNodeDestroyTree;
01816 newNode->synchToPreOrderList = xanNodeToPreOrderList;
01817 newNode->synchToPostOrderList = xanNodeToPostOrderList;
01818 newNode->synchToInOrderList = xanNodeToInOrderList;
01819 newNode->synchFind = xanNodeFind;
01820 newNode->getParent = _xanNodeGetParent;
01821 newNode->getNextChildren = _xanNodeGetNextChildren;
01822 newNode->addNewChildren = _xanNodeAddNewChildren;
01823 newNode->addChildren = _xanNodeAddChildren;
01824 newNode->setParent = _xanNodeSetParent;
01825 newNode->setData = _xanNodeSetData;
01826 newNode->getData = _xanNodeGetData;
01827 newNode->cloneTree = _xanNodeCloneTree;
01828 newNode->deleteChildren = _xanNodeDeleteChildren;
01829 newNode->getChildrens = _xanNodeGetChildrens;
01830 newNode->setCloneFunction = _xanNodeSetCloneFunction;
01831 newNode->destroyTreeAndData = _xanNodeDestroyTreeAndData;
01832 newNode->destroyTree = _xanNodeDestroyTree;
01833 newNode->destroyNode = _xanNodeDestroyNode;
01834 newNode->toPreOrderList = _xanNodeToPreOrderList;
01835 newNode->toPostOrderList = _xanNodeToPostOrderList;
01836 newNode->toInOrderList = _xanNodeToInOrderList;
01837 newNode->find = _xanNodeFind;
01838 newNode->childrens = xanListNew(allocFunction, freeFunction, NULL);
01839 newNode->parent = NULL;
01840 newNode->data = NULL;
01841 sem_init(&(newNode->mutex), 0, 1);
01842 assert(newNode->childrens != NULL);
01843
01844
01845 return newNode;
01846 }
01847
01848 static inline XanList * xanNodeToPreOrderList (XanNode *node){
01849 XanList *list;
01850
01851
01852 assert(node != NULL);
01853
01854 sem_wait(&(node->mutex));
01855 list = _xanNodeToPreOrderList(node);
01856 assert(list != NULL);
01857 sem_post(&(node->mutex));
01858
01859 return list;
01860 }
01861
01862 static inline XanList * xanNodeToPostOrderList (XanNode *node){
01863 XanList *list;
01864
01865
01866 assert(node != NULL);
01867
01868 sem_wait(&(node->mutex));
01869 list = _xanNodeToPostOrderList(node);
01870 assert(list != NULL);
01871 sem_post(&(node->mutex));
01872
01873 return list;
01874 }
01875
01876 static inline XanNode * xanNodeFind (XanNode *rootNode, void *data){
01877 XanNode *node;
01878
01879
01880 assert(rootNode != NULL);
01881
01882 sem_wait(&(rootNode->mutex));
01883 node = _xanNodeFind(rootNode, data);
01884 sem_post(&(rootNode->mutex));
01885
01886 return node;
01887 }
01888
01889 static inline XanList * xanNodeToInOrderList (XanNode *node){
01890 XanList *list;
01891
01892
01893 assert(node != NULL);
01894
01895 sem_wait(&(node->mutex));
01896 list = _xanNodeToInOrderList(node);
01897 assert(list != NULL);
01898 sem_post(&(node->mutex));
01899
01900 return list;
01901 }
01902
01903 static inline void xanNodeDestroyTree (XanNode *node){
01904
01905
01906 assert(node != NULL);
01907
01908 sem_wait(&(node->mutex));
01909 _xanNodeDestroyTree(node);
01910 sem_post(&(node->mutex));
01911 }
01912
01913 static inline void xanNodeDestroyTreeAndData (XanNode *node){
01914
01915
01916 assert(node != NULL);
01917
01918 sem_wait(&(node->mutex));
01919 _xanNodeDestroyTreeAndData(node);
01920 sem_post(&(node->mutex));
01921 }
01922
01923 static inline void xanNodeSetCloneFunction (XanNode *node, void * (*cloneFunction) (void *data)){
01924
01925
01926 assert(node != NULL);
01927
01928 sem_wait(&(node->mutex));
01929 _xanNodeSetCloneFunction(node, cloneFunction);
01930 sem_post(&(node->mutex));
01931 }
01932
01933 static inline XanList * xanNodeGetChildrens (XanNode *node){
01934 XanList *childrens;
01935
01936
01937 assert(node != NULL);
01938
01939 sem_wait(&(node->mutex));
01940 childrens = _xanNodeGetChildrens(node);
01941 sem_post(&(node->mutex));
01942
01943 return childrens;
01944 }
01945
01946 static inline XanNode * xanNodeCloneTree (XanNode *node){
01947 XanNode *clone;
01948
01949
01950 assert(node != NULL);
01951
01952 sem_wait(&(node->mutex));
01953 clone = _xanNodeCloneTree(node);
01954 sem_post(&(node->mutex));
01955
01956 return clone;
01957 }
01958
01959 static inline void * xanNodeGetData (XanNode *node){
01960 void *data;
01961
01962
01963 assert(node != NULL);
01964
01965 sem_wait(&(node->mutex));
01966 data = _xanNodeGetData(node);
01967 sem_post(&(node->mutex));
01968
01969 return data;
01970 }
01971
01972 static inline void xanNodeSetData (XanNode *node, void *data){
01973
01974
01975 assert(node != NULL);
01976
01977 sem_wait(&(node->mutex));
01978 _xanNodeSetData(node, data);
01979 sem_post(&(node->mutex));
01980 }
01981
01982 static inline XanNode * xanNodeGetParent (XanNode *node){
01983 XanNode *parent;
01984
01985
01986 assert(node != NULL);
01987
01988 sem_wait(&(node->mutex));
01989 parent = _xanNodeGetParent(node);
01990 sem_post(&(node->mutex));
01991
01992 return parent;
01993 }
01994
01995 static inline XanNode * xanNodeGetNextChildren (XanNode *node, XanNode *child){
01996 XanNode *nextChild;
01997
01998
01999 assert(node != NULL);
02000
02001 sem_wait(&(node->mutex));
02002 nextChild = _xanNodeGetNextChildren(node, child);
02003 sem_post(&(node->mutex));
02004
02005 return nextChild;
02006 }
02007
02008 static inline void xanNodeDeleteChildren (XanNode *node, XanNode *child){
02009
02010
02011 assert(node != NULL);
02012 assert(child != NULL);
02013
02014 sem_wait(&(node->mutex));
02015 _xanNodeDeleteChildren(node, child);
02016 sem_post(&(node->mutex));
02017 }
02018
02019 static inline void xanNodeAddChildren (XanNode *node, XanNode *child){
02020
02021
02022 assert(node != NULL);
02023 assert(child != NULL);
02024
02025 sem_wait(&(node->mutex));
02026 _xanNodeAddChildren(node, child);
02027 sem_post(&(node->mutex));
02028 }
02029
02030 static inline XanNode * xanNodeAddNewChildren (XanNode *node, void *childData){
02031 XanNode *newNode;
02032
02033
02034 assert(node != NULL);
02035
02036 sem_wait(&(node->mutex));
02037 newNode = _xanNodeAddNewChildren(node, childData);
02038 sem_post(&(node->mutex));
02039
02040 return newNode;
02041 }
02042
02043 static inline void xanNodeSetParent (XanNode *node, XanNode *parent){
02044
02045
02046 assert(node != NULL);
02047
02048 sem_wait(&(node->mutex));
02049 _xanNodeSetParent(node, parent);
02050 sem_post(&(node->mutex));
02051
02052 return;
02053 }
02054
02055 static inline void _xanNodeSetData (XanNode *node, void *data){
02056
02057
02058 assert(node != NULL);
02059
02060 node->data = data;
02061 }
02062
02063 static inline void * _xanNodeGetData (XanNode *node){
02064
02065
02066 assert(node != NULL);
02067
02068 return node->data;
02069 }
02070
02071 static inline void _xanNodeDestroyTreeAndData (XanNode *node){
02072 XanNode *child;
02073 XanNode *childNext;
02074
02075
02076 assert(node != NULL);
02077
02078 child = _xanNodeGetNextChildren(node, NULL);
02079 while (child != NULL){
02080 childNext = _xanNodeGetNextChildren(node, child);
02081 _xanNodeDestroyTreeAndData(child);
02082 child = childNext;
02083 }
02084
02085 if (node->data != NULL){
02086 node->free(node->data);
02087 }
02088 _xanListDestroy(node->childrens);
02089 node->free(node);
02090 }
02091
02092 static inline void _xanNodeDestroyNode (XanNode *node){
02093
02094
02095 assert(node != NULL);
02096 assert(node->childrens != NULL);
02097
02098 _xanListDestroy(node->childrens);
02099 node->free(node);
02100 }
02101
02102
02103 static inline void _xanNodeDestroyTree (XanNode *node){
02104 XanNode *child;
02105 XanNode *childNext;
02106
02107
02108 assert(node != NULL);
02109 assert(node->childrens != NULL);
02110
02111 child = _xanNodeGetNextChildren(node, NULL);
02112 while (child != NULL){
02113 childNext = _xanNodeGetNextChildren(node, child);
02114 _xanNodeDestroyTree(child);
02115 child = childNext;
02116 }
02117 _xanListDestroy(node->childrens);
02118 node->free(node);
02119 }
02120
02121 static inline XanList * _xanNodeToPreOrderList (XanNode *node){
02122 XanList *list;
02123
02124
02125 assert(node != NULL);
02126
02127
02128 list = xanListNew(node->alloc, node->free, node->clone);
02129 assert(list != NULL);
02130 internalPreOrderListHelpFunction(node, list);
02131 assert(list->length(list) > 0);
02132
02133 return list;
02134 }
02135
02136 static inline XanList * _xanNodeToPostOrderList (XanNode *node){
02137 XanList *list;
02138
02139
02140 assert(node != NULL);
02141
02142
02143 list = xanListNew(node->alloc, node->free, node->clone);
02144 assert(list != NULL);
02145 internalPostOrderListHelpFunction(node, list);
02146 assert(list->length(list) > 0);
02147
02148 return list;
02149 }
02150
02151 static inline XanNode * _xanNodeFind (XanNode *rootNode, void *data){
02152 XanNode *child;
02153 XanNode *node;
02154
02155
02156 assert(rootNode != NULL);
02157
02158 if (rootNode->data == data) return rootNode;
02159 child = rootNode->getNextChildren(rootNode, NULL);
02160 while (child != NULL){
02161 node = _xanNodeFind(child, data);
02162 if (node != NULL) return node;
02163 child = rootNode->getNextChildren(rootNode, child);
02164 }
02165
02166 return NULL;
02167 }
02168
02169 static inline XanList * _xanNodeToInOrderList (XanNode *node){
02170 XanList *list;
02171
02172
02173 assert(node != NULL);
02174
02175
02176 list = xanListNew(node->alloc, node->free, node->clone);
02177 assert(list != NULL);
02178 internalInOrderListHelpFunction(node, list);
02179 assert(list->length(list) > 0);
02180
02181 return list;
02182 }
02183
02184 static inline void _xanNodeSetCloneFunction (XanNode *node, void * (*cloneFunction) (void *data)){
02185
02186
02187 assert(node != NULL);
02188
02189 node->clone = cloneFunction;
02190 node->childrens->setCloneFunction(node->childrens, cloneFunction);
02191 }
02192
02193 static inline XanNode * _xanNodeCloneTree (XanNode *node){
02194 XanNode *clone;
02195 XanNode *child;
02196 XanNode *childClone;
02197 void *cloneData;
02198
02199
02200 assert(node != NULL);
02201
02202
02203 clone = xanNodeNew(node->alloc, node->free, node->clone);
02204 assert(clone != NULL);
02205 if (node->clone != NULL){
02206 cloneData = node->clone(node->data);
02207 } else {
02208 cloneData = node->data;
02209 }
02210 _xanNodeSetData(clone, cloneData);
02211
02212
02213 child = node->getNextChildren(node, NULL);
02214 while (child != NULL){
02215 childClone = _xanNodeCloneTree(child);
02216 assert(childClone != NULL);
02217 _xanListInsert(clone->childrens, childClone);
02218 child = node->getNextChildren(node, child);
02219 }
02220
02221
02222 return clone;
02223 }
02224
02225 static inline XanNode * _xanNodeGetParent (XanNode *node){
02226
02227
02228 assert(node != NULL);
02229
02230 #ifdef DEBUG
02231 if (node->parent != NULL){
02232 XanNode *item;
02233 item = node->parent->getNextChildren(node->parent, NULL);
02234 while (item != NULL){
02235 if (item == node) break;
02236 item = node->parent->getNextChildren(node->parent, item);
02237 }
02238 assert(item != NULL);
02239 }
02240 #endif
02241
02242 return node->parent;
02243 }
02244
02245 static inline XanNode * _xanNodeGetNextChildren (XanNode *node, XanNode *child){
02246 XanListItem *item;
02247 XanNode *nextChild;
02248
02249
02250 assert(node != NULL);
02251
02252
02253 item = NULL;
02254 nextChild = NULL;
02255
02256 if (child == NULL){
02257 item = _xanListFirst(node->childrens);
02258 if (item != NULL){
02259 nextChild = (XanNode *) _xanListData(node->childrens, item);
02260 assert(nextChild != NULL);
02261 }
02262 return nextChild;
02263 }
02264 item = _xanListFirst(node->childrens);
02265 assert(item != NULL);
02266 while (item != NULL){
02267 if (_xanListData(node->childrens, item) == child) break;
02268 item = _xanListNext(node->childrens, item);
02269 }
02270 assert(item != NULL);
02271 item = _xanListNext(node->childrens, item);
02272 if (item != NULL){
02273 nextChild = _xanListData(node->childrens, item);
02274 assert(nextChild != NULL);
02275 }
02276 return nextChild;
02277 }
02278
02279 static inline void _xanNodeDeleteChildren (XanNode *node, XanNode *child){
02280
02281
02282 assert(node != NULL);
02283 assert(child != NULL);
02284 assert(child->data != NULL);
02285
02286
02287 _xanNodeSetParent(child, NULL);
02288
02289
02290 _xanListDelete(node->childrens, child);
02291 }
02292
02293 static inline void _xanNodeAddChildren (XanNode *node, XanNode *child){
02294 XanNode *oldParent;
02295
02296
02297 assert(node != NULL);
02298 assert(child != NULL);
02299
02300
02301
02302 oldParent = _xanNodeGetParent(child);
02303 if (oldParent != NULL){
02304 _xanNodeDeleteChildren(oldParent, child);
02305 }
02306
02307
02308 _xanNodeSetParent(child, node);
02309
02310
02311 _xanListAppend(node->childrens, child);
02312 }
02313
02314 static inline XanNode * _xanNodeAddNewChildren (XanNode *node, void *childData){
02315 XanNode *newChild;
02316
02317
02318 assert(node != NULL);
02319
02320
02321 newChild = xanNodeNew(node->alloc, node->free, node->clone);
02322 assert(newChild != NULL);
02323
02324
02325 _xanNodeSetParent(newChild, node);
02326 _xanNodeSetData(newChild, childData);
02327
02328
02329 _xanListAppend(node->childrens, newChild);
02330
02331
02332 return newChild;
02333 }
02334
02335 static inline void _xanNodeSetParent (XanNode *node, XanNode *parent){
02336
02337
02338 assert(node != NULL);
02339
02340 node->parent = parent;
02341 }
02342
02343 static inline XanList * _xanNodeGetChildrens (XanNode *node){
02344 XanList *childrens;
02345
02346
02347 assert(node != NULL);
02348
02349
02350 childrens = NULL;
02351
02352
02353 if (_xanListLength(node->childrens) > 0){
02354 childrens = _xanListCloneList(node->childrens);
02355 }
02356
02357
02358 return childrens;
02359 }
02360
02361 XanHashTable * xanHashTableNew(unsigned int length, int hasFixedLength, void *(*allocFunction) (size_t size), void *(*reallocFunction)(void *addr, size_t newSize), void (*freeFunction) (void *addr), unsigned int (*hashFunction) (void *element), int (*equalsFunction) (void *key1, void *key2)){
02362 XanHashTable *hashTable;
02363 unsigned int count;
02364
02365
02366 assert(allocFunction != NULL);
02367 assert(reallocFunction != NULL);
02368 assert(freeFunction != NULL);
02369 assert(length > 0);
02370
02371
02372 hashTable = (XanHashTable *) allocFunction(sizeof(XanHashTable));
02373 assert(hashTable != NULL);
02374
02375
02376 hashTable->alloc = allocFunction;
02377 hashTable->realloc = reallocFunction;
02378 hashTable->free = freeFunction;
02379 hashTable->clone = NULL;
02380 if (hashFunction == NULL){
02381 hashTable->hash = xanHashTableDefaultHashFunction;
02382 } else {
02383 hashTable->hash = hashFunction;
02384 }
02385 if (equalsFunction == NULL){
02386 hashTable->equals = xanHashTableDefaultEqualsFunction;
02387 } else {
02388 hashTable->equals = equalsFunction;
02389 }
02390 for (count = 0; count < PRIMES_TABLE_LENGTH ; count++){
02391 if (primes[count] > length){
02392 hashTable->primeIndex = count;
02393 hashTable->length = primes[count];
02394 break;
02395 }
02396 }
02397 hashTable->table = allocFunction(sizeof(XanHashTableItem) * hashTable->length);
02398 memset(hashTable->table, 0, sizeof(XanHashTableItem) * hashTable->length);
02399 hashTable->size = 0;
02400 hashTable->hasFixedLength = hasFixedLength;
02401 hashTable->currentLoadFactor = 0;
02402 hashTable->synchInsert = xanHashTableInsert;
02403 hashTable->synchLookup = xanHashTableLookup;
02404 hashTable->synchDelete = xanHashTableDelete;
02405 hashTable->synchDestroy = xanHashTableDestroy;
02406 hashTable->synchToList = xanHashTableToList;
02407 hashTable->synchToSlotList = xanHashTableToSlotList;
02408 hashTable->synchElementsInside = xanHashTableElementsInside;
02409 hashTable->synchCloneHashTable = xanHashTableCloneHashTable;
02410 hashTable->synchSetCloneFunction= xanHashTableSetCloneFunction;
02411 hashTable->synchGetCloneFunction= xanHashTableGetCloneFunction;
02412 hashTable->lock = _xanHashTableLock;
02413 hashTable->unlock = _xanHashTableUnlock;
02414 hashTable->insert = _xanHashTableInsert;
02415 hashTable->delete = _xanHashTableDelete;
02416 hashTable->destroy = _xanHashTableDestroy;
02417 hashTable->toList = _xanHashTableToList;
02418 hashTable->toSlotList = _xanHashTableToSlotList;
02419 hashTable->elementsInside = _xanHashTableElementsInside;
02420 hashTable->cloneHashTable = _xanHashTableCloneHashTable;
02421 hashTable->setCloneFunction = _xanHashTableSetCloneFunction;
02422 hashTable->getCloneFunction = _xanHashTableGetCloneFunction;
02423 hashTable->lookup = _xanHashTableLookup;
02424 sem_init(&(hashTable->mutex), 0, 1);
02425
02426
02427 return hashTable;
02428 }
02429
02430 static inline void xanHashTableSetCloneFunction(XanHashTable *table, void * (*cloneFunction) (void *data)){
02431
02432
02433 assert(table != NULL);
02434
02435 sem_wait(&(table->mutex));
02436 _xanHashTableSetCloneFunction(table, cloneFunction);
02437 sem_post(&(table->mutex));
02438 }
02439
02440 static inline void * xanHashTableGetCloneFunction (XanHashTable *table){
02441 void *function;
02442
02443
02444 assert(table != NULL);
02445
02446 sem_wait(&(table->mutex));
02447 function = _xanHashTableGetCloneFunction(table);
02448 sem_post(&(table->mutex));
02449
02450 return function;
02451 }
02452
02453 static inline XanHashTable * xanHashTableCloneHashTable (XanHashTable *table){
02454 XanHashTable *newTable;
02455
02456
02457 assert(table != NULL);
02458
02459 sem_wait(&(table->mutex));
02460 newTable = _xanHashTableCloneHashTable(table);
02461 assert(newTable != NULL);
02462 sem_post(&(table->mutex));
02463
02464 return newTable;
02465 }
02466
02467 static inline int xanHashTableElementsInside (XanHashTable *table){
02468 int count;
02469
02470
02471 assert(table != NULL);
02472
02473 sem_wait(&(table->mutex));
02474 count = _xanHashTableElementsInside(table);
02475 sem_post(&(table->mutex));
02476
02477 return count;
02478 }
02479
02480 static inline XanList * xanHashTableToSlotList (XanHashTable *table){
02481 XanList *list;
02482
02483
02484 assert(table != NULL);
02485
02486 sem_wait(&(table->mutex));
02487 list = _xanHashTableToSlotList(table);
02488 sem_post(&(table->mutex));
02489
02490 return list;
02491 }
02492
02493 static inline XanList * xanHashTableToList (XanHashTable *table){
02494 XanList *list;
02495
02496
02497 assert(table != NULL);
02498
02499 sem_wait(&(table->mutex));
02500 list = _xanHashTableToList(table);
02501 sem_post(&(table->mutex));
02502
02503 return list;
02504 }
02505
02506 static inline int xanHashTableDefaultEqualsFunction (void *key1, void *key2){
02507 if (key1 == key2) return 1;
02508 return 0;
02509 }
02510
02511 static inline unsigned int xanHashTableDefaultHashFunction (void *element){
02512 return (unsigned int ) element;
02513 }
02514
02515 static inline void xanHashTableInsert (XanHashTable *table, void *key, void *element){
02516
02517
02518 assert(table != NULL);
02519 assert(table->length > 0);
02520 assert(table->table != NULL);
02521 assert(key != NULL);
02522
02523 sem_wait(&(table->mutex));
02524 _xanHashTableInsert(table, key, element);
02525 sem_post(&(table->mutex));
02526 }
02527
02528 static inline void * xanHashTableLookup (XanHashTable *table, void *key){
02529 void *data;
02530
02531
02532 assert(table != NULL);
02533 assert(table->length > 0);
02534 assert(table->table != NULL);
02535
02536 sem_wait(&(table->mutex));
02537 data = _xanHashTableLookup(table, key);
02538 sem_post(&(table->mutex));
02539
02540 return data;
02541 }
02542
02543 static inline void xanHashTableDelete (XanHashTable *table, void *key){
02544
02545
02546 assert(table != NULL);
02547 assert(table->length > 0);
02548 assert(table->table != NULL);
02549
02550 sem_wait(&(table->mutex));
02551 _xanHashTableDelete(table, key);
02552 sem_post(&(table->mutex));
02553 }
02554
02555 static inline void xanHashTableDestroy (XanHashTable *table){
02556
02557
02558 assert(table != NULL);
02559 assert(table->length > 0);
02560 assert(table->table != NULL);
02561
02562 sem_wait(&(table->mutex));
02563 _xanHashTableDestroy(table);
02564 }
02565
02566 static inline void * _xanHashTableGetCloneFunction (XanHashTable *table){
02567
02568
02569 assert(table != NULL);
02570
02571 return table->clone;
02572 }
02573
02574 static inline void _xanHashTableSetCloneFunction(XanHashTable *table, void * (*cloneFunction) (void *data)){
02575
02576
02577 assert(table != NULL);
02578
02579 table->clone = cloneFunction;
02580 }
02581
02582 static inline XanHashTable * _xanHashTableCloneHashTable (XanHashTable *table){
02583 XanHashTable *newTable;
02584 void *newElement;
02585 unsigned int count;
02586
02587
02588 assert(table != NULL);
02589 assert(table->alloc != NULL);
02590 assert(table->realloc != NULL);
02591 assert(table->free != NULL);
02592 assert(table->hash != NULL);
02593 assert(table->equals != NULL);
02594
02595
02596 newTable = xanHashTableNew(table->length, table->hasFixedLength, table->alloc, table->realloc, table->free, table->hash, table->equals);
02597 assert(newTable != NULL);
02598 newTable->setCloneFunction(newTable, table->getCloneFunction(table));
02599 assert(table->clone == newTable->clone);
02600 for (count = 0; count < table->length; count++){
02601 XanHashTableItem *bucket=&(table->table[count]);
02602 if (bucket->used){
02603 while (bucket!=NULL){
02604 if (newTable->clone != NULL){
02605 assert(table->clone != NULL);
02606 newElement = newTable->clone(bucket->element);
02607 } else {
02608 assert(table->clone == NULL);
02609 newElement = bucket->element;
02610 }
02611 newTable->insert(newTable, bucket->elementID, newElement);
02612 bucket=bucket->next;
02613 }
02614 }
02615 }
02616 assert(newTable->elementsInside(newTable) == table->elementsInside(table));
02617
02618
02619 return newTable;
02620 }
02621
02622 static inline int _xanHashTableElementsInside (XanHashTable *table){
02623 int count;
02624
02625
02626 assert(table != NULL);
02627
02628 count = (int)table->size;
02629
02630 return count;
02631 }
02632
02633 static inline XanList * _xanHashTableToList (XanHashTable *table){
02634 XanHashTableItem* bucket;
02635 XanList *list;
02636 unsigned int count;
02637
02638
02639 assert(table != NULL);
02640
02641
02642 list = xanListNew(table->alloc, table->free, NULL);
02643 assert(list != NULL);
02644
02645
02646 for (count = 0; count < table->length; count++){
02647 bucket=&(table->table[count]);
02648 if (bucket->used){
02649 while (bucket!=NULL){
02650 _xanListInsert(list, bucket->element);
02651 bucket=bucket->next;
02652 }
02653 }
02654 }
02655
02656
02657 return list;
02658 }
02659
02660 XanList * XanHashTable_ToItemList (XanHashTable *table){
02661 XanHashTableItem* bucket;
02662 XanList *list;
02663 unsigned int count;
02664
02665
02666 assert(table != NULL);
02667
02668
02669 list = xanListNew(table->alloc, table->free, NULL);
02670 assert(list != NULL);
02671
02672
02673 for (count = 0; count < table->length; count++){
02674 bucket=&(table->table[count]);
02675 if (bucket->used){
02676 while (bucket!=NULL){
02677 _xanListInsert(list, bucket);
02678 bucket=bucket->next;
02679 }
02680 }
02681 }
02682
02683
02684 return list;
02685 }
02686
02687 static inline XanList * _xanHashTableToSlotList (XanHashTable *table){
02688 XanHashTableItem* bucket;
02689 XanList *list;
02690 unsigned int count;
02691
02692
02693 assert(table != NULL);
02694
02695
02696 list = xanListNew(table->alloc, table->free, NULL);
02697 assert(list != NULL);
02698
02699
02700 for (count = 0; count < table->length; count++){
02701 bucket=&(table->table[count]);
02702 if (bucket->used){
02703 while (bucket!=NULL){
02704 _xanListInsert(list, &(bucket->element));
02705 bucket=bucket->next;
02706 }
02707 }
02708 }
02709
02710
02711 return list;
02712 }
02713
02714 static inline void _xanHashTableLock (XanHashTable *table){
02715
02716
02717 assert(table != NULL);
02718 sem_wait(&(table->mutex));
02719 }
02720
02721 static inline void _xanHashTableUnlock (XanHashTable *table){
02722
02723
02724 assert(table != NULL);
02725 sem_post(&(table->mutex));
02726 }
02727
02728 static inline void _xanHashTableInsert (XanHashTable *table, void *key, void *element){
02729 unsigned int position;
02730 XanHashTableItem *bucket;
02731
02732
02733 assert(table != NULL);
02734 assert(table->length > 0);
02735 assert(table->table != NULL);
02736 assert(_xanHashTableLookup(table, key) == NULL);
02737
02738
02739 position = -1;
02740
02741
02742 if(table->currentLoadFactor >= HASHTABLE_DEFAULT_LOAD_FACTOR) {
02743
02744
02745 if(table->hasFixedLength) {
02746 print_err("HASH TABLE: ERROR = The element cannot be stored in the hash table. ", 0);
02747 abort();
02748 }
02749
02750
02751 _xanHashTableExpand(table);
02752 }
02753
02754
02755
02756 position = _xanHashTableImproveHash(table, key);
02757 position = position % (table->length);
02758 bucket = &(table->table[position]);
02759
02760 if(!bucket->used){
02761 bucket->elementID = key;
02762 bucket->element = element;
02763 bucket->used = true;
02764
02765 table->currentLoadFactor += 1.f / table->length;
02766
02767 }else {
02768 XanHashTableItem *item=table->alloc(sizeof(XanHashTableItem));
02769 item->next = NULL;
02770 item->elementID = key;
02771 item->element = element;
02772 item->used = true;
02773 while(bucket->next!=NULL) bucket=bucket->next;
02774 bucket->next=item;
02775 }
02776
02777 table->size++;
02778
02779 assert(_xanHashTableLookup(table, key) == element);
02780
02781
02782 return ;
02783 }
02784
02785 static inline void * _xanHashTableLookup (XanHashTable *table, void *key){
02786 XanHashTableItem *bucket;
02787 unsigned int position;
02788 void* result;
02789
02790
02791 assert(table != NULL);
02792 assert(table->length > 0);
02793 assert(table->table != NULL);
02794
02795 result = NULL;
02796
02797
02798
02799 position = _xanHashTableImproveHash(table, key);
02800 position %= (table->length);
02801 bucket = &(table->table[position]);
02802
02803 if (bucket->used){
02804 if(table->equals(bucket->elementID,key)){
02805 result = bucket->element;
02806 }else{
02807 bucket=bucket->next;
02808 while(bucket!=NULL){
02809 if(table->equals(bucket->elementID,key)){
02810 result = bucket->element;
02811 break;
02812 }
02813 bucket=bucket->next;
02814 }
02815 }
02816 }
02817 return result;
02818 }
02819
02820 static inline void _xanHashTableDelete (XanHashTable *table, void *key){
02821 XanHashTableItem* bucket;
02822 XanHashTableItem* prev;
02823 unsigned int position;
02824
02825
02826 assert(table != NULL);
02827 assert(table->length > 0);
02828 assert(table->table != NULL);
02829
02830
02831 position = -1;
02832 prev = NULL;
02833
02834
02835
02836 position = _xanHashTableImproveHash(table, key);
02837 position %= (table->length);
02838 bucket = &(table->table[position]);
02839
02840 if (bucket->used){
02841 if(table->equals(bucket->elementID,key)){
02842 if (bucket->next!=NULL){
02843 XanHashTableItem *tempBucket=bucket->next;
02844 bucket->elementID=tempBucket->elementID;
02845 bucket->element=tempBucket->element;
02846 bucket->next=tempBucket->next;
02847 table->free(tempBucket);
02848 }else{
02849 bucket->elementID = NULL;
02850 bucket->element = NULL;
02851 bucket->used=false;
02852
02853 table->currentLoadFactor -= 1.f / table->length;
02854 }
02855 table->size--;
02856 return;
02857 }else{
02858 prev=bucket;
02859 bucket=bucket->next;
02860 while(bucket!=NULL){
02861 if(table->equals(bucket->elementID,key)){
02862 prev->next=bucket->next;
02863 table->free(bucket);
02864 table->size--;
02865 return;
02866 }
02867 bucket=bucket->next;
02868 }
02869 }
02870 }
02871
02872 print_err("XANLIB: xanHashTableDelete: ERROR: Element not found. ", 0);
02873 abort();
02874 }
02875
02876 static inline void _xanHashTableExpand (XanHashTable* table) {
02877 XanHashTableItem* newTable;
02878 XanHashTableItem* bucket;
02879 XanHashTableItem* newBucket;
02880 XanHashTableItem* next;
02881 unsigned int newPrimeIndex;
02882 size_t newLength;
02883 size_t i;
02884 size_t newIndex;
02885 size_t elementsCount;
02886
02887
02888 newPrimeIndex = table->primeIndex+1;
02889 newLength = primes[newPrimeIndex];
02890 newTable = (XanHashTableItem*) table->alloc(sizeof(XanHashTableItem) * newLength);
02891 memset(newTable, 0, sizeof(XanHashTableItem) * newLength);
02892 elementsCount = 0;
02893
02894
02895 for(i = 0; i < table->length; i++) {
02896 bucket = &table->table[i];
02897 if(bucket->used) {
02898 newIndex = _xanHashTableImproveHash(table, bucket->elementID) % newLength;
02899 newBucket=&(newTable[newIndex]);
02900 if(!newBucket->used){
02901 newBucket->elementID = bucket->elementID;
02902 newBucket->element = bucket->element;
02903 newBucket->used = true;
02904 newBucket->next = NULL;
02905 elementsCount++;
02906 }else{
02907 XanHashTableItem *item=table->alloc(sizeof(XanHashTableItem));
02908 item->elementID = bucket->elementID;
02909 item->element = bucket->element;
02910 item->used = true;
02911 item->next = NULL;
02912 while(newBucket->next!=NULL){
02913 newBucket=newBucket->next;
02914 }
02915 newBucket->next=item;
02916 }
02917 bucket=bucket->next;
02918 while(bucket!=NULL){
02919 newIndex = _xanHashTableImproveHash(table, bucket->elementID) % newLength;
02920 newBucket=&(newTable[newIndex]);
02921 if(!newBucket->used){
02922 newBucket->elementID = bucket->elementID;
02923 newBucket->element = bucket->element;
02924 newBucket->used = true;
02925 newBucket->next = NULL;
02926 elementsCount++;
02927 }else{
02928 XanHashTableItem *item=table->alloc(sizeof(XanHashTableItem));
02929 item->elementID = bucket->elementID;
02930 item->element = bucket->element;
02931 item->used=true;
02932 item->next = NULL;
02933 while(newBucket->next!=NULL) newBucket=newBucket->next;
02934 newBucket->next=item;
02935 }
02936 next=bucket->next;
02937 table->free(bucket);
02938 bucket=next;
02939 }
02940 }
02941 }
02942
02943
02944 table->free(table->table);
02945 table->table = newTable;
02946 table->length = newLength;
02947 table->primeIndex =newPrimeIndex;
02948 table->currentLoadFactor = ((float) elementsCount / newLength);
02949
02950
02951 return ;
02952 }
02953
02954 static inline unsigned int _xanHashTableImproveHash(XanHashTable* table,void *key){
02955 unsigned int i = table->hash(key);
02956 i += ~(i << 9);
02957 i ^= ((i >> 14) | (i << 18));
02958 i += (i << 4);
02959 i ^= ((i >> 10) | (i << 22));
02960 return i;
02961 }
02962
02963
02964 static inline void _xanHashTableDestroy (XanHashTable *table){
02965 unsigned int count;
02966 XanHashTableItem *bucket;
02967 XanHashTableItem *next;
02968
02969
02970 assert(table != NULL);
02971 assert(table->length > 0);
02972 assert(table->table != NULL);
02973
02974
02975 for (count = 0; count < table->length; count++){
02976 bucket=&(table->table[count]);
02977 if (bucket->used){
02978 bucket=bucket->next;
02979 while (bucket!=NULL){
02980 next=bucket->next;
02981 table->free(bucket);
02982 bucket=next;
02983 }
02984 }
02985 }
02986 table->free(table->table);
02987
02988
02989 table->free(table);
02990
02991
02992 return;
02993 }
02994
02995 void print_ascii_err (signed char * message, int err){
02996 print_err((char *) message, err);
02997 }
02998
02999 void print_err (char * message, int err){
03000 fprintf(stderr, "%s", message);
03001 if (err==0) {
03002 fprintf(stderr, "\n");
03003 return;
03004 }
03005 fprintf(stderr, "Error:\n ");
03006 switch (err){
03007 case EACCES:
03008 fprintf(stderr, "EACCES=%s\n", strerror(err));
03009 break;
03010 case EAGAIN:
03011 fprintf(stderr, "EAGAIN=%s\n", strerror(err));
03012 break;
03013 case EBADF:
03014 fprintf(stderr, "EBADF=%s\n", strerror(err));
03015 break;
03016 case ECONNREFUSED:
03017 fprintf(stderr, "ECONNREFUSED=%s\n", strerror(err));
03018 break;
03019 case EEXIST:
03020 fprintf(stderr, "EEXIST=%s\n", strerror(err));
03021 break;
03022 case EFAULT:
03023 fprintf (stderr, "EFAULT=%s\n", strerror(err));
03024 break;
03025 case EINVAL:
03026 fprintf(stderr, "EINVAL=%s\n", strerror(err));
03027 break;
03028 case EINTR:
03029 fprintf(stderr, "EINTR=%s\n", strerror(err));
03030 break;
03031 case EMFILE:
03032 fprintf(stderr, "EMFILE=%s\n", strerror(err));
03033 break;
03034 case EMSGSIZE:
03035 fprintf(stderr, "EMSGSIZE=%s\n", strerror(err));
03036 break;
03037 case ENAMETOOLONG:
03038 fprintf(stderr, "ENAMETOOLONG=%s\n", strerror(err));
03039 break;
03040 case ENFILE:
03041 fprintf(stderr, "ENFILE=%s\n", strerror(err));
03042 break;
03043 case ENOENT:
03044 fprintf(stderr, "ENOENT=%s\n", strerror(err));
03045 break;
03046 case ENOSPC:
03047 fprintf(stderr, "ENOSPC=%s\n", strerror(err));
03048 break;
03049 case ENOMEM:
03050 fprintf(stderr, "ENOMEM=%s\n", strerror(err));
03051 break;
03052 case ENOTCONN:
03053 fprintf(stderr, "ENOTCONN=%s\n", strerror(err));
03054 break;
03055 case ENXIO:
03056 fprintf(stderr, "ENXIO=%s\n", strerror(err));
03057 break;
03058 case EPERM:
03059 fprintf (stderr, "EPERM=%s\n", strerror(err));
03060 break;
03061 case ERANGE:
03062 fprintf(stderr, "ERANGE=%s\n", strerror(err));
03063 break;
03064 case ETIMEDOUT:
03065 fprintf(stderr, "ETIMEDOUT=%s\n", strerror(err));
03066 break;
03067 default:
03068 fprintf(stderr, "I don't know\n");
03069 }
03070 }
03071
03072 int str_has_suffix(char *string, char *suffix){
03073 unsigned int count;
03074 unsigned int count2;
03075
03076 for (count=0, count2=0; count<strlen(string) && count2<strlen(suffix); count++){
03077 if (string[count]==suffix[count2]) count2++;
03078 else count2=0;
03079 }
03080 if (count==strlen(string) && count2==strlen(suffix)) return 1;
03081 return 0;
03082 }
03083
03084 static inline void internalPreOrderListHelpFunction(XanNode *tree, XanList *list){
03085 XanNode *child;
03086 void *data;
03087
03088
03089 assert(tree != NULL);
03090 assert(list != NULL);
03091
03092
03093 data = _xanNodeGetData(tree);
03094
03095
03096 _xanListAppend(list, data);
03097
03098
03099 child = tree->getNextChildren(tree, NULL);
03100 while (child != NULL){
03101 internalPreOrderListHelpFunction(child, list);
03102 child = tree->getNextChildren(tree, child);
03103 }
03104 }
03105
03106 static inline void internalPostOrderListHelpFunction(XanNode *tree, XanList *list){
03107 XanNode *child;
03108 void *data;
03109
03110
03111 assert(tree != NULL);
03112 assert(list != NULL);
03113
03114
03115 data = tree->getData(tree);
03116
03117
03118 child = tree->getNextChildren(tree, NULL);
03119 while (child != NULL){
03120 internalPostOrderListHelpFunction(child, list);
03121 child = tree->getNextChildren(tree, child);
03122 }
03123
03124
03125 _xanListAppend(list, data);
03126 }
03127
03128 static inline void internalInOrderListHelpFunction(XanNode *tree, XanList *list){
03129 XanNode *child;
03130 void *data;
03131
03132
03133 assert(tree != NULL);
03134 assert(list != NULL);
03135
03136
03137 data = tree->getData(tree);
03138
03139
03140 child = tree->getNextChildren(tree, NULL);
03141 if (child != NULL){
03142 internalInOrderListHelpFunction(child, list);
03143 }
03144
03145
03146 _xanListAppend(list, data);
03147
03148
03149 child = tree->getNextChildren(tree, child);
03150 while (child != NULL){
03151 internalPreOrderListHelpFunction(child, list);
03152 child = tree->getNextChildren(tree, child);
03153 }
03154 }
03155
03156 static inline void * xanStackPop (XanStack *stack){
03157 void *element;
03158
03159
03160 assert(stack != NULL);
03161
03162 sem_wait(&(stack->mutex));
03163 element = _xanStackPop(stack);
03164 sem_post(&(stack->mutex));
03165
03166 return element;
03167 }
03168
03169 static inline int xanStackGetSize (XanStack *stack){
03170 int size;
03171
03172
03173 assert(stack != NULL);
03174
03175 sem_wait(&(stack->mutex));
03176 size = _xanStackGetSize(stack);
03177 sem_post(&(stack->mutex));
03178
03179 return size;
03180 }
03181
03182 bool xanStackContains (XanStack *stack, void *element){
03183 void* elemFound;
03184
03185
03186 assert(stack != NULL);
03187
03188 elemFound = _xanListFind(stack->internalList, element);
03189
03190 if(elemFound==NULL) {
03191 return false;
03192 }
03193 else {
03194 return true;
03195 }
03196 }
03197
03198 bool xanStackSynchContains (XanStack *stack, void *element){
03199 bool res;
03200
03201 assert(stack != NULL);
03202
03203 sem_wait(&(stack->mutex));
03204 res = xanStackContains(stack, element);
03205 sem_post(&(stack->mutex));
03206
03207 return res;
03208 }
03209
03210 static inline void _xanStackDestroyStack (XanStack *stack){
03211
03212
03213 assert(stack != NULL);
03214 assert(stack->internalList != NULL);
03215
03216 _xanListDestroy(stack->internalList);
03217 }
03218
03219 static inline int _xanStackGetSize (XanStack *stack){
03220 int size;
03221
03222
03223 assert(stack != NULL);
03224
03225 size = _xanListLength(stack->internalList);
03226
03227 return size;
03228 }
03229
03230 static inline void xanStackPush (XanStack *stack, void *newElement){
03231
03232
03233 assert(stack != NULL);
03234
03235 sem_wait(&(stack->mutex));
03236 _xanStackPush(stack, newElement);
03237 sem_post(&(stack->mutex));
03238
03239 return;
03240 }
03241
03242 static inline void * _xanStackPop (XanStack *stack){
03243 XanListItem *item;
03244 void *element;
03245
03246
03247 assert(stack != NULL);
03248
03249 element = NULL;
03250
03251
03252 if (_xanListLength(stack->internalList) > 0){
03253 item = _xanListFirst(stack->internalList);
03254 assert(item != NULL);
03255 element = _xanListData(stack->internalList, item);
03256 _xanListDeleteItem(stack->internalList, item);
03257 }
03258
03259
03260 return element;
03261 }
03262
03263 static inline void _xanStackPush (XanStack *stack, void *newElement){
03264
03265
03266 assert(stack != NULL);
03267
03268 _xanListInsert(stack->internalList, newElement);
03269 }
03270
03271 void libxanCompilationFlags(char *buffer, int bufferLength){
03272
03273
03274 assert(buffer != NULL);
03275
03276 snprintf(buffer, sizeof(char)*bufferLength, " ");
03277 #ifdef DEBUG
03278 strncat(buffer, "DEBUG ", sizeof(char)*bufferLength);
03279 #endif
03280 #ifdef PRINTDEBUG
03281 strncat(buffer, "PRINTDEBUG ", sizeof(char)*bufferLength);
03282 #endif
03283 #ifdef PROFILE
03284 strncat(buffer, "PROFILE ", sizeof(char)*bufferLength);
03285 #endif
03286 }
03287
03288 void libxanCompilationTime (char *buffer, int bufferLength){
03289
03290
03291 assert(buffer != NULL);
03292
03293 snprintf(buffer, sizeof(char) * bufferLength, "%s %s", __DATE__, __TIME__);
03294 }
03295
03296 char * libxanVersion(){
03297 return VERSION;
03298 }
03299
03300
03301
03302
03303
03304 #define BITS_IN_A_WORD ( 8 * sizeof(size_t) )
03305
03306
03307 #define MASK(pos) ( ((size_t)1) << ((pos) % BITS_IN_A_WORD) )
03308
03309
03310 #define WORD_NUMBER(set, pos) ( (set)->data[(pos) / BITS_IN_A_WORD] )
03311
03312
03313 #define WORDS_NECESSARY(length) \
03314 ( ((length) + (BITS_IN_A_WORD - 1)) / BITS_IN_A_WORD )
03315
03316 XanBitSet* XanBitSet_Alloc(size_t length) {
03317 XanBitSet *set;
03318
03319 set = malloc(sizeof(XanBitSet));
03320 assert(set != NULL);
03321
03322 set->data = calloc(WORDS_NECESSARY(length), sizeof(size_t));
03323 set->length = length;
03324 assert(set->data);
03325
03326 return set;
03327 }
03328
03329 void XanBitSet_Intersect(XanBitSet *dest, XanBitSet *src) {
03330 size_t i;
03331 for (i=0; i < WORDS_NECESSARY(src->length); ++i)
03332 dest->data[i] &= src->data[i];
03333 }
03334
03335 int XanBitSet_GetCountOfBitsSet(XanBitSet *set) {
03336 size_t bitsetSize;
03337 size_t count;
03338 size_t i;
03339
03340 bitsetSize = set->length;
03341
03342 count = 0;
03343 for(i=0; i<bitsetSize; i++) {
03344 if(XanBitSet_IsBitSet(set, i)) {
03345 count++;
03346 }
03347 }
03348
03349 return count;
03350 }
03351
03352 bool XanBitSet_Equal(XanBitSet *bs1, XanBitSet *bs2) {
03353 if (bs1->length != bs2->length) return 0;
03354 return (memcmp(bs1->data, bs2->data, WORDS_NECESSARY(bs1->length) * sizeof(size_t)) == 0);
03355 }
03356
03357 XanBitSet * XanBitSet_Clone(XanBitSet *src) {
03358 XanBitSet *dest;
03359 dest = XanBitSet_Alloc(src->length);
03360 memcpy(dest->data, src->data, WORDS_NECESSARY(src->length) * sizeof(size_t));
03361 return dest;
03362 }
03363
03364 void XanBitSet_Copy(XanBitSet *dest, XanBitSet *src) {
03365
03366 memcpy(dest->data, src->data, WORDS_NECESSARY(src->length) * sizeof(size_t));
03367 }
03368
03369 void XanBitSet_Print(XanBitSet *set, int cr) {
03370 size_t i;
03371 for(i=0; i < set->length; i++){
03372 fprintf(stdout, "%d", ((WORD_NUMBER(set, i) & MASK(i))!=0));
03373 }
03374 if(cr) fprintf(stdout, "\n");
03375 }
03376
03377 void XanBitSet_ClearAll(XanBitSet *set) {
03378
03379 memset(set->data, 0, WORDS_NECESSARY(set->length) * sizeof(*set->data));
03380 }
03381
03382 void XanBitSet_SetAll(XanBitSet *set) {
03383
03384 memset(set->data, 0xFF, WORDS_NECESSARY(set->length) * sizeof(*set->data));
03385 }
03386
03387 void XanBitSet_Subtract(XanBitSet *fromThis, XanBitSet *subtractThis) {
03388 int words, i;
03389 unsigned int bitmask;
03390
03391 if(fromThis->length != subtractThis->length) {
03392 fprintf(stderr, "ERROR: unable to subtract two XanBitSets of different size");
03393 abort();
03394 }
03395
03396 words=WORDS_NECESSARY(fromThis->length);
03397 for(i=0; i<words; i++) {
03398 bitmask = ~(subtractThis->data[i]);
03399 fromThis->data[i] = fromThis->data[i] & bitmask;
03400 }
03401 }
03402
03403 void XanBitSet_Free(XanBitSet *set) {
03404 free(set->data);
03405 free(set);
03406 }
03407
03408 void XanBitSet_ClearBit(XanBitSet *set, size_t pos) {
03409 assert(pos<set->length);
03410 WORD_NUMBER(set, pos) &= ~MASK(pos);
03411 }
03412
03413 void XanBitSet_SetBit(XanBitSet *set, size_t pos) {
03414 assert(pos<set->length);
03415 WORD_NUMBER(set, pos) |= MASK(pos);
03416 }
03417
03418 static inline bool is_bit_set(XanBitSet *set, size_t pos) {
03419 return (WORD_NUMBER(set, pos) & MASK(pos)) != 0;
03420 }
03421
03422 bool XanBitSet_IsBitSet(XanBitSet *set, size_t pos) {
03423 assert(pos<set->length);
03424 return is_bit_set(set, pos);
03425 }
03426
03427 bool XanBitSet_IsSubSetOf(XanBitSet *setA, XanBitSet *setB) {
03428 size_t length, i;
03429
03430 if(setA->length != setB->length) {
03431 return false;
03432 }
03433
03434 length = setA->length;
03435
03436 for(i=0; i<length; i++) {
03437 if(is_bit_set(setA, i) && !is_bit_set(setB, i)) {
03438 return false;
03439 }
03440 }
03441
03442 return true;
03443 }