/** * Writes node to disk also if the node gets new * address updates the previous and next nodes * to have the right address. * */ int ListNodeWrite(DiskList* dList,ListNode* node) { BinaryStr toVal; uint8_t newPtr; toVal.data = malloc(sizeof(DiskListNode)+node->data.len); toVal.len = sizeof(DiskListNode)+node->data.len; assert(toVal.data); memcpy(toVal.data,node->nodePtr,sizeof(*node->nodePtr)); memcpy(toVal.data+sizeof(*node->nodePtr),node->data.data,node->data.len); if (!BlockMgrDataWrite(dList->handle,&toVal,&node->curPtr,&newPtr)) { BinaryStrFree(&toVal); return -1; } BinaryStrFree(&toVal); if (newPtr) { ListNode* n; // update next node and prev node if (!(n = ListLoadNode(dList,node->nodePtr->next))){ return -1; } n->nodePtr->prev = node->curPtr; ListNodeWrite(dList,n); ListNodeFree(n); if (!(n = ListLoadNode(dList,node->nodePtr->prev))){ return -1; } n->nodePtr->next = node->curPtr; ListNodeWrite(dList,n); ListNodeFree(n); } return 0; }
int ListAddAfter(DiskList* dList,ListNode *node,BinaryStr data) { ListNode* newNode = ListNodeInit(data); assert(newNode); _SO(&newNode->curPtr,0); newNode->nodePtr->prev = node->curPtr; newNode->nodePtr->next = node->nodePtr->next; if (ListNodeWrite(dList,newNode)) { ListNodeFree(newNode); return -1; } node->nodePtr->next = node->curPtr; ListNodeFree(newNode); return 0; // node->nodePtr->next = node->curPtr; }
/** * Returns the pointer to last node in the list. * In an empty list this will return header address. * */ BlockMgrDiskPtr GetLast(DiskList* dList) { ListNode* node; BlockMgrDiskPtr ptr; node = ListLoadNode(dList,dList->header->head); ptr = node->nodePtr->prev; ListNodeFree(node); return ptr; }
/** * Removes the given node from the list. */ int ListRemove(DiskList* dList,ListNode* node) { ListNode* n = ListLoadNode(dList,node->nodePtr->next); assert(n); n->nodePtr->prev = node->nodePtr->prev; if (ListNodeWrite(dList,n)) { ListNodeFree(n); return -1; } ListNodeFree(n); n = ListLoadNode(dList,node->nodePtr->prev); assert(n); n->nodePtr->next = node->nodePtr->next; if (ListNodeWrite(dList,n)) { ListNodeFree(n); return -1; } ListNodeFree(n); assert(BlockMgrDataFree(dList->handle,node->curPtr)); return 0; }
/** * List iterator. * * Goes through all nodes in the list and calls the callback * function for each node. * If the call back returns non-zero iteration stops. */ int ListForAll(DiskList* dList,ListCbFn fn,void* args) { ListNode* node; int rv=0; node = ListLoadNode(dList,GetFirst(dList)); assert(node); while (_O(&node->curPtr) != _O(&dList->header->head)) { ListNode* tmp = node; rv = fn(dList,node,args); if (rv) { break; } node = ListLoadNode(dList,node->nodePtr->next); assert(node); ListNodeFree(tmp); } return rv; }
/* Delete a ListGame; implies removint it from a list. */ static void GameListDeleteGame (ListGame *listGame) { if (listGame) { if (listGame->gameInfo.event) free(listGame->gameInfo.event); if (listGame->gameInfo.site) free(listGame->gameInfo.site); if (listGame->gameInfo.date) free(listGame->gameInfo.date); if (listGame->gameInfo.round) free(listGame->gameInfo.round); if (listGame->gameInfo.white) free(listGame->gameInfo.white); if (listGame->gameInfo.black) free(listGame->gameInfo.black); if (listGame->gameInfo.fen) free(listGame->gameInfo.fen); if (listGame->gameInfo.resultDetails) free(listGame->gameInfo.resultDetails); if (listGame->gameInfo.timeControl) free(listGame->gameInfo.timeControl); if (listGame->gameInfo.extraTags) free(listGame->gameInfo.extraTags); if (listGame->gameInfo.outOfBook) free(listGame->gameInfo.outOfBook); ListNodeFree((ListNode *) listGame); } }