/** * Removes the mapping for this key from this map if it is present. * * More formally, if this map contains a mapping from a key k to a value v such that * (key==null ? k==null : memcmp( key, k, keyLength ) == 0, * that mapping is removed. * (The map can contain at most one such mapping.) * * Returns the previous value associated with key, * NULL if there was no mapping for key * or (void*)-1 in case of an error. * * Note: If a valid pointer to a value is returned, the value returned is * malloced on the heap. It is the caller's responsibility to free that memory * once it is no longer needed. * * For hash maps this method has a time complexity of O(1). * For tree maps this method has a time complexity of O(Log N). * * @return void * retptr != (void*)-1: The previously associated value. * @return void * retptr == (void*)-1: An error, see pbl_errno: * * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory. */ void * pblMapRemove( /* */ PblMap * map, /** The map to remove from */ void * key, /** Key whose association is removed */ size_t keyLength, /** Length of the key */ size_t * valueLengthPtr /** Out: Length of the value returned */ ) { PblMapEntry * mapEntry; void * retptr = NULL; PblMapKey mapKey; mapKey.tag = PBL_MAP_KEY_TAG; mapKey.keyLength = keyLength; mapKey.key = key; mapEntry = (PblMapEntry *)pblSetGetElement( map->entrySet, &mapKey ); if( !mapEntry ) { if( valueLengthPtr ) { *valueLengthPtr = 0; } return NULL; } if( mapEntry->valueLength > 0 ) { retptr = pbl_memdup( "pblMapRemove", mapEntry->buffer + mapEntry->keyLength, mapEntry->valueLength ); } else { retptr = pbl_malloc0( "pblMapRemove0", 1 ); } if( !retptr ) { if( valueLengthPtr ) { *valueLengthPtr = 0; } return (void*)-1; } if( valueLengthPtr ) { *valueLengthPtr = mapEntry->valueLength; } pblSetRemoveElement( map->entrySet, mapEntry ); PBL_FREE( mapEntry ); return retptr; }
/** * Removes from the underlying list or tree set the last element returned by the iterator. * * This method can be called only once per call to next or previous. * It can be made only if pblIteratorAdd() has not been called after the last call to next or previous. * * For array lists this method has a time complexity of O(N), * with N being the number of elements in the underlying list. * * For linked lists and hash sets this method has a time complexity of O(1). * * For tree sets this method has a time complexity of O(Log N), * with N being the number of elements in the underlying collection. * * @return int rc >= 0: The size of the collection. * @return int rc < 0: An error, see pbl_errno: * * <BR>PBL_ERROR_NOT_ALLOWED - The the next or previous method has not yet been called, * or the remove method has already been called after the last call to the next or previous method. * * <BR>PBL_ERROR_CONCURRENT_MODIFICATION - The underlying list or tree set was modified concurrently. * <BR>PBL_ERROR_PARAM_LIST - The underlying collection is neither a list nor a tree set. */ int pblIteratorRemove( PblIterator * iterator /** The iterator to remove the next element from */ ) { if( iterator->changeCounter != iterator->collection->changeCounter ) { pbl_errno = PBL_ERROR_CONCURRENT_MODIFICATION; return -1; } if( PBL_SET_IS_TREE_SET( iterator->collection ) ) { PblTreeIterator * treeIterator = (PblTreeIterator *)iterator; if( !treeIterator->current ) { pbl_errno = PBL_ERROR_NOT_ALLOWED; return -1; } else { if( treeIterator->next == treeIterator->current ) { treeIterator->next = pblTreeNodeNext( treeIterator->next ); } else if( treeIterator->prev == treeIterator->current ) { treeIterator->prev = pblTreeNodePrevious( treeIterator->prev ); } pblSetRemoveElement( (PblSet*)treeIterator->collection, treeIterator->current->element ); } } else if( PBL_LIST_IS_LINKED_LIST( iterator->collection ) ) { if( !iterator->current ) { pbl_errno = PBL_ERROR_NOT_ALLOWED; return -1; } else { PblLinkedList * linkedList = (PblLinkedList *)iterator->collection; PblLinkedNode * nodeToFree = iterator->current; if( iterator->next == iterator->current ) { iterator->next = iterator->next->next; } else if( iterator->prev == iterator->current ) { iterator->prev = iterator->prev->prev; } PBL_LIST_UNLINK( linkedList->head, linkedList->tail, nodeToFree, next, prev ); linkedList->genericList.size--; linkedList->genericList.changeCounter++; PBL_FREE( nodeToFree ); } } else if( PBL_LIST_IS_ARRAY_LIST( iterator->collection ) ) { if( iterator->lastIndexReturned < 0 ) { pbl_errno = PBL_ERROR_NOT_ALLOWED; return -1; } if( pblArrayListRemoveAt( (PblArrayList*)iterator->collection, iterator->lastIndexReturned ) == (void*)-1 ) { return -1; } } else { pbl_errno = PBL_ERROR_PARAM_LIST; return -1; } if( iterator->lastIndexReturned < iterator->index ) { iterator->index--; } iterator->current = NULL; iterator->lastIndexReturned = -1; iterator->changeCounter = iterator->collection->changeCounter; return iterator->collection->size; }