dbLkList.c

Go to the documentation of this file.
00001 #include "dbLkList.h"
00002 
00003 /** static functions, used only in this file */
00004 
00005 /** Returns the node which holds the object passed as argument.
00006  * @param lsit the list being searched
00007  * @param object we are looking for the node holding this
00008  * @return the node holding the object, NULL otherwise
00009  */
00010 static DbLkListNode *gotoNodeWith(DbLkList*list, void *object){
00011         DbLkListNode *node = list->head.next;
00012         int i;
00013 
00014         for (i=0;i<list->numElements;i++){
00015                 if (node->nodeContent.content == object){
00016                         return node;    
00017                 }
00018                 node= node->next;
00019         }
00020 
00021         return NULL;
00022 
00023 }
00024 
00025 
00026 /** Returns a pointer to the node at the given position 
00027  * @param list the list
00028  * @param position the position we are looking for
00029  * @return the node at the given position, NULL otherwise
00030  */
00031 static DbLkListNode *gotoNodeAt(DbLkList*list, int position){
00032         if ( (position < 0) || (position >= list->numElements) ){
00033                 //invalid position
00034                 return NULL;
00035         }
00036 
00037         int middle = list->numElements / 2;
00038         if (position <= middle){
00039                 DbLkListNode *node = list->head.next;
00040                 int i;
00041                 //get the right spot to insert
00042                 for (i=0;i<position;i++){
00043                         node = node->next;
00044                 }
00045                 return node;
00046         }
00047         else {
00048                 DbLkListNode *node = list->tail.previous;
00049                 int i;
00050                 for (i=(list->numElements-1);i>position;i--){
00051                         node = node->previous;
00052                 }
00053                 return node;
00054         }
00055 }
00056 
00057 /**
00058  * Inserts an object after the given node, used internally
00059  * @param node we insert the object in a new node after this
00060  * @param object the object being inserted
00061  * @return 1 on success, -1 otherwise
00062  */
00063 static int insertAfter(DbLkList*list, DbLkListNode *node, void *object){
00064         //now we have the right node
00065         DbLkListNode *aux = node->next, *newNode;
00066 
00067         //pointer adjust
00068         node->next = (DbLkListNode*)malloc(sizeof(DbLkListNode));
00069         newNode = node->next;
00070         newNode->previous = node;
00071         newNode->next = aux;
00072         aux->previous = newNode;
00073         
00074         //place the object
00075         newNode->nodeContent.content = object;
00076 
00077         //finally...
00078         list->numElements++;
00079 
00080         return 1;
00081 }
00082 
00083 // end static functions ----------------------------------
00084 
00085 /** constructor and destructor */
00086 
00087 DbLkList* listCreate(){
00088         DbLkList*list = (DbLkList*)malloc(sizeof(DbLkList));
00089         list->numElements = 0;
00090         list->head.previous = NULL;
00091         list->head.next = &list->tail;
00092         list->tail.previous = &list->head;
00093         list->tail.next = NULL;
00094 
00095         list->deleteFunction = NULL;
00096         list->printFunction = NULL;
00097         list->visitFunction = NULL;
00098         
00099         list->lastVisited = NULL;
00100         
00101         return list;
00102 }
00103 
00104 void listDestroy(DbLkList**listPointerAddress, DbLkDestroyMode mode){
00105         DbLkList*list = listPointerAddress[0];  
00106         while (list->numElements != 0){
00107                 void *object;
00108 
00109                 listRemoveObjectAt(list, 0, &object);   
00110                 if (mode == DBLIST_DM_FREE){
00111                         if (list->deleteFunction != NULL){
00112                                 list->deleteFunction(list, object);
00113                         }
00114                         else {
00115                                 if (object != NULL){
00116                                         free(object);
00117                                 }
00118                         }
00119                 }
00120         }
00121 
00122         free(list);
00123         listPointerAddress[0] = NULL;
00124 }
00125 
00126 
00127 /** iteration functions */
00128 
00129 int listPrepare(DbLkList *list, DbLkTransMode from){
00130         if (list->numElements <= 0){
00131                 return -1;
00132         }
00133 
00134         list->lastVisited = (from == DBLIST_TM_FROM_HEAD)? &list->head : &list->tail;
00135         return 1;
00136 }
00137 
00138 int listGetNext(DbLkList *list, void **object){
00139         list->lastVisited = ((list->lastVisited == NULL) ||  (list->lastVisited->next == &list->tail) ) ? 
00140                         NULL : list->lastVisited->next;
00141         if (list->lastVisited == NULL){
00142                 return -1;
00143         }
00144         object[0] = list->lastVisited->nodeContent.content;
00145         
00146         return 1;
00147 }
00148 
00149 int listGetPrevious(DbLkList *list, void **object){
00150         list->lastVisited = ((list->lastVisited == NULL) || (list->lastVisited->previous == &list->head)) ? 
00151                         NULL : list->lastVisited->previous;
00152         if (list->lastVisited == NULL){
00153                 return -1;
00154         }
00155 
00156         object[0] = list->lastVisited->nodeContent.content;
00157         
00158         return 1;
00159 
00160 }
00161 
00162 
00163 /** 
00164  * Insertion functions
00165  */
00166 
00167 
00168 int listInsertHead(DbLkList*list, void *object){        
00169         DbLkListNode *node = &list->head;
00170         return insertAfter(list, node, object);
00171 }
00172 int listInsertTail(DbLkList*list, void *object){
00173         DbLkListNode *node = &list->tail;
00174         return insertAfter(list, node->previous, object);
00175 }
00176 
00177 int listInsertAt(DbLkList*list, int position, void *object){
00178         if ((position < 0) || (position > list->numElements)){
00179                 //invalid position
00180                 return -1;
00181         }
00182         else if (position == 0){
00183                 return listInsertHead(list, object);
00184         }
00185         else if (position == list->numElements){
00186                 return listInsertTail(list, object);
00187         }
00188         else {
00189                 DbLkListNode *node = gotoNodeAt(list, position);
00190                 if (node == NULL){
00191                         return -1;
00192                 }
00193                 node = node->previous;
00194                 return insertAfter(list, node, object);
00195         }
00196 }
00197 
00198 /** Retrieving functions */
00199 
00200 int listGetObjectAt(DbLkList*list, int position, void **objectAddress){
00201         DbLkListNode *node = gotoNodeAt(list, position);
00202         if (node == NULL){
00203                 return -1;
00204         }
00205         //we got the node, return the values
00206         (*objectAddress) = node->nodeContent.content;
00207         return 1;
00208 }
00209 
00210 
00211 /** Remove functions */
00212 
00213 /** Removes a node from the list, does not check if its valid or not, so careful here
00214  * @param list the list
00215  * @param node the node being removed
00216  */
00217 static void removeNode(DbLkList*list, DbLkListNode *node){
00218         node->next->previous = node->previous;
00219         node->previous->next = node->next;
00220         free(node);
00221         list->numElements--;
00222 }
00223 
00224 int listRemoveObjectAt(DbLkList*list, int position, void **objectAddress){
00225         DbLkListNode *node = gotoNodeAt(list, position);
00226         if (node == NULL){
00227                 return -1;
00228         }
00229 
00230         if (objectAddress != NULL){
00231                 objectAddress[0] = node->nodeContent.content;
00232         }
00233         removeNode(list, node); 
00234         return 1;
00235 }
00236 
00237 int listRemoveObject(DbLkList*list, void *object){
00238         DbLkListNode *node = gotoNodeWith(list, object);
00239         if (node == NULL){
00240                 return -1;
00241         }
00242         removeNode(list, node);
00243         return 1;
00244 }
00245 
00246 int listRemoveHead(DbLkList *list, void **objectAddress){
00247         if (list->numElements == 0){
00248                 return -1;
00249         }
00250         objectAddress[0] = list->head.next->nodeContent.content;
00251         removeNode(list, list->head.next);
00252         return 1;
00253 }
00254 
00255 int listRemoveTail(DbLkList *list, void **objectAddress){
00256         if (list->numElements == 0){
00257                 return -1;
00258         }
00259         objectAddress[0] = list->tail.previous->nodeContent.content;
00260         removeNode(list, list->tail.previous);
00261         return 1;
00262 }
00263 
00264 int listGetTail(DbLkList *list, void **objectAddress){
00265         if (list->numElements == 0){
00266                 return -1;
00267         }
00268         objectAddress[0] = list->tail.previous->nodeContent.content;
00269         return 1;
00270 }
00271 
00272 int listGetHead(DbLkList *list, void **objectAddress){
00273         if (list->numElements == 0){
00274                 return -1;
00275         }
00276         objectAddress[0] = list->head.next->nodeContent.content;
00277         return 1;
00278 }
00279 
00280 
00281 
00282 
00283 /** Concatenate functions */
00284 
00285 int listCat(DbLkList*dest, DbLkList**sourceAddress){
00286         DbLkList*source = sourceAddress[0];
00287 
00288         //if dest has 0 elements it works... if source has 0, the if catches it.
00289         if (source->numElements != 0){
00290                 DbLkListNode *lastDest = dest->tail.previous;
00291                 DbLkListNode *firstSource = source->head.next;
00292                 DbLkListNode *lastSource = source->tail.previous;
00293 
00294                 lastDest->next = firstSource;
00295                 firstSource->previous = lastDest;
00296                 lastSource->next = &dest->tail;
00297                 dest->tail.previous = lastSource;
00298 
00299                 dest->numElements += source->numElements;
00300         }
00301         free(source);
00302         sourceAddress[0] = NULL;
00303 
00304         return dest->numElements;
00305 }
00306 
00307 
00308 /** visit function */
00309 void listVisit(DbLkList* list){
00310         if (list->visitFunction == NULL){
00311                 //return if no registered visit function
00312                 return;
00313         }
00314         int i;
00315         DbLkListNode *node = list->head.next;
00316         for (i=0;i<list->numElements;i++){
00317                 list->visitFunction(list, node->nodeContent.content);
00318                 node = node->next;
00319         }
00320 
00321 }
00322 
00323 /** Print functions */
00324 
00325 
00326 void listPrint(DbLkList*list){
00327         if (list->printFunction == NULL){
00328                 //we cant print if we dont have a print function        
00329                 return;
00330         }
00331         int i;
00332         DbLkListNode *node = list->head.next;
00333         for (i=0;i<list->numElements;i++){
00334                 list->printFunction(list, node->nodeContent.content);
00335                 node = node->next;
00336         }
00337 }
00338 
00339 /** Register functions */
00340 
00341 void listRegisterPrintFunction(DbLkList*list, ListPrintFunction *printFunction){
00342         list->printFunction = printFunction;
00343 }
00344 
00345 void listRegisterDeleteFunction(DbLkList*list, ListDeleteFunction *deleteFunction){
00346         list->deleteFunction = deleteFunction;
00347 }
00348 
00349 void listRegisterVisitFunction(DbLkList *list, ListVisitFunction *visitFunction){
00350         list->visitFunction = visitFunction;
00351 }
00352 

Generated on Tue Jan 17 19:18:38 2006 for Void by  doxygen 1.4.6