• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 // -*- c++ -*-
19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20 
21 //                     O S C L _ L I N K E D _ L I S T
22 
23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
24 
25 /*! \addtogroup osclbase OSCL Base
26  *
27  * @{
28  */
29 
30 
31 /*! \file oscl_linked_list.h
32     \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.
33 */
34 
35 #ifndef OSCL_LINKED_LIST_H_INCLUDED
36 #define OSCL_LINKED_LIST_H_INCLUDED
37 
38 #ifndef OSCL_BASE_H_INCLUDED
39 #include "oscl_base.h"
40 #endif
41 #ifndef OSCL_DEFALLOC_H_INCLUDED
42 #include "oscl_defalloc.h"
43 #endif
44 #ifndef OSCL_OPAQUE_TYPE_H_INCLUDED
45 #include "oscl_opaque_type.h"
46 #endif
47 #ifndef OSCL_ASSERT_H_INCLUDED
48 #include "oscl_assert.h"
49 #endif
50 
51 
52 /**
53  * oscl_linked_list supports random access to elements, constant time insertion
54  * and removal of elements from the list, and linear time
55  * insertion and removal of elements at the beginning or middle of the
56  * list.  The number of elements in a list can vary dynamically, and
57  * memory management is performed using new and delete operators.
58  */
59 
60 template <class LLClass, class Alloc> class Oscl_Linked_List;
61 /**
62  * Linked List Element Class
63  */
64 template <class LLClass> class LinkedListElement
65 {
66 
67     public:
LinkedListElement(LLClass in_data)68         LinkedListElement(LLClass in_data)
69         {
70             data = in_data;
71             next = NULL;
72         };
73         //  ~LinkedListElement() {};
74 
75 //  friend class Oscl_Linked_List<LLClass>;
76         LinkedListElement<LLClass>* next;
77         LLClass data;
78 
79     private:
80 };
81 
82 /**
83  * Oscl Linked List Base Class.  A non-templated base class is used to avoid
84  * large inline functions in the Oscl_Linked_List implementation.
85  */
86 class Oscl_Linked_List_Base
87 {
88     protected:
~Oscl_Linked_List_Base()89         virtual ~Oscl_Linked_List_Base()
90         {}
91 
92         OSCL_IMPORT_REF void construct(Oscl_Opaque_Type_Alloc_LL* op);
93 
94         OSCL_IMPORT_REF void destroy();
95 
96         /**
97          * Return the first element of list in passed parameter,
98          * @param ele return the value of first element of list in this parameter
99          * @return 32-bit interger,If first element found, it returns 1
100          * otherwise it returns 0
101          */
102         OSCL_IMPORT_REF int32 get_first(OsclAny* ele);
103 
104         /**
105          * Return the next element of list in passed parameter,
106          * @param ele return the value of next element of list in this parameter
107          * @return 32-bit interger ,if next element is found in list,it returns 1
108          * otherwise it returns 0
109          */
110         OSCL_IMPORT_REF int32 get_next(OsclAny* ele);
111 
112         /**
113          * Debug routine: Checks the list for elements.
114          * @return 32-bit integer, if node count is equal to number of node added
115          * to the list then returns 1 otherwise returns 0.
116          */
117         OSCL_IMPORT_REF int32 check_list();
118 
119         /**
120          * Adds new element to the list.if list is already there then it adds element at end of list otherwise
121          * it create the list and add the element as first element of list.
122          * @param new_element the element to be add in the list.
123          * @return 32-bit integer on the success returns 1.
124          */
125         OSCL_IMPORT_REF int32 add_element(OsclAny* new_element);
126 
127         /**
128          * Adds new element at the start of the list.if list is already
129          * exist then it adds element at start of list otherwise
130          * it create the list and add the element as first element of list.
131          * @param new_element the element to be add in the list.
132          * @return 32-bit integer on the success returns 1.
133          */
134         OSCL_IMPORT_REF int32 add_to_front(const OsclAny* new_element);
135 
136         /**
137          * Search and returs the element in the list for passed index.
138          * @param index, element The index is the count for the node.
139          * @return 32-bit integer on success returns 1 otherwise returns 0.
140          */
141         OSCL_IMPORT_REF int32 get_element(int32 index, OsclAny* element);
142 
143         /**
144          * Removes the element from the list.
145          * @param data_to_remove
146          * @return 32-bit integer on if  element fount in the list returns 1 otherwise returns 0.
147          */
148         OSCL_IMPORT_REF int32 remove_element(const OsclAny* data_to_remove);
149 
150         /**
151          * Returns the index for requested element.
152          * @param data the element for which index to be return.
153          * @return 32-bit integer if data is found in the list it returns index
154          * otherwise it returns -1.
155          */
156         OSCL_IMPORT_REF int32 get_index(const OsclAny* data);
157 
158         /**
159          * Removes the element for requested index.
160          * @param index_to_remove
161          * @return on success return 1 otherwise return 0.
162          */
163         OSCL_IMPORT_REF int32 remove_element(const int32 index_to_remove);
164 
165         /**
166          * Moves the element to end of the list
167          * @param data_to_move
168          * @return On success returns 1 otherwise returns 0.
169          */
170         OSCL_IMPORT_REF int32 move_to_end(const OsclAny* data_to_move);
171 
172         /**
173          * Moves the element to front of the list
174          * @param data_to_move
175          * @return On success returns 1 otherwise returns 0.
176          */
177         OSCL_IMPORT_REF int32 move_to_front(const OsclAny* data_to_move);
178 
179         OsclAny *head;
180         OsclAny *tail;
181         OsclAny *iterator;
182         int32 num_elements;
183         uint32 sizeof_T;
184 
185     private:
186         Oscl_Opaque_Type_Alloc_LL* pOpaqueType;
187 };
188 
189 /**
190  * Oscl Linked List Class
191  */
192 template <class LLClass, class Alloc> class Oscl_Linked_List
193         : public Oscl_Linked_List_Base
194         , public Oscl_Opaque_Type_Alloc_LL
195 {
196 
197     public:
198         /**
199          * Initialized the protected variables of list.
200          */
Oscl_Linked_List()201         Oscl_Linked_List(): Oscl_Linked_List_Base(), Oscl_Opaque_Type_Alloc_LL()
202         {
203             sizeof_T = sizeof(LinkedListElement<LLClass>);
204             Oscl_Linked_List_Base::construct(this);
205         }
206 
207         /**
208          * The destructor.
209          */
~Oscl_Linked_List()210         ~Oscl_Linked_List()
211         {
212             Oscl_Linked_List_Base::destroy();
213         }
214 
dequeue_element(LLClass & element)215         int32 dequeue_element(LLClass & element)
216         {
217             get_element(0, element);
218             return remove_element((int32) 0);
219         }
220         // get_first() and get_next() together provide iterator function
221 
222         /**
223          * Return the first element of list in passed parameter,
224          * @param ele return the value of first element of list in this parameter
225          * @return 32-bit interger,If first element found, it returns 1
226          * otherwise it returns 0
227          */
get_first(LLClass & ele)228         int32 get_first(LLClass & ele)
229         {
230             return Oscl_Linked_List_Base::get_first(&ele);
231         }
232 
233         /**
234          * Return the next element of list in passed parameter,
235          * @param ele return the value of next element of list in this parameter
236          * @return 32-bit interger ,if next element is found in list,it returns 1
237          * otherwise it returns 0
238          */
get_next(LLClass & ele)239         int32 get_next(LLClass & ele)
240         {
241             return Oscl_Linked_List_Base::get_next(&ele);
242         }
243 
244         /**
245          * Debug routine: Checks the list for elements.
246          * @return 32-bit integer, if node count is equal to number of node added
247          * to the list then returns 1 otherwise returns 0.
248          */
check_list()249         int32 check_list()
250         {
251             return Oscl_Linked_List_Base::check_list();
252         }
253 
254         /**
255          * Get number of elements in the list.
256          * @return 32-bit integer, number of elements in list.
257          */
get_num_elements()258         int32 get_num_elements()
259         {
260             return num_elements;
261         }
262 
263         /**
264          * Adds new element to the list.if list is already there then it adds element at end of list otherwise
265          * it create the list and add the element as first element of list.
266          * @param new_element the element to be add in the list.
267          * @return 32-bit integer on the success returns 1.
268          */
add_element(LLClass & new_element)269         int32 add_element(LLClass& new_element)
270         {
271             return Oscl_Linked_List_Base::add_element(&new_element);
272         }
273 
274         /**
275          * Adds new element at the start of the list.if list is already
276          * exist then it adds element at start of list otherwise
277          * it create the list and add the element as first element of list.
278          * @param new_element the element to be add in the list.
279          * @return 32-bit integer on the success returns 1.
280          */
add_to_front(const LLClass & new_element)281         int32 add_to_front(const LLClass& new_element)
282         {
283             return Oscl_Linked_List_Base::add_to_front(&new_element);
284         }
285 
286         /**
287          * Search and returs the element in the list for passed index.
288          * @param index, element The index is the count for the node.
289          * @return 32-bit integer on success returns 1 otherwise returns 0.
290          */
get_element(int32 index,LLClass & element)291         int32 get_element(int32 index, LLClass& element)
292         {
293             return Oscl_Linked_List_Base::get_element(index, &element);
294         }
295 
296         /**
297          * Removes the element from the list.
298          * @param data_to_remove
299          * @return 32-bit integer on if  element fount in the list returns 1 otherwise returns 0.
300          */
remove_element(const LLClass & data_to_remove)301         int32 remove_element(const LLClass& data_to_remove)
302         {
303             return Oscl_Linked_List_Base::remove_element(&data_to_remove);
304         }
305 
306         /**
307          * Returns the index for requested element.
308          * @param data the element for which index to be return.
309          * @return 32-bit integer if data is found in the list it returns index
310          * otherwise it returns -1.
311          */
get_index(const LLClass & data)312         int32 get_index(const LLClass& data)
313         {
314             return Oscl_Linked_List_Base::get_index(&data);
315         }
316 
317         /**
318          * Removes the element for requested index.
319          * @param index_to_remove
320          * @return on success return 1 otherwise return 0.
321          */
remove_element(const int32 index_to_remove)322         int32 remove_element(const int32 index_to_remove)
323         {
324             return Oscl_Linked_List_Base::remove_element(index_to_remove);
325         }
326 
327         /**
328          * Moves the element to end of the list
329          * @param data_to_move
330          * @return On success returns 1 otherwise returns 0.
331          */
move_to_end(const LLClass & data_to_move)332         int32 move_to_end(const LLClass& data_to_move)
333         {
334             return Oscl_Linked_List_Base::move_to_end(&data_to_move);
335         }
336 
337         /**
338          * Moves the element to front of the list
339          * @param data_to_move
340          * @return On success returns 1 otherwise returns 0.
341          */
move_to_front(const LLClass & data_to_move)342         int32 move_to_front(const LLClass& data_to_move)
343         {
344             return Oscl_Linked_List_Base::move_to_front(&data_to_move);
345         }
346 
347 
348     private:
349 
350         //from Oscl_Opaque_Type_Alloc_LL
construct(OsclAny * p,const OsclAny * init_val)351         void construct(OsclAny* p, const OsclAny* init_val)
352         {
353             OSCL_ASSERT(init_val);
354             OSCL_ASSERT(p);
355             new(p) LinkedListElement<LLClass>(*(LLClass*)init_val);
356         }
357 
358         //this typedef is needed to avoid compile errors ADS 1.2 compiler.
359         typedef LinkedListElement<LLClass>* p_elem_type;
360 
361         //from Oscl_Opaque_Type_Alloc_LL
destroy(OsclAny * p)362         void destroy(OsclAny* p)
363         {
364             OSCL_ASSERT(p);
365             ((p_elem_type)p)->~LinkedListElement<LLClass>();
366         }
367 
368         //from Oscl_Opaque_Type_Alloc_LL
allocate(const uint32 size)369         OsclAny* allocate(const uint32 size)
370         {
371             return alloc.ALLOCATE(size);
372         }
373 
374         //from Oscl_Opaque_Type_Alloc_LL
deallocate(OsclAny * p)375         void deallocate(OsclAny* p)
376         {
377             alloc.deallocate(p);
378         }
379 
380         //from Oscl_Opaque_Type_Alloc_LL
get_next(const OsclAny * elem)381         OsclAny* get_next(const OsclAny* elem)const
382         {
383             return ((LinkedListElement<LLClass>*)elem)->next;
384         }
385 
386         //from Oscl_Opaque_Type_Alloc_LL
set_next(OsclAny * elem,const OsclAny * nextelem)387         void set_next(OsclAny* elem, const OsclAny* nextelem)
388         {
389             OSCL_ASSERT(elem);
390             ((LinkedListElement<LLClass>*)elem)->next = (LinkedListElement<LLClass>*)nextelem;
391         }
392 
393         //from Oscl_Opaque_Type_Alloc_LL
get_data(OsclAny * elem,OsclAny * data_val)394         void get_data(OsclAny*elem, OsclAny*data_val)
395         {
396             OSCL_ASSERT(elem);
397             OSCL_ASSERT(data_val);
398             *((LLClass*)data_val) = ((LinkedListElement<LLClass>*)elem)->data ;
399         }
400 
401         //from Oscl_Opaque_Type_Alloc_LL
compare_data(const OsclAny * elem,const OsclAny * data_val)402         bool compare_data(const OsclAny*elem, const OsclAny*data_val)const
403         {
404             OSCL_ASSERT(elem);
405             OSCL_ASSERT(data_val);
406             return ((LinkedListElement<LLClass>*)elem)->data == *((LLClass*)data_val);
407         }
408 
409         Alloc alloc;
410 
411 };
412 
413 /**
414  * Oscl_MTLinked_List is a multi-threaded version of
415  * the LinkedList.  It has mutex protection to
416  * allow access by different threads.
417  */
418 template <class LLClass, class Alloc, class TheLock> class Oscl_MTLinked_List
419 {
420 
421     public:
422         /**
423          * Constructor for Oscl_MTLinked_List
424          */
Oscl_MTLinked_List()425         Oscl_MTLinked_List() {};
426 
427         /**
428          * Destructor for Oscl_MTLinked_List
429          */
~Oscl_MTLinked_List()430         ~Oscl_MTLinked_List() {};
431 
dequeue_element(LLClass & element)432         int32 dequeue_element(LLClass & element)
433         {
434             int32 status;
435             TheLock Mylock;
436             Mylock.Lock();
437             status = the_list.dequeue_element(element);
438             Mylock.Unlock();
439             return status;
440         }
441 
442         /**
443          * Adds new element to the Multi Threaded Linked list.if list
444          * is already there then it adds element at end of list otherwise
445          * it create the list and add the element as first element of list.
446          * @param new_element the element to be add in the list.
447          * @return 32-bit integer on the success returns 1.
448          */
add_element(LLClass & new_element)449         int32 add_element(LLClass& new_element)
450         {
451             int32 status;
452             TheLock Mylock;
453             Mylock.Lock();
454             status = the_list.add_element(new_element);
455             Mylock.Unlock();
456             return status;
457         }
458 
459         /**
460          * Adds new element at the start of the Multi Threaded Linked list.
461          * if list is already exist then it adds element at start of list otherwise
462          * it create the list and add the element as first element of list.
463          * @param new_element the element to be add in the list.
464          * @return 32-bit integer on the success returns 1.
465          */
add_to_front(LLClass & new_element)466         int32 add_to_front(LLClass& new_element)
467         {
468             int32 status;
469             TheLock Mylock;
470             Mylock.Lock();
471             status = the_list.add_to_front(new_element);
472             Mylock.Unlock();
473             return status;
474         }
475 
476         /**
477          * Search and returs the element in the Multi Treaded Linked List
478          * for passed index.
479          * @param index, element The index is the count for the node.
480          * @return 32-bit integer on success returns 1 otherwise returns 0.
481          */
get_element(int32 index,LLClass & element)482         uint32 get_element(int32 index, LLClass& element)
483         {
484 
485             int32 status;
486             TheLock Mylock;
487             Mylock.Lock();
488             status = the_list.get_element(index, element);
489             Mylock.Unlock();
490             return status;
491         }
492 
493         /**
494          * Removes the element from the list.
495          * @param data_to_remove
496          * @return 32-bit integer on if  element fount in the list returns 1 otherwise returns 0.
497          */
remove_element(const LLClass & data_to_remove)498         int32 remove_element(const LLClass& data_to_remove)
499         {
500             int32 status;
501             TheLock Mylock;
502             Mylock.Lock();
503             status = the_list.remove_element(data_to_remove);
504             Mylock.Unlock();
505             return status;
506         }
507 
508         /**
509          * Returns the index for requested element.
510          * @param data the element for which index to be return.
511          * @return 32-bit integer if data is found in the list it returns index
512          * otherwise it returns -1.
513          */
get_index(const LLClass & data)514         int32 get_index(const LLClass& data)
515         {
516             int32 status;
517             TheLock Mylock;
518             Mylock.Lock();
519             status = the_list.get_index(data);
520             Mylock.Unlock();
521             return status;
522         }
523 
524         /**
525          * Removes the element for requested index.
526          * @param index_to_remove
527          * @return on success return 1 otherwise return 0.
528          */
remove_element(const int32 index_to_remove)529         int32 remove_element(const int32 index_to_remove)
530         {
531             int32 status;
532             TheLock Mylock;
533             Mylock.Lock();
534             status = the_list.remove_element(index_to_remove);
535             Mylock.Unlock();
536             return status;
537         }
538 
539         /**
540          * Moves the element to end of the list
541          * @param data_to_move
542          * @return On success returns 1 otherwise returns 0.
543          */
move_to_end(const LLClass & data_to_move)544         int32 move_to_end(const LLClass& data_to_move)
545         {
546             int32 status;
547             TheLock Mylock;
548             Mylock.Lock();
549             status = the_list.move_to_end(data_to_move);
550             Mylock.Unlock();
551             return status;
552         }
553 
554         /**
555          * Moves the element to front of the list
556          * @param data_to_move
557          * @return On success returns 1 otherwise returns 0.
558          */
move_to_front(const LLClass & data_to_move)559         int32 move_to_front(const LLClass& data_to_move)
560         {
561             int32 status;
562             TheLock Mylock;
563             Mylock.Lock();
564             status = the_list.move_to_front(data_to_move);
565             Mylock.Unlock();
566             return status;
567         }
568 
569     protected:
570         Oscl_Linked_List<LLClass, Alloc> the_list;
571 //    PVMutex mutex;
572 
573 };
574 
575 
576 /*! @} */
577 
578 
579 #endif  // __LINKED_LIST_H
580 
581