Ap4List.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:12k
- /*****************************************************************
- |
- | AP4 - Lists
- |
- | Copyright 2002 Gilles Boccon-Gibod
- |
- |
- | This file is part of Bento4/AP4 (MP4 Atom Processing Library).
- |
- | Unless you have obtained Bento4 under a difference license,
- | this version of Bento4 is Bento4|GPL.
- | Bento4|GPL is free software; you can redistribute it and/or modify
- | it under the terms of the GNU General Public License as published by
- | the Free Software Foundation; either version 2, or (at your option)
- | any later version.
- |
- | Bento4|GPL is distributed in the hope that it will be useful,
- | but WITHOUT ANY WARRANTY; without even the implied warranty of
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- | GNU General Public License for more details.
- |
- | You should have received a copy of the GNU General Public License
- | along with Bento4|GPL; see the file COPYING. If not, write to the
- | Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- | 02111-1307, USA.
- |
- ****************************************************************/
- #ifndef _AP4_LIST_H_
- #define _AP4_LIST_H_
- /*----------------------------------------------------------------------
- | includes
- +---------------------------------------------------------------------*/
- #include "Ap4.h"
- #include "Ap4Results.h"
- /*----------------------------------------------------------------------
- | forward references
- +---------------------------------------------------------------------*/
- template <typename T> class AP4_List;
- /*----------------------------------------------------------------------
- | AP4_List
- +---------------------------------------------------------------------*/
- template <typename T>
- class AP4_List
- {
- public:
- // types
- class Item
- {
- public:
- // types
- class Operator
- {
- public:
- // methods
- virtual ~Operator() {}
- virtual AP4_Result Action(T* data) const = 0;
- };
- class Finder
- {
- public:
- // methods
- virtual ~Finder() {}
- virtual AP4_Result Test(T* data) const = 0;
- };
- // methods
- Item(T* data) : m_Data(data), m_Next(0), m_Prev(0) {}
- ~Item() {}
- Item* GetNext() { return m_Next; }
- Item* GetPrev() { return m_Prev; }
- T* GetData() { return m_Data; }
- private:
- // members
- T* m_Data;
- Item* m_Next;
- Item* m_Prev;
- // friends
- friend class AP4_List;
- };
- // methods
- AP4_List<T>(): m_ItemCount(0), m_Head(0), m_Tail(0) {}
- virtual ~AP4_List<T>();
- AP4_Result Add(T* data);
- AP4_Result Add(Item* item);
- AP4_Result Remove(T* data);
- AP4_Result Insert(Item* where, T* data);
- AP4_Result Get(AP4_Ordinal idx, T*& data);
- AP4_Result PopHead(T*& data);
- AP4_Result Apply(const typename Item::Operator& op);
- AP4_Result ApplyUntilFailure(const typename Item::Operator& op);
- AP4_Result ApplyUntilSuccess(const typename Item::Operator& op);
- AP4_Result ReverseApply(const typename Item::Operator& op);
- AP4_Result Find(const typename Item::Finder& finder, T*& data);
- AP4_Result ReverseFind(const typename Item::Finder& finder, T*& data);
- AP4_Result DeleteReferences();
- AP4_Cardinal ItemCount() { return m_ItemCount; }
- Item* FirstItem() { return m_Head; }
- Item* LastItem() { return m_Tail; }
-
- protected:
- // members
- AP4_Cardinal m_ItemCount;
- Item* m_Head;
- Item* m_Tail;
-
- private:
- // these cannot be used
- AP4_List<T>(const AP4_List<T>&);
- AP4_List<T>& operator=(const AP4_List<T>&);
- };
- /*----------------------------------------------------------------------
- | AP4_List<T>::~AP4_List<T>
- +---------------------------------------------------------------------*/
- template <typename T>
- AP4_List<T>::~AP4_List<T>()
- {
- Item* item = m_Head;
-
- while (item) {
- Item* next = item->m_Next;
- delete item;
- item = next;
- }
- }
-
- /*----------------------------------------------------------------------
- | AP4_List<T>::Add
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::Add(T* data)
- {
- return Add(new Item(data));
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::Add
- +---------------------------------------------------------------------*/
- template <typename T>
- AP4_Result
- AP4_List<T>::Add(Item* item)
- {
- // add element at the tail
- if (m_Tail) {
- item->m_Prev = m_Tail;
- item->m_Next = NULL;
- m_Tail->m_Next = item;
- m_Tail = item;
- } else {
- m_Head = item;
- m_Tail = item;
- item->m_Next = NULL;
- item->m_Prev = NULL;
- }
- // one more item in the list now
- m_ItemCount++;
-
- return AP4_SUCCESS;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::Remove
- +---------------------------------------------------------------------*/
- template <typename T>
- AP4_Result
- AP4_List<T>::Remove(T* data)
- {
- Item* item = m_Head;
- while (item) {
- if (item->m_Data == data) {
- // delete item
- if (item->m_Prev) {
- // item is not the head
- if (item->m_Next) {
- // item is not the tail
- item->m_Next->m_Prev = item->m_Prev;
- item->m_Prev->m_Next = item->m_Next;
- } else {
- // item is the tail
- m_Tail = item->m_Prev;
- m_Tail->m_Next = NULL;
- }
- } else {
- // item is the head
- m_Head = item->m_Next;
- if (m_Head) {
- // item is not the tail
- m_Head->m_Prev = NULL;
- } else {
- // item is also the tail
- m_Tail = NULL;
- }
- }
- // delete the item
- delete item;
- // one less item in the list now
- m_ItemCount--;
- return AP4_SUCCESS;
- }
- item = item->m_Next;
- }
-
- return AP4_ERROR_NO_SUCH_ITEM;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::Insert
- +---------------------------------------------------------------------*/
- template <typename T>
- AP4_Result
- AP4_List<T>::Insert(Item* where, T* data)
- {
- Item* item = new Item(data);
- if (where == NULL) {
- // insert as the head
- if (m_Head) {
- // replace the current head
- item->m_Prev = NULL;
- item->m_Next = m_Head;
- m_Head->m_Prev = item;
- m_Head = item;
- } else {
- // this item becomes the head and tail
- m_Head = item;
- m_Tail = item;
- item->m_Next = NULL;
- item->m_Prev = NULL;
- }
- } else {
- // insert after the 'where' item
- if (where == m_Tail) {
- // add the item at the end
- return Add(item);
- } else {
- // update the links
- item->m_Prev = where;
- item->m_Next = where->m_Next;
- where->m_Next->m_Prev = item;
- where->m_Next = item;
- }
- }
- // one more item in the list now
- ++m_ItemCount;
- return AP4_SUCCESS;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::Get
- +---------------------------------------------------------------------*/
- template <typename T>
- AP4_Result
- AP4_List<T>::Get(AP4_Ordinal idx, T*& data)
- {
- Item* item = m_Head;
- if (idx < m_ItemCount) {
- while (idx--) item = item->m_Next;
- data = item->m_Data;
- return AP4_SUCCESS;
- } else {
- data = NULL;
- return AP4_ERROR_NO_SUCH_ITEM;
- }
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::PopHead
- +---------------------------------------------------------------------*/
- template <typename T>
- AP4_Result
- AP4_List<T>::PopHead(T*& data)
- {
- // check that we have at least one item
- if (m_Head == NULL) {
- return AP4_ERROR_LIST_EMPTY;
- }
- // remove the item and return it
- data = m_Head->m_Data;
- Item* head = m_Head;
- m_Head = m_Head->m_Next;
- if (m_Head) {
- m_Head->m_Prev = NULL;
- } else {
- m_Tail = NULL;
- }
- // delete item
- delete head;
- // one less item in the list now
- m_ItemCount--;
-
- return AP4_SUCCESS;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::Apply
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::Apply(const typename Item::Operator& op)
- {
- Item* item = m_Head;
-
- while (item) {
- op.Action(item->m_Data);
- item = item->m_Next;
- }
- return AP4_SUCCESS;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::ApplyUntilFailure
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op)
- {
- Item* item = m_Head;
-
- while (item) {
- AP4_Result result;
- result = op.Action(item->m_Data);
- if (result != AP4_SUCCESS) return result;
- item = item->m_Next;
- }
- return AP4_SUCCESS;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::ApplyUntilSuccess
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op)
- {
- Item* item = m_Head;
-
- while (item) {
- AP4_Result result;
- result = op.Action(item->m_Data);
- if (result == AP4_SUCCESS) return AP4_SUCCESS;
- item = item->m_Next;
- }
- return AP4_FAILURE;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::ReverseApply
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::ReverseApply(const typename Item::Operator& op)
- {
- Item* item = m_Tail;
-
- while (item) {
- if (op.Action(item->m_Data) != AP4_SUCCESS) {
- return AP4_ERROR_LIST_OPERATION_ABORTED;
- }
- item = item->m_Prev;
- }
- return AP4_SUCCESS;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::Find
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::Find(const typename Item::Finder& finder, T*& data)
- {
- Item* item = m_Head;
-
- while (item) {
- if (finder.Test(item->m_Data) == AP4_SUCCESS) {
- data = item->m_Data;
- return AP4_SUCCESS;
- }
- item = item->m_Next;
- }
- data = NULL;
- return AP4_ERROR_NO_SUCH_ITEM;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::ReverseFind
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data)
- {
- Item* item = m_Tail;
-
- while (item) {
- if (finder.Test(item->m_Data) == AP4_SUCCESS) {
- data = item->m_Data;
- return AP4_SUCCESS;
- }
- item = item->m_Prev;
- }
- data = NULL;
- return AP4_ERROR_NO_SUCH_ITEM;
- }
- /*----------------------------------------------------------------------
- | AP4_List<T>::DeleteReferences
- +---------------------------------------------------------------------*/
- template <typename T>
- inline
- AP4_Result
- AP4_List<T>::DeleteReferences()
- {
- Item* item = m_Head;
-
- while (item) {
- Item* next = item->m_Next;
- delete item->m_Data;
- delete item;
- item = next;
- }
- // no more items
- m_Head = m_Tail = NULL;
- m_ItemCount = 0;
- return AP4_SUCCESS;
- }
- #endif // _AP4_LIST_H_