diff --git a/src/core/common/linked_list.hpp b/src/core/common/linked_list.hpp index ff694821b..2f6504497 100644 --- a/src/core/common/linked_list.hpp +++ b/src/core/common/linked_list.hpp @@ -303,6 +303,72 @@ public: return error; } + /** + * This method searches within the linked list to find an entry and if found returns a pointer to previous entry. + * + * @param[in] aEntry A reference to an entry to find. + * @param[out] aPrevEntry A pointer to output previous entry on success (when @p aEntry is found is the list). + * @p aPrevEntry is set to NULL if the @p aEntry is head of the list. Otherwise it + * is updated to point to previous entry before @p aEntry in the list. + * + * @retval OT_ERROR_NONE The entry was found in the list and @p aPrevEntry was updated successfully. + * @retval OT_ERROR_NOT_FOUND The entry was not found in the list. + * + */ + otError Find(const Type &aEntry, Type *&aPrevEntry) const + { + otError error = OT_ERROR_NOT_FOUND; + + if (mHead == &aEntry) + { + aPrevEntry = NULL; + error = OT_ERROR_NONE; + } + else + { + for (Type *cur = mHead; cur->GetNext() != NULL; cur = cur->GetNext()) + { + if (cur->GetNext() == &aEntry) + { + aPrevEntry = cur; + error = OT_ERROR_NONE; + break; + } + } + } + + return error; + } + + /** + * This method returns the tail of the linked list (i.e., the last entry in the list). + * + * @returns A pointer to tail entry in the linked list or NULL if list is empty. + * + */ + const Type *GetTail(void) const + { + const Type *tail = mHead; + + if (tail != NULL) + { + while (tail->GetNext() != NULL) + { + tail = tail->GetNext(); + } + } + + return tail; + } + + /** + * This method returns the tail of the linked list (i.e., the last entry in the list). + * + * @returns A pointer to tail entry in the linked list or NULL if list is empty. + * + */ + Type *GetTail(void) { return const_cast(const_cast *>(this)->GetTail()); } + private: Type *mHead; }; diff --git a/tests/unit/test_linked_list.cpp b/tests/unit/test_linked_list.cpp index 3e9cb6458..2a13a7838 100644 --- a/tests/unit/test_linked_list.cpp +++ b/tests/unit/test_linked_list.cpp @@ -52,19 +52,29 @@ void VerifyLinkedListContent(const ot::LinkedList &aList, ...) { va_list args; Entry * argEntry; + Entry * argPrev = NULL; va_start(args, aList); for (const Entry *entry = aList.GetHead(); entry; entry = entry->GetNext()) { + Entry *prev; + argEntry = va_arg(args, Entry *); VerifyOrQuit(argEntry != NULL, "List contains more entries than expected"); VerifyOrQuit(argEntry == entry, "List does not contain the same entry"); VerifyOrQuit(aList.Contains(*argEntry), "List::Contains() failed"); + + SuccessOrQuit(aList.Find(*argEntry, prev), "List::Find() failed"); + VerifyOrQuit(prev == argPrev, "List::Find() returned prev entry is incorrect"); + + argPrev = argEntry; } argEntry = va_arg(args, Entry *); VerifyOrQuit(argEntry == NULL, "List contains less entries than expected"); + + VerifyOrQuit(aList.GetTail() == argPrev, "List::GetTail() failed"); } void TestLinkedList(void)