Ap4List.h
Go to the documentation of this file.00001 /***************************************************************** 00002 | 00003 | AP4 - Lists 00004 | 00005 | Copyright 2002-2008 Axiomatic Systems, LLC 00006 | 00007 | 00008 | This file is part of Bento4/AP4 (MP4 Atom Processing Library). 00009 | 00010 | Unless you have obtained Bento4 under a difference license, 00011 | this version of Bento4 is Bento4|GPL. 00012 | Bento4|GPL is free software; you can redistribute it and/or modify 00013 | it under the terms of the GNU General Public License as published by 00014 | the Free Software Foundation; either version 2, or (at your option) 00015 | any later version. 00016 | 00017 | Bento4|GPL is distributed in the hope that it will be useful, 00018 | but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 | GNU General Public License for more details. 00021 | 00022 | You should have received a copy of the GNU General Public License 00023 | along with Bento4|GPL; see the file COPYING. If not, write to the 00024 | Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 00025 | 02111-1307, USA. 00026 | 00027 ****************************************************************/ 00028 00029 #ifndef _AP4_LIST_H_ 00030 #define _AP4_LIST_H_ 00031 00032 /*---------------------------------------------------------------------- 00033 | includes 00034 +---------------------------------------------------------------------*/ 00035 #include "Ap4Types.h" 00036 #include "Ap4Results.h" 00037 00038 /*---------------------------------------------------------------------- 00039 | forward references 00040 +---------------------------------------------------------------------*/ 00041 template <typename T> class AP4_List; 00042 00043 /*---------------------------------------------------------------------- 00044 | AP4_List 00045 +---------------------------------------------------------------------*/ 00046 template <typename T> 00047 class AP4_List 00048 { 00049 public: 00050 // types 00051 class Item 00052 { 00053 public: 00054 // types 00055 class Operator 00056 { 00057 public: 00058 // methods 00059 virtual ~Operator() {} 00060 virtual AP4_Result Action(T* data) const = 0; 00061 }; 00062 00063 class Finder 00064 { 00065 public: 00066 // methods 00067 virtual ~Finder() {} 00068 virtual AP4_Result Test(T* data) const = 0; 00069 }; 00070 00071 // methods 00072 Item(T* data) : m_Data(data), m_Next(0), m_Prev(0) {} 00073 ~Item() {} 00074 Item* GetNext() { return m_Next; } 00075 Item* GetPrev() { return m_Prev; } 00076 T* GetData() { return m_Data; } 00077 00078 private: 00079 // members 00080 T* m_Data; 00081 Item* m_Next; 00082 Item* m_Prev; 00083 00084 // friends 00085 friend class AP4_List; 00086 }; 00087 00088 // methods 00089 AP4_List<T>(): m_ItemCount(0), m_Head(0), m_Tail(0) {} 00090 virtual ~AP4_List<T>(); 00091 AP4_Result Clear(); 00092 AP4_Result Add(T* data); 00093 AP4_Result Add(Item* item); 00094 AP4_Result Remove(T* data); 00095 AP4_Result Insert(Item* where, T* data); 00096 AP4_Result Get(AP4_Ordinal idx, T*& data) const; 00097 AP4_Result PopHead(T*& data); 00098 AP4_Result Apply(const typename Item::Operator& op) const; 00099 AP4_Result ApplyUntilFailure(const typename Item::Operator& op) const; 00100 AP4_Result ApplyUntilSuccess(const typename Item::Operator& op) const ; 00101 AP4_Result ReverseApply(const typename Item::Operator& op) const; 00102 AP4_Result Find(const typename Item::Finder& finder, T*& data) const; 00103 AP4_Result ReverseFind(const typename Item::Finder& finder, T*& data) const; 00104 AP4_Result DeleteReferences(); 00105 AP4_Cardinal ItemCount() const { return m_ItemCount; } 00106 Item* FirstItem() const { return m_Head; } 00107 Item* LastItem() const { return m_Tail; } 00108 00109 protected: 00110 // members 00111 AP4_Cardinal m_ItemCount; 00112 Item* m_Head; 00113 Item* m_Tail; 00114 00115 private: 00116 // these cannot be used 00117 AP4_List<T>(const AP4_List<T>&); 00118 AP4_List<T>& operator=(const AP4_List<T>&); 00119 }; 00120 00121 /*---------------------------------------------------------------------- 00122 | AP4_List<T>::~AP4_List<T> 00123 +---------------------------------------------------------------------*/ 00124 template <typename T> 00125 AP4_List<T>::~AP4_List() 00126 { 00127 Clear(); 00128 } 00129 00130 /*---------------------------------------------------------------------- 00131 | AP4_List<T>::Clear 00132 +---------------------------------------------------------------------*/ 00133 template <typename T> 00134 inline 00135 AP4_Result 00136 AP4_List<T>::Clear() 00137 { 00138 Item* item = m_Head; 00139 00140 while (item) { 00141 Item* next = item->m_Next; 00142 delete item; 00143 item = next; 00144 } 00145 m_ItemCount = 0; 00146 m_Head = m_Tail = NULL; 00147 00148 return AP4_SUCCESS; 00149 } 00150 00151 /*---------------------------------------------------------------------- 00152 | AP4_List<T>::Add 00153 +---------------------------------------------------------------------*/ 00154 template <typename T> 00155 inline 00156 AP4_Result 00157 AP4_List<T>::Add(T* data) 00158 { 00159 return Add(new Item(data)); 00160 } 00161 00162 /*---------------------------------------------------------------------- 00163 | AP4_List<T>::Add 00164 +---------------------------------------------------------------------*/ 00165 template <typename T> 00166 AP4_Result 00167 AP4_List<T>::Add(Item* item) 00168 { 00169 // add element at the tail 00170 if (m_Tail) { 00171 item->m_Prev = m_Tail; 00172 item->m_Next = NULL; 00173 m_Tail->m_Next = item; 00174 m_Tail = item; 00175 } else { 00176 m_Head = item; 00177 m_Tail = item; 00178 item->m_Next = NULL; 00179 item->m_Prev = NULL; 00180 } 00181 00182 // one more item in the list now 00183 m_ItemCount++; 00184 00185 return AP4_SUCCESS; 00186 } 00187 00188 /*---------------------------------------------------------------------- 00189 | AP4_List<T>::Remove 00190 +---------------------------------------------------------------------*/ 00191 template <typename T> 00192 AP4_Result 00193 AP4_List<T>::Remove(T* data) 00194 { 00195 Item* item = m_Head; 00196 00197 while (item) { 00198 if (item->m_Data == data) { 00199 // delete item 00200 if (item->m_Prev) { 00201 // item is not the head 00202 if (item->m_Next) { 00203 // item is not the tail 00204 item->m_Next->m_Prev = item->m_Prev; 00205 item->m_Prev->m_Next = item->m_Next; 00206 } else { 00207 // item is the tail 00208 m_Tail = item->m_Prev; 00209 m_Tail->m_Next = NULL; 00210 } 00211 } else { 00212 // item is the head 00213 m_Head = item->m_Next; 00214 if (m_Head) { 00215 // item is not the tail 00216 m_Head->m_Prev = NULL; 00217 } else { 00218 // item is also the tail 00219 m_Tail = NULL; 00220 } 00221 } 00222 00223 // delete the item 00224 delete item; 00225 00226 // one less item in the list now 00227 m_ItemCount--; 00228 00229 return AP4_SUCCESS; 00230 } 00231 item = item->m_Next; 00232 } 00233 00234 return AP4_ERROR_NO_SUCH_ITEM; 00235 } 00236 00237 /*---------------------------------------------------------------------- 00238 | AP4_List<T>::Insert 00239 +---------------------------------------------------------------------*/ 00240 template <typename T> 00241 AP4_Result 00242 AP4_List<T>::Insert(Item* where, T* data) 00243 { 00244 Item* item = new Item(data); 00245 00246 if (where == NULL) { 00247 // insert as the head 00248 if (m_Head) { 00249 // replace the current head 00250 item->m_Prev = NULL; 00251 item->m_Next = m_Head; 00252 m_Head->m_Prev = item; 00253 m_Head = item; 00254 } else { 00255 // this item becomes the head and tail 00256 m_Head = item; 00257 m_Tail = item; 00258 item->m_Next = NULL; 00259 item->m_Prev = NULL; 00260 } 00261 } else { 00262 // insert after the 'where' item 00263 if (where == m_Tail) { 00264 // add the item at the end 00265 return Add(item); 00266 } else { 00267 // update the links 00268 item->m_Prev = where; 00269 item->m_Next = where->m_Next; 00270 where->m_Next->m_Prev = item; 00271 where->m_Next = item; 00272 } 00273 } 00274 00275 // one more item in the list now 00276 ++m_ItemCount; 00277 00278 return AP4_SUCCESS; 00279 } 00280 00281 /*---------------------------------------------------------------------- 00282 | AP4_List<T>::Get 00283 +---------------------------------------------------------------------*/ 00284 template <typename T> 00285 AP4_Result 00286 AP4_List<T>::Get(AP4_Ordinal idx, T*& data) const 00287 { 00288 Item* item = m_Head; 00289 00290 if (idx < m_ItemCount) { 00291 while (idx--) item = item->m_Next; 00292 data = item->m_Data; 00293 return AP4_SUCCESS; 00294 } else { 00295 data = NULL; 00296 return AP4_ERROR_NO_SUCH_ITEM; 00297 } 00298 } 00299 00300 /*---------------------------------------------------------------------- 00301 | AP4_List<T>::PopHead 00302 +---------------------------------------------------------------------*/ 00303 template <typename T> 00304 AP4_Result 00305 AP4_List<T>::PopHead(T*& data) 00306 { 00307 // check that we have at least one item 00308 if (m_Head == NULL) { 00309 return AP4_ERROR_LIST_EMPTY; 00310 } 00311 00312 // remove the item and return it 00313 data = m_Head->m_Data; 00314 Item* head = m_Head; 00315 m_Head = m_Head->m_Next; 00316 if (m_Head) { 00317 m_Head->m_Prev = NULL; 00318 } else { 00319 m_Tail = NULL; 00320 } 00321 00322 // delete item 00323 delete head; 00324 00325 // one less item in the list now 00326 m_ItemCount--; 00327 00328 return AP4_SUCCESS; 00329 } 00330 00331 /*---------------------------------------------------------------------- 00332 | AP4_List<T>::Apply 00333 +---------------------------------------------------------------------*/ 00334 template <typename T> 00335 inline 00336 AP4_Result 00337 AP4_List<T>::Apply(const typename Item::Operator& op) const 00338 { 00339 Item* item = m_Head; 00340 00341 while (item) { 00342 op.Action(item->m_Data); 00343 item = item->m_Next; 00344 } 00345 00346 return AP4_SUCCESS; 00347 } 00348 00349 /*---------------------------------------------------------------------- 00350 | AP4_List<T>::ApplyUntilFailure 00351 +---------------------------------------------------------------------*/ 00352 template <typename T> 00353 inline 00354 AP4_Result 00355 AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op) const 00356 { 00357 Item* item = m_Head; 00358 00359 while (item) { 00360 AP4_Result result; 00361 result = op.Action(item->m_Data); 00362 if (result != AP4_SUCCESS) return result; 00363 item = item->m_Next; 00364 } 00365 00366 return AP4_SUCCESS; 00367 } 00368 00369 /*---------------------------------------------------------------------- 00370 | AP4_List<T>::ApplyUntilSuccess 00371 +---------------------------------------------------------------------*/ 00372 template <typename T> 00373 inline 00374 AP4_Result 00375 AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op) const 00376 { 00377 Item* item = m_Head; 00378 00379 while (item) { 00380 AP4_Result result; 00381 result = op.Action(item->m_Data); 00382 if (result == AP4_SUCCESS) return AP4_SUCCESS; 00383 item = item->m_Next; 00384 } 00385 00386 return AP4_FAILURE; 00387 } 00388 00389 /*---------------------------------------------------------------------- 00390 | AP4_List<T>::ReverseApply 00391 +---------------------------------------------------------------------*/ 00392 template <typename T> 00393 inline 00394 AP4_Result 00395 AP4_List<T>::ReverseApply(const typename Item::Operator& op) const 00396 { 00397 Item* item = m_Tail; 00398 00399 while (item) { 00400 if (op.Action(item->m_Data) != AP4_SUCCESS) { 00401 return AP4_ERROR_LIST_OPERATION_ABORTED; 00402 } 00403 item = item->m_Prev; 00404 } 00405 00406 return AP4_SUCCESS; 00407 } 00408 00409 /*---------------------------------------------------------------------- 00410 | AP4_List<T>::Find 00411 +---------------------------------------------------------------------*/ 00412 template <typename T> 00413 inline 00414 AP4_Result 00415 AP4_List<T>::Find(const typename Item::Finder& finder, T*& data) const 00416 { 00417 Item* item = m_Head; 00418 00419 while (item) { 00420 if (finder.Test(item->m_Data) == AP4_SUCCESS) { 00421 data = item->m_Data; 00422 return AP4_SUCCESS; 00423 } 00424 item = item->m_Next; 00425 } 00426 00427 data = NULL; 00428 return AP4_ERROR_NO_SUCH_ITEM; 00429 } 00430 00431 /*---------------------------------------------------------------------- 00432 | AP4_List<T>::ReverseFind 00433 +---------------------------------------------------------------------*/ 00434 template <typename T> 00435 inline 00436 AP4_Result 00437 AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data) const 00438 { 00439 Item* item = m_Tail; 00440 00441 while (item) { 00442 if (finder.Test(item->m_Data) == AP4_SUCCESS) { 00443 data = item->m_Data; 00444 return AP4_SUCCESS; 00445 } 00446 item = item->m_Prev; 00447 } 00448 00449 data = NULL; 00450 return AP4_ERROR_NO_SUCH_ITEM; 00451 } 00452 00453 /*---------------------------------------------------------------------- 00454 | AP4_List<T>::DeleteReferences 00455 +---------------------------------------------------------------------*/ 00456 template <typename T> 00457 inline 00458 AP4_Result 00459 AP4_List<T>::DeleteReferences() 00460 { 00461 Item* item = m_Head; 00462 00463 while (item) { 00464 Item* next = item->m_Next; 00465 delete item->m_Data; 00466 delete item; 00467 item = next; 00468 } 00469 00470 // no more items 00471 m_Head = m_Tail = NULL; 00472 m_ItemCount = 0; 00473 00474 return AP4_SUCCESS; 00475 } 00476 00477 #endif // _AP4_LIST_H_ 00478 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 00489 00490
Generated on Thu May 13 16:36:32 2010 for Bento4 MP4 SDK by
