00001 #include "dbLkList.h"
00002
00003
00004
00005
00006
00007
00008
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
00027
00028
00029
00030
00031 static DbLkListNode *gotoNodeAt(DbLkList*list, int position){
00032 if ( (position < 0) || (position >= list->numElements) ){
00033
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
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
00059
00060
00061
00062
00063 static int insertAfter(DbLkList*list, DbLkListNode *node, void *object){
00064
00065 DbLkListNode *aux = node->next, *newNode;
00066
00067
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
00075 newNode->nodeContent.content = object;
00076
00077
00078 list->numElements++;
00079
00080 return 1;
00081 }
00082
00083
00084
00085
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
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
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
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
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
00206 (*objectAddress) = node->nodeContent.content;
00207 return 1;
00208 }
00209
00210
00211
00212
00213
00214
00215
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
00284
00285 int listCat(DbLkList*dest, DbLkList**sourceAddress){
00286 DbLkList*source = sourceAddress[0];
00287
00288
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
00309 void listVisit(DbLkList* list){
00310 if (list->visitFunction == NULL){
00311
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
00324
00325
00326 void listPrint(DbLkList*list){
00327 if (list->printFunction == NULL){
00328
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
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