| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| // -*- c++ -*- |
| // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
| |
| // O S C L _ L I N K E D _ L I S T |
| |
| // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
| |
| /*! \addtogroup osclbase OSCL Base |
| * |
| * @{ |
| */ |
| |
| |
| /*! \file oscl_linked_list.h |
| \brief The file oscl_linked_list.h defines the template class Oscl_Linked_List which has a very similar API as the STL Vector class (it basically provides a subset of the STL functionality). Memory allocation is abstracted through the use of an allocator template parameter. |
| */ |
| |
| #ifndef OSCL_LINKED_LIST_H_INCLUDED |
| #define OSCL_LINKED_LIST_H_INCLUDED |
| |
| #ifndef OSCL_BASE_H_INCLUDED |
| #include "oscl_base.h" |
| #endif |
| #ifndef OSCL_DEFALLOC_H_INCLUDED |
| #include "oscl_defalloc.h" |
| #endif |
| #ifndef OSCL_OPAQUE_TYPE_H_INCLUDED |
| #include "oscl_opaque_type.h" |
| #endif |
| #ifndef OSCL_ASSERT_H_INCLUDED |
| #include "oscl_assert.h" |
| #endif |
| |
| |
| /** |
| * oscl_linked_list supports random access to elements, constant time insertion |
| * and removal of elements from the list, and linear time |
| * insertion and removal of elements at the beginning or middle of the |
| * list. The number of elements in a list can vary dynamically, and |
| * memory management is performed using new and delete operators. |
| */ |
| |
| template <class LLClass, class Alloc> class Oscl_Linked_List; |
| /** |
| * Linked List Element Class |
| */ |
| template <class LLClass> class LinkedListElement |
| { |
| |
| public: |
| LinkedListElement(LLClass in_data) |
| { |
| data = in_data; |
| next = NULL; |
| }; |
| // ~LinkedListElement() {}; |
| |
| // friend class Oscl_Linked_List<LLClass>; |
| LinkedListElement<LLClass>* next; |
| LLClass data; |
| |
| private: |
| }; |
| |
| /** |
| * Oscl Linked List Base Class. A non-templated base class is used to avoid |
| * large inline functions in the Oscl_Linked_List implementation. |
| */ |
| class Oscl_Linked_List_Base |
| { |
| protected: |
| virtual ~Oscl_Linked_List_Base() |
| {} |
| |
| OSCL_IMPORT_REF void construct(Oscl_Opaque_Type_Alloc_LL* op); |
| |
| OSCL_IMPORT_REF void destroy(); |
| |
| /** |
| * Return the first element of list in passed parameter, |
| * @param ele return the value of first element of list in this parameter |
| * @return 32-bit interger,If first element found, it returns 1 |
| * otherwise it returns 0 |
| */ |
| OSCL_IMPORT_REF int32 get_first(OsclAny* ele); |
| |
| /** |
| * Return the next element of list in passed parameter, |
| * @param ele return the value of next element of list in this parameter |
| * @return 32-bit interger ,if next element is found in list,it returns 1 |
| * otherwise it returns 0 |
| */ |
| OSCL_IMPORT_REF int32 get_next(OsclAny* ele); |
| |
| /** |
| * Debug routine: Checks the list for elements. |
| * @return 32-bit integer, if node count is equal to number of node added |
| * to the list then returns 1 otherwise returns 0. |
| */ |
| OSCL_IMPORT_REF int32 check_list(); |
| |
| /** |
| * Adds new element to the list.if list is already there then it adds element at end of list otherwise |
| * it create the list and add the element as first element of list. |
| * @param new_element the element to be add in the list. |
| * @return 32-bit integer on the success returns 1. |
| */ |
| OSCL_IMPORT_REF int32 add_element(OsclAny* new_element); |
| |
| /** |
| * Adds new element at the start of the list.if list is already |
| * exist then it adds element at start of list otherwise |
| * it create the list and add the element as first element of list. |
| * @param new_element the element to be add in the list. |
| * @return 32-bit integer on the success returns 1. |
| */ |
| OSCL_IMPORT_REF int32 add_to_front(const OsclAny* new_element); |
| |
| /** |
| * Search and returs the element in the list for passed index. |
| * @param index, element The index is the count for the node. |
| * @return 32-bit integer on success returns 1 otherwise returns 0. |
| */ |
| OSCL_IMPORT_REF int32 get_element(int32 index, OsclAny* element); |
| |
| /** |
| * Removes the element from the list. |
| * @param data_to_remove |
| * @return 32-bit integer on if element fount in the list returns 1 otherwise returns 0. |
| */ |
| OSCL_IMPORT_REF int32 remove_element(const OsclAny* data_to_remove); |
| |
| /** |
| * Returns the index for requested element. |
| * @param data the element for which index to be return. |
| * @return 32-bit integer if data is found in the list it returns index |
| * otherwise it returns -1. |
| */ |
| OSCL_IMPORT_REF int32 get_index(const OsclAny* data); |
| |
| /** |
| * Removes the element for requested index. |
| * @param index_to_remove |
| * @return on success return 1 otherwise return 0. |
| */ |
| OSCL_IMPORT_REF int32 remove_element(const int32 index_to_remove); |
| |
| /** |
| * Moves the element to end of the list |
| * @param data_to_move |
| * @return On success returns 1 otherwise returns 0. |
| */ |
| OSCL_IMPORT_REF int32 move_to_end(const OsclAny* data_to_move); |
| |
| /** |
| * Moves the element to front of the list |
| * @param data_to_move |
| * @return On success returns 1 otherwise returns 0. |
| */ |
| OSCL_IMPORT_REF int32 move_to_front(const OsclAny* data_to_move); |
| |
| OsclAny *head; |
| OsclAny *tail; |
| OsclAny *iterator; |
| int32 num_elements; |
| uint32 sizeof_T; |
| |
| private: |
| Oscl_Opaque_Type_Alloc_LL* pOpaqueType; |
| }; |
| |
| /** |
| * Oscl Linked List Class |
| */ |
| template <class LLClass, class Alloc> class Oscl_Linked_List |
| : public Oscl_Linked_List_Base |
| , public Oscl_Opaque_Type_Alloc_LL |
| { |
| |
| public: |
| /** |
| * Initialized the protected variables of list. |
| */ |
| Oscl_Linked_List(): Oscl_Linked_List_Base(), Oscl_Opaque_Type_Alloc_LL() |
| { |
| sizeof_T = sizeof(LinkedListElement<LLClass>); |
| Oscl_Linked_List_Base::construct(this); |
| } |
| |
| /** |
| * The destructor. |
| */ |
| ~Oscl_Linked_List() |
| { |
| Oscl_Linked_List_Base::destroy(); |
| } |
| |
| int32 dequeue_element(LLClass & element) |
| { |
| get_element(0, element); |
| return remove_element((int32) 0); |
| } |
| // get_first() and get_next() together provide iterator function |
| |
| /** |
| * Return the first element of list in passed parameter, |
| * @param ele return the value of first element of list in this parameter |
| * @return 32-bit interger,If first element found, it returns 1 |
| * otherwise it returns 0 |
| */ |
| int32 get_first(LLClass & ele) |
| { |
| return Oscl_Linked_List_Base::get_first(&ele); |
| } |
| |
| /** |
| * Return the next element of list in passed parameter, |
| * @param ele return the value of next element of list in this parameter |
| * @return 32-bit interger ,if next element is found in list,it returns 1 |
| * otherwise it returns 0 |
| */ |
| int32 get_next(LLClass & ele) |
| { |
| return Oscl_Linked_List_Base::get_next(&ele); |
| } |
| |
| /** |
| * Debug routine: Checks the list for elements. |
| * @return 32-bit integer, if node count is equal to number of node added |
| * to the list then returns 1 otherwise returns 0. |
| */ |
| int32 check_list() |
| { |
| return Oscl_Linked_List_Base::check_list(); |
| } |
| |
| /** |
| * Get number of elements in the list. |
| * @return 32-bit integer, number of elements in list. |
| */ |
| int32 get_num_elements() |
| { |
| return num_elements; |
| } |
| |
| /** |
| * Adds new element to the list.if list is already there then it adds element at end of list otherwise |
| * it create the list and add the element as first element of list. |
| * @param new_element the element to be add in the list. |
| * @return 32-bit integer on the success returns 1. |
| */ |
| int32 add_element(LLClass& new_element) |
| { |
| return Oscl_Linked_List_Base::add_element(&new_element); |
| } |
| |
| /** |
| * Adds new element at the start of the list.if list is already |
| * exist then it adds element at start of list otherwise |
| * it create the list and add the element as first element of list. |
| * @param new_element the element to be add in the list. |
| * @return 32-bit integer on the success returns 1. |
| */ |
| int32 add_to_front(const LLClass& new_element) |
| { |
| return Oscl_Linked_List_Base::add_to_front(&new_element); |
| } |
| |
| /** |
| * Search and returs the element in the list for passed index. |
| * @param index, element The index is the count for the node. |
| * @return 32-bit integer on success returns 1 otherwise returns 0. |
| */ |
| int32 get_element(int32 index, LLClass& element) |
| { |
| return Oscl_Linked_List_Base::get_element(index, &element); |
| } |
| |
| /** |
| * Removes the element from the list. |
| * @param data_to_remove |
| * @return 32-bit integer on if element fount in the list returns 1 otherwise returns 0. |
| */ |
| int32 remove_element(const LLClass& data_to_remove) |
| { |
| return Oscl_Linked_List_Base::remove_element(&data_to_remove); |
| } |
| |
| /** |
| * Returns the index for requested element. |
| * @param data the element for which index to be return. |
| * @return 32-bit integer if data is found in the list it returns index |
| * otherwise it returns -1. |
| */ |
| int32 get_index(const LLClass& data) |
| { |
| return Oscl_Linked_List_Base::get_index(&data); |
| } |
| |
| /** |
| * Removes the element for requested index. |
| * @param index_to_remove |
| * @return on success return 1 otherwise return 0. |
| */ |
| int32 remove_element(const int32 index_to_remove) |
| { |
| return Oscl_Linked_List_Base::remove_element(index_to_remove); |
| } |
| |
| /** |
| * Moves the element to end of the list |
| * @param data_to_move |
| * @return On success returns 1 otherwise returns 0. |
| */ |
| int32 move_to_end(const LLClass& data_to_move) |
| { |
| return Oscl_Linked_List_Base::move_to_end(&data_to_move); |
| } |
| |
| /** |
| * Moves the element to front of the list |
| * @param data_to_move |
| * @return On success returns 1 otherwise returns 0. |
| */ |
| int32 move_to_front(const LLClass& data_to_move) |
| { |
| return Oscl_Linked_List_Base::move_to_front(&data_to_move); |
| } |
| |
| |
| private: |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| void construct(OsclAny* p, const OsclAny* init_val) |
| { |
| OSCL_ASSERT(init_val); |
| OSCL_ASSERT(p); |
| new(p) LinkedListElement<LLClass>(*(LLClass*)init_val); |
| } |
| |
| //this typedef is needed to avoid compile errors ADS 1.2 compiler. |
| typedef LinkedListElement<LLClass>* p_elem_type; |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| void destroy(OsclAny* p) |
| { |
| OSCL_ASSERT(p); |
| ((p_elem_type)p)->~LinkedListElement<LLClass>(); |
| } |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| OsclAny* allocate(const uint32 size) |
| { |
| return alloc.ALLOCATE(size); |
| } |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| void deallocate(OsclAny* p) |
| { |
| alloc.deallocate(p); |
| } |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| OsclAny* get_next(const OsclAny* elem)const |
| { |
| return ((LinkedListElement<LLClass>*)elem)->next; |
| } |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| void set_next(OsclAny* elem, const OsclAny* nextelem) |
| { |
| OSCL_ASSERT(elem); |
| ((LinkedListElement<LLClass>*)elem)->next = (LinkedListElement<LLClass>*)nextelem; |
| } |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| void get_data(OsclAny*elem, OsclAny*data_val) |
| { |
| OSCL_ASSERT(elem); |
| OSCL_ASSERT(data_val); |
| *((LLClass*)data_val) = ((LinkedListElement<LLClass>*)elem)->data ; |
| } |
| |
| //from Oscl_Opaque_Type_Alloc_LL |
| bool compare_data(const OsclAny*elem, const OsclAny*data_val)const |
| { |
| OSCL_ASSERT(elem); |
| OSCL_ASSERT(data_val); |
| return ((LinkedListElement<LLClass>*)elem)->data == *((LLClass*)data_val); |
| } |
| |
| Alloc alloc; |
| |
| }; |
| |
| /** |
| * Oscl_MTLinked_List is a multi-threaded version of |
| * the LinkedList. It has mutex protection to |
| * allow access by different threads. |
| */ |
| template <class LLClass, class Alloc, class TheLock> class Oscl_MTLinked_List |
| { |
| |
| public: |
| /** |
| * Constructor for Oscl_MTLinked_List |
| */ |
| Oscl_MTLinked_List() {}; |
| |
| /** |
| * Destructor for Oscl_MTLinked_List |
| */ |
| ~Oscl_MTLinked_List() {}; |
| |
| int32 dequeue_element(LLClass & element) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.dequeue_element(element); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Adds new element to the Multi Threaded Linked list.if list |
| * is already there then it adds element at end of list otherwise |
| * it create the list and add the element as first element of list. |
| * @param new_element the element to be add in the list. |
| * @return 32-bit integer on the success returns 1. |
| */ |
| int32 add_element(LLClass& new_element) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.add_element(new_element); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Adds new element at the start of the Multi Threaded Linked list. |
| * if list is already exist then it adds element at start of list otherwise |
| * it create the list and add the element as first element of list. |
| * @param new_element the element to be add in the list. |
| * @return 32-bit integer on the success returns 1. |
| */ |
| int32 add_to_front(LLClass& new_element) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.add_to_front(new_element); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Search and returs the element in the Multi Treaded Linked List |
| * for passed index. |
| * @param index, element The index is the count for the node. |
| * @return 32-bit integer on success returns 1 otherwise returns 0. |
| */ |
| uint32 get_element(int32 index, LLClass& element) |
| { |
| |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.get_element(index, element); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Removes the element from the list. |
| * @param data_to_remove |
| * @return 32-bit integer on if element fount in the list returns 1 otherwise returns 0. |
| */ |
| int32 remove_element(const LLClass& data_to_remove) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.remove_element(data_to_remove); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Returns the index for requested element. |
| * @param data the element for which index to be return. |
| * @return 32-bit integer if data is found in the list it returns index |
| * otherwise it returns -1. |
| */ |
| int32 get_index(const LLClass& data) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.get_index(data); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Removes the element for requested index. |
| * @param index_to_remove |
| * @return on success return 1 otherwise return 0. |
| */ |
| int32 remove_element(const int32 index_to_remove) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.remove_element(index_to_remove); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Moves the element to end of the list |
| * @param data_to_move |
| * @return On success returns 1 otherwise returns 0. |
| */ |
| int32 move_to_end(const LLClass& data_to_move) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.move_to_end(data_to_move); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| /** |
| * Moves the element to front of the list |
| * @param data_to_move |
| * @return On success returns 1 otherwise returns 0. |
| */ |
| int32 move_to_front(const LLClass& data_to_move) |
| { |
| int32 status; |
| TheLock Mylock; |
| Mylock.Lock(); |
| status = the_list.move_to_front(data_to_move); |
| Mylock.Unlock(); |
| return status; |
| } |
| |
| protected: |
| Oscl_Linked_List<LLClass, Alloc> the_list; |
| // PVMutex mutex; |
| |
| }; |
| |
| |
| /*! @} */ |
| |
| |
| #endif // __LINKED_LIST_H |
| |