Ap4List.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:12k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /*****************************************************************
  2. |
  3. |    AP4 - Lists
  4. |
  5. |    Copyright 2002 Gilles Boccon-Gibod
  6. |
  7. |
  8. |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
  9. |
  10. |    Unless you have obtained Bento4 under a difference license,
  11. |    this version of Bento4 is Bento4|GPL.
  12. |    Bento4|GPL is free software; you can redistribute it and/or modify
  13. |    it under the terms of the GNU General Public License as published by
  14. |    the Free Software Foundation; either version 2, or (at your option)
  15. |    any later version.
  16. |
  17. |    Bento4|GPL is distributed in the hope that it will be useful,
  18. |    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. |    GNU General Public License for more details.
  21. |
  22. |    You should have received a copy of the GNU General Public License
  23. |    along with Bento4|GPL; see the file COPYING.  If not, write to the
  24. |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  25. |    02111-1307, USA.
  26. |
  27.  ****************************************************************/
  28. #ifndef _AP4_LIST_H_
  29. #define _AP4_LIST_H_
  30. /*----------------------------------------------------------------------
  31. |       includes
  32. +---------------------------------------------------------------------*/
  33. #include "Ap4.h"
  34. #include "Ap4Results.h"
  35. /*----------------------------------------------------------------------
  36. |       forward references
  37. +---------------------------------------------------------------------*/
  38. template <typename T> class AP4_List;
  39. /*----------------------------------------------------------------------
  40. |       AP4_List
  41. +---------------------------------------------------------------------*/
  42. template <typename T> 
  43. class AP4_List 
  44. {
  45. public:
  46.     // types
  47.     class Item 
  48.     {
  49.     public:
  50.         // types
  51.         class Operator 
  52.         {
  53.         public:
  54.             // methods
  55.             virtual ~Operator() {}
  56.             virtual AP4_Result Action(T* data) const = 0;
  57.         };
  58.         class Finder 
  59.         {
  60.         public:
  61.             // methods
  62.             virtual ~Finder() {}
  63.             virtual AP4_Result Test(T* data) const = 0;
  64.         };
  65.         // methods
  66.         Item(T* data) : m_Data(data), m_Next(0), m_Prev(0) {}
  67.        ~Item() {}
  68.         Item* GetNext() { return m_Next; }
  69.         Item* GetPrev() { return m_Prev; }
  70.         T*    GetData() { return m_Data; }
  71.     private:
  72.         // members
  73.         T*    m_Data;
  74.         Item* m_Next;
  75.         Item* m_Prev;
  76.         // friends
  77.         friend class AP4_List;
  78.     };
  79.     // methods
  80.                  AP4_List<T>(): m_ItemCount(0), m_Head(0), m_Tail(0) {}
  81.     virtual     ~AP4_List<T>();
  82.     AP4_Result   Add(T* data);
  83.     AP4_Result   Add(Item* item);
  84.     AP4_Result   Remove(T* data);
  85.     AP4_Result   Insert(Item* where, T* data);
  86.     AP4_Result   Get(AP4_Ordinal idx, T*& data);
  87.     AP4_Result   PopHead(T*& data);
  88.     AP4_Result   Apply(const typename Item::Operator& op);
  89.     AP4_Result   ApplyUntilFailure(const typename Item::Operator& op);
  90.     AP4_Result   ApplyUntilSuccess(const typename Item::Operator& op);
  91.     AP4_Result   ReverseApply(const typename Item::Operator& op);
  92.     AP4_Result   Find(const typename Item::Finder& finder, T*& data);
  93.     AP4_Result   ReverseFind(const typename Item::Finder& finder, T*& data);
  94.     AP4_Result   DeleteReferences();
  95.     AP4_Cardinal ItemCount() { return m_ItemCount; }
  96.     Item*        FirstItem() { return m_Head; }
  97.     Item*        LastItem()  { return m_Tail; }
  98.  
  99. protected:
  100.     // members
  101.     AP4_Cardinal m_ItemCount;
  102.     Item*        m_Head;
  103.     Item*        m_Tail;
  104.     
  105. private:
  106. // these cannot be used
  107.     AP4_List<T>(const AP4_List<T>&);
  108. AP4_List<T>& operator=(const AP4_List<T>&);
  109. };
  110. /*----------------------------------------------------------------------
  111. |       AP4_List<T>::~AP4_List<T>
  112. +---------------------------------------------------------------------*/
  113. template <typename T>
  114. AP4_List<T>::~AP4_List<T>()
  115. {
  116.     Item* item = m_Head;
  117.  
  118.     while (item) {
  119.         Item* next = item->m_Next;
  120.         delete item;
  121.         item = next;
  122.     }
  123. }
  124.  
  125. /*----------------------------------------------------------------------
  126. |       AP4_List<T>::Add
  127. +---------------------------------------------------------------------*/
  128. template <typename T>
  129. inline
  130. AP4_Result
  131. AP4_List<T>::Add(T* data)
  132. {
  133.     return Add(new Item(data));
  134. }
  135. /*----------------------------------------------------------------------
  136. |       AP4_List<T>::Add
  137. +---------------------------------------------------------------------*/
  138. template <typename T>
  139. AP4_Result
  140. AP4_List<T>::Add(Item* item)
  141. {
  142.     // add element at the tail
  143.     if (m_Tail) {
  144.         item->m_Prev = m_Tail;
  145.         item->m_Next = NULL;
  146.         m_Tail->m_Next = item;
  147.         m_Tail = item;
  148.     } else {
  149.         m_Head = item;
  150.         m_Tail = item;
  151.         item->m_Next = NULL;
  152.         item->m_Prev = NULL;
  153.     }
  154.     // one more item in the list now
  155.     m_ItemCount++;
  156.  
  157.     return AP4_SUCCESS;
  158. }
  159. /*----------------------------------------------------------------------
  160. |       AP4_List<T>::Remove
  161. +---------------------------------------------------------------------*/
  162. template <typename T>
  163. AP4_Result
  164. AP4_List<T>::Remove(T* data)
  165. {
  166.     Item* item = m_Head;
  167.     while (item) {
  168.         if (item->m_Data == data) {
  169.             // delete item
  170.             if (item->m_Prev) {
  171.                 // item is not the head
  172.                 if (item->m_Next) {
  173.                     // item is not the tail
  174.                     item->m_Next->m_Prev = item->m_Prev;
  175.                     item->m_Prev->m_Next = item->m_Next;
  176.                 } else {
  177.                     // item is the tail
  178.                     m_Tail = item->m_Prev;
  179.                     m_Tail->m_Next = NULL;
  180.                 }
  181.             } else {
  182.                 // item is the head
  183.                 m_Head = item->m_Next;
  184.                 if (m_Head) {
  185.                     // item is not the tail
  186.                     m_Head->m_Prev = NULL;
  187.                 } else {
  188.                     // item is also the tail
  189.                     m_Tail = NULL;
  190.                 }
  191.             }
  192.             // delete the item
  193.             delete item;
  194.             // one less item in the list now
  195.             m_ItemCount--;
  196.             return AP4_SUCCESS;
  197.         }
  198.         item = item->m_Next;
  199.     }
  200.  
  201.     return AP4_ERROR_NO_SUCH_ITEM;
  202. }
  203. /*----------------------------------------------------------------------
  204. |       AP4_List<T>::Insert
  205. +---------------------------------------------------------------------*/
  206. template <typename T>
  207. AP4_Result
  208. AP4_List<T>::Insert(Item* where, T* data)
  209. {
  210.     Item* item = new Item(data);
  211.     if (where == NULL) {
  212.         // insert as the head
  213.         if (m_Head) {
  214.             // replace the current head
  215.             item->m_Prev = NULL;
  216.             item->m_Next = m_Head;
  217.             m_Head->m_Prev = item;
  218.             m_Head = item;
  219.         } else {
  220.             // this item becomes the head and tail
  221.             m_Head = item;
  222.             m_Tail = item;
  223.             item->m_Next = NULL;
  224.             item->m_Prev = NULL;
  225.         }
  226.     } else {
  227.         // insert after the 'where' item
  228.         if (where == m_Tail) {
  229.             // add the item at the end
  230.             return Add(item);
  231.         } else {
  232.             // update the links
  233.             item->m_Prev = where;
  234.             item->m_Next = where->m_Next;
  235.             where->m_Next->m_Prev = item;
  236.             where->m_Next = item;
  237.         }
  238.     }
  239.     // one more item in the list now
  240.     ++m_ItemCount;
  241.     return AP4_SUCCESS;
  242. }
  243. /*----------------------------------------------------------------------
  244. |       AP4_List<T>::Get
  245. +---------------------------------------------------------------------*/
  246. template <typename T>
  247. AP4_Result
  248. AP4_List<T>::Get(AP4_Ordinal idx, T*& data)
  249. {
  250.     Item* item = m_Head;
  251.     if (idx < m_ItemCount) {
  252.         while (idx--) item = item->m_Next;
  253.         data = item->m_Data;
  254.         return AP4_SUCCESS;
  255.     } else {
  256.         data = NULL;
  257.         return AP4_ERROR_NO_SUCH_ITEM;
  258.     }
  259. }
  260. /*----------------------------------------------------------------------
  261. |       AP4_List<T>::PopHead
  262. +---------------------------------------------------------------------*/
  263. template <typename T>
  264. AP4_Result
  265. AP4_List<T>::PopHead(T*& data)
  266. {
  267.     // check that we have at least one item
  268.     if (m_Head == NULL) {
  269.         return AP4_ERROR_LIST_EMPTY;
  270.     }
  271.     // remove the item and return it
  272.     data = m_Head->m_Data;
  273.     Item* head = m_Head;
  274.     m_Head = m_Head->m_Next;
  275.     if (m_Head) {
  276.         m_Head->m_Prev = NULL;
  277.     } else {
  278.         m_Tail = NULL;
  279.     }
  280.     // delete item
  281.     delete head;
  282.     // one less item in the list now
  283.     m_ItemCount--;
  284.  
  285.     return AP4_SUCCESS;
  286. }
  287. /*----------------------------------------------------------------------
  288. |       AP4_List<T>::Apply
  289. +---------------------------------------------------------------------*/
  290. template <typename T>
  291. inline 
  292. AP4_Result
  293. AP4_List<T>::Apply(const typename Item::Operator& op)
  294. {
  295.     Item* item = m_Head;
  296.  
  297.     while (item) {
  298.         op.Action(item->m_Data);
  299.         item = item->m_Next;
  300.     }
  301.     return AP4_SUCCESS;
  302. }
  303. /*----------------------------------------------------------------------
  304. |       AP4_List<T>::ApplyUntilFailure
  305. +---------------------------------------------------------------------*/
  306. template <typename T>
  307. inline 
  308. AP4_Result
  309. AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op)
  310. {
  311.     Item* item = m_Head;
  312.  
  313.     while (item) {
  314.         AP4_Result result;
  315.         result = op.Action(item->m_Data);
  316.         if (result != AP4_SUCCESS) return result;
  317.         item = item->m_Next;
  318.     }
  319.     return AP4_SUCCESS;
  320. }
  321. /*----------------------------------------------------------------------
  322. |       AP4_List<T>::ApplyUntilSuccess
  323. +---------------------------------------------------------------------*/
  324. template <typename T>
  325. inline 
  326. AP4_Result
  327. AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op)
  328. {
  329.     Item* item = m_Head;
  330.  
  331.     while (item) {
  332.         AP4_Result result;
  333.         result = op.Action(item->m_Data);
  334.         if (result == AP4_SUCCESS) return AP4_SUCCESS;
  335.         item = item->m_Next;
  336.     }
  337.     return AP4_FAILURE;
  338. }
  339. /*----------------------------------------------------------------------
  340. |       AP4_List<T>::ReverseApply
  341. +---------------------------------------------------------------------*/
  342. template <typename T>
  343. inline 
  344. AP4_Result
  345. AP4_List<T>::ReverseApply(const typename Item::Operator& op)
  346. {
  347.     Item* item = m_Tail;
  348.  
  349.     while (item) {
  350.         if (op.Action(item->m_Data) != AP4_SUCCESS) {
  351.             return AP4_ERROR_LIST_OPERATION_ABORTED;
  352.         }
  353.         item = item->m_Prev;
  354.     }
  355.     return AP4_SUCCESS;
  356. }
  357. /*----------------------------------------------------------------------
  358. |       AP4_List<T>::Find
  359. +---------------------------------------------------------------------*/
  360. template <typename T>
  361. inline 
  362. AP4_Result
  363. AP4_List<T>::Find(const typename Item::Finder& finder, T*& data)
  364. {
  365.     Item* item = m_Head;
  366.  
  367.     while (item) {
  368.         if (finder.Test(item->m_Data) == AP4_SUCCESS) {
  369.             data = item->m_Data;
  370.             return AP4_SUCCESS;
  371.         }
  372.         item = item->m_Next;
  373.     }
  374.     data = NULL;
  375.     return AP4_ERROR_NO_SUCH_ITEM;
  376. }
  377. /*----------------------------------------------------------------------
  378. |       AP4_List<T>::ReverseFind
  379. +---------------------------------------------------------------------*/
  380. template <typename T>
  381. inline 
  382. AP4_Result
  383. AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data)
  384. {
  385.     Item* item = m_Tail;
  386.  
  387.     while (item) {
  388.         if (finder.Test(item->m_Data) == AP4_SUCCESS) {
  389.             data = item->m_Data;
  390.             return AP4_SUCCESS;
  391.         }
  392.         item = item->m_Prev;
  393.     }
  394.     data = NULL;
  395.     return AP4_ERROR_NO_SUCH_ITEM;
  396. }
  397. /*----------------------------------------------------------------------
  398. |       AP4_List<T>::DeleteReferences
  399. +---------------------------------------------------------------------*/
  400. template <typename T>
  401. inline 
  402. AP4_Result
  403. AP4_List<T>::DeleteReferences()
  404. {
  405.     Item* item = m_Head;
  406.  
  407.     while (item) {
  408.         Item* next = item->m_Next;
  409.         delete item->m_Data;
  410.         delete item;
  411.         item = next;
  412.     }
  413.     // no more items
  414.     m_Head = m_Tail = NULL;
  415.     m_ItemCount = 0;
  416.     return AP4_SUCCESS;
  417. }
  418. #endif // _AP4_LIST_H_