list_attribute_pointer search_item_in_list_attribute(attribute_type item, list_attribute_type *list) { list_attribute_pointer aux; /* If there is no item on the list, it returns NULL*/ if(!get_first_in_list_attribute(list, &aux)) return NULL; /* While there is an next item, keep searching */ do { if (compare_attributes(aux->item, item)) { return aux; } go_next_attribute(list, &aux); } while (!is_last_attribute(aux, list)); /* Tests if the object is the last */ if (compare_attributes(aux->item, item)) { return aux; } return NULL; }
// compare_iterators static int compare_iterators(const ShareAttrDirIterator* a, const ShareAttrDirIterator* b) { return compare_attributes(a->GetCurrentAttribute(), b->GetCurrentAttribute()); }
// compare_attributes static int compare_attributes(const void* _a, const void* _b) { return compare_attributes(*(const Attribute**)_a, *(const Attribute**)_b); }
// Update status_t ShareAttrDir::Update(const AttrDirInfo& dirInfo, DoublyLinkedList<ShareAttrDirIterator>* iterators) { if (!dirInfo.isValid) return B_BAD_VALUE; if (fRevision >= dirInfo.revision) return B_OK; // allocate an array for the old attributes int32 oldCount = fAttributes.Size(); Attribute** oldAttributes = new(std::nothrow) Attribute*[oldCount]; if (!oldAttributes) return B_NO_MEMORY; ArrayDeleter<Attribute*> _(oldAttributes); // get the new attributes Attribute** newAttributes = NULL; int32 newCount = 0; status_t error = _GetAttributes(dirInfo, newAttributes, newCount); if (error != B_OK) return error; ArrayDeleter<Attribute*> _2(newAttributes); // sort the iterators int32 iteratorCount = (iterators ? iterators->Count() : 0); if (iteratorCount > 0) { // allocate an array ShareAttrDirIterator** _iterators = new(std::nothrow) ShareAttrDirIterator*[iteratorCount]; if (!_iterators) return B_NO_MEMORY; ArrayDeleter<ShareAttrDirIterator*> _3(_iterators); // move the iterators for (int32 i = 0; i < iteratorCount; i++) { ShareAttrDirIterator* iterator = iterators->First(); _iterators[i] = iterator; iterators->Remove(iterator); } // sort them qsort(_iterators, iteratorCount, sizeof(ShareAttrDirIterator*), compare_iterators); // move them back into the list for (int32 i = 0; i < iteratorCount; i++) iterators->Insert(_iterators[i]); } // remove the old attributes for (int32 i = 0; i < oldCount; i++) { Attribute* attribute = fAttributes.GetFirst(); oldAttributes[i] = attribute; fAttributes.Remove(attribute); } // add the new attributes int32 oldIndex = 0; int32 newIndex = 0; ShareAttrDirIterator* iterator = (iterators ? iterators->First() : NULL); while (oldIndex < oldCount || newIndex < newCount) { Attribute* oldAttr = (oldCount > 0 ? oldAttributes[oldIndex] : NULL); Attribute* newAttr = (newCount > 0 ? newAttributes[newIndex] : NULL); int cmp = compare_attributes(oldAttr, newAttr); if (cmp < 0) { // oldAttr is obsolete: move all iterators pointing to it to the // next new attribute while (iterator && iterator->GetCurrentAttribute() == oldAttr) { iterator->SetCurrentAttribute(newAttr); iterator = iterators->GetNext(iterator); } oldIndex++; } else if (cmp > 0) { // newAttr is new fAttributes.Insert(newAttr); newIndex++; } else { // oldAttr == newAttr fAttributes.Insert(newAttr); oldIndex++; newIndex++; // move the attributes pointing to this attribute while (iterator && iterator->GetCurrentAttribute() == oldAttr) { iterator->SetCurrentAttribute(newAttr); iterator = iterators->GetNext(iterator); } } } // delete the old attributes for (int32 i = 0; i < oldCount; i++) Attribute::DeleteAttribute(oldAttributes[i]); fRevision = dirInfo.revision; fUpToDate = true; return B_OK; }