00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _AP4_LIST_H_
00030 #define _AP4_LIST_H_
00031
00032
00033
00034
00035 #include "Ap4Types.h"
00036 #include "Ap4Results.h"
00037
00038
00039
00040
00041 template <typename T> class AP4_List;
00042
00043
00044
00045
00046 template <typename T>
00047 class AP4_List
00048 {
00049 public:
00050
00051 class Item
00052 {
00053 public:
00054
00055 class Operator
00056 {
00057 public:
00058
00059 virtual ~Operator() {}
00060 virtual AP4_Result Action(T* data) const = 0;
00061 };
00062
00063 class Finder
00064 {
00065 public:
00066
00067 virtual ~Finder() {}
00068 virtual AP4_Result Test(T* data) const = 0;
00069 };
00070
00071
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
00080 T* m_Data;
00081 Item* m_Next;
00082 Item* m_Prev;
00083
00084
00085 friend class AP4_List;
00086 };
00087
00088
00089 AP4_List<T>(): m_ItemCount(0), m_Head(0), m_Tail(0) {}
00090 virtual ~AP4_List<T>();
00091 AP4_Result Add(T* data);
00092 AP4_Result Add(Item* item);
00093 AP4_Result Remove(T* data);
00094 AP4_Result Insert(Item* where, T* data);
00095 AP4_Result Get(AP4_Ordinal idx, T*& data) const;
00096 AP4_Result PopHead(T*& data);
00097 AP4_Result Apply(const typename Item::Operator& op) const;
00098 AP4_Result ApplyUntilFailure(const typename Item::Operator& op) const;
00099 AP4_Result ApplyUntilSuccess(const typename Item::Operator& op) const ;
00100 AP4_Result ReverseApply(const typename Item::Operator& op) const;
00101 AP4_Result Find(const typename Item::Finder& finder, T*& data) const;
00102 AP4_Result ReverseFind(const typename Item::Finder& finder, T*& data) const;
00103 AP4_Result DeleteReferences();
00104 AP4_Cardinal ItemCount() const { return m_ItemCount; }
00105 Item* FirstItem() const { return m_Head; }
00106 Item* LastItem() const { return m_Tail; }
00107
00108 protected:
00109
00110 AP4_Cardinal m_ItemCount;
00111 Item* m_Head;
00112 Item* m_Tail;
00113
00114 private:
00115
00116 AP4_List<T>(const AP4_List<T>&);
00117 AP4_List<T>& operator=(const AP4_List<T>&);
00118 };
00119
00120
00121
00122
00123 template <typename T>
00124 AP4_List<T>::~AP4_List()
00125 {
00126 Item* item = m_Head;
00127
00128 while (item) {
00129 Item* next = item->m_Next;
00130 delete item;
00131 item = next;
00132 }
00133 }
00134
00135
00136
00137
00138 template <typename T>
00139 inline
00140 AP4_Result
00141 AP4_List<T>::Add(T* data)
00142 {
00143 return Add(new Item(data));
00144 }
00145
00146
00147
00148
00149 template <typename T>
00150 AP4_Result
00151 AP4_List<T>::Add(Item* item)
00152 {
00153
00154 if (m_Tail) {
00155 item->m_Prev = m_Tail;
00156 item->m_Next = NULL;
00157 m_Tail->m_Next = item;
00158 m_Tail = item;
00159 } else {
00160 m_Head = item;
00161 m_Tail = item;
00162 item->m_Next = NULL;
00163 item->m_Prev = NULL;
00164 }
00165
00166
00167 m_ItemCount++;
00168
00169 return AP4_SUCCESS;
00170 }
00171
00172
00173
00174
00175 template <typename T>
00176 AP4_Result
00177 AP4_List<T>::Remove(T* data)
00178 {
00179 Item* item = m_Head;
00180
00181 while (item) {
00182 if (item->m_Data == data) {
00183
00184 if (item->m_Prev) {
00185
00186 if (item->m_Next) {
00187
00188 item->m_Next->m_Prev = item->m_Prev;
00189 item->m_Prev->m_Next = item->m_Next;
00190 } else {
00191
00192 m_Tail = item->m_Prev;
00193 m_Tail->m_Next = NULL;
00194 }
00195 } else {
00196
00197 m_Head = item->m_Next;
00198 if (m_Head) {
00199
00200 m_Head->m_Prev = NULL;
00201 } else {
00202
00203 m_Tail = NULL;
00204 }
00205 }
00206
00207
00208 delete item;
00209
00210
00211 m_ItemCount--;
00212
00213 return AP4_SUCCESS;
00214 }
00215 item = item->m_Next;
00216 }
00217
00218 return AP4_ERROR_NO_SUCH_ITEM;
00219 }
00220
00221
00222
00223
00224 template <typename T>
00225 AP4_Result
00226 AP4_List<T>::Insert(Item* where, T* data)
00227 {
00228 Item* item = new Item(data);
00229
00230 if (where == NULL) {
00231
00232 if (m_Head) {
00233
00234 item->m_Prev = NULL;
00235 item->m_Next = m_Head;
00236 m_Head->m_Prev = item;
00237 m_Head = item;
00238 } else {
00239
00240 m_Head = item;
00241 m_Tail = item;
00242 item->m_Next = NULL;
00243 item->m_Prev = NULL;
00244 }
00245 } else {
00246
00247 if (where == m_Tail) {
00248
00249 return Add(item);
00250 } else {
00251
00252 item->m_Prev = where;
00253 item->m_Next = where->m_Next;
00254 where->m_Next->m_Prev = item;
00255 where->m_Next = item;
00256 }
00257 }
00258
00259
00260 ++m_ItemCount;
00261
00262 return AP4_SUCCESS;
00263 }
00264
00265
00266
00267
00268 template <typename T>
00269 AP4_Result
00270 AP4_List<T>::Get(AP4_Ordinal idx, T*& data) const
00271 {
00272 Item* item = m_Head;
00273
00274 if (idx < m_ItemCount) {
00275 while (idx--) item = item->m_Next;
00276 data = item->m_Data;
00277 return AP4_SUCCESS;
00278 } else {
00279 data = NULL;
00280 return AP4_ERROR_NO_SUCH_ITEM;
00281 }
00282 }
00283
00284
00285
00286
00287 template <typename T>
00288 AP4_Result
00289 AP4_List<T>::PopHead(T*& data)
00290 {
00291
00292 if (m_Head == NULL) {
00293 return AP4_ERROR_LIST_EMPTY;
00294 }
00295
00296
00297 data = m_Head->m_Data;
00298 Item* head = m_Head;
00299 m_Head = m_Head->m_Next;
00300 if (m_Head) {
00301 m_Head->m_Prev = NULL;
00302 } else {
00303 m_Tail = NULL;
00304 }
00305
00306
00307 delete head;
00308
00309
00310 m_ItemCount--;
00311
00312 return AP4_SUCCESS;
00313 }
00314
00315
00316
00317
00318 template <typename T>
00319 inline
00320 AP4_Result
00321 AP4_List<T>::Apply(const typename Item::Operator& op) const
00322 {
00323 Item* item = m_Head;
00324
00325 while (item) {
00326 op.Action(item->m_Data);
00327 item = item->m_Next;
00328 }
00329
00330 return AP4_SUCCESS;
00331 }
00332
00333
00334
00335
00336 template <typename T>
00337 inline
00338 AP4_Result
00339 AP4_List<T>::ApplyUntilFailure(const typename Item::Operator& op) const
00340 {
00341 Item* item = m_Head;
00342
00343 while (item) {
00344 AP4_Result result;
00345 result = op.Action(item->m_Data);
00346 if (result != AP4_SUCCESS) return result;
00347 item = item->m_Next;
00348 }
00349
00350 return AP4_SUCCESS;
00351 }
00352
00353
00354
00355
00356 template <typename T>
00357 inline
00358 AP4_Result
00359 AP4_List<T>::ApplyUntilSuccess(const typename Item::Operator& op) const
00360 {
00361 Item* item = m_Head;
00362
00363 while (item) {
00364 AP4_Result result;
00365 result = op.Action(item->m_Data);
00366 if (result == AP4_SUCCESS) return AP4_SUCCESS;
00367 item = item->m_Next;
00368 }
00369
00370 return AP4_FAILURE;
00371 }
00372
00373
00374
00375
00376 template <typename T>
00377 inline
00378 AP4_Result
00379 AP4_List<T>::ReverseApply(const typename Item::Operator& op) const
00380 {
00381 Item* item = m_Tail;
00382
00383 while (item) {
00384 if (op.Action(item->m_Data) != AP4_SUCCESS) {
00385 return AP4_ERROR_LIST_OPERATION_ABORTED;
00386 }
00387 item = item->m_Prev;
00388 }
00389
00390 return AP4_SUCCESS;
00391 }
00392
00393
00394
00395
00396 template <typename T>
00397 inline
00398 AP4_Result
00399 AP4_List<T>::Find(const typename Item::Finder& finder, T*& data) const
00400 {
00401 Item* item = m_Head;
00402
00403 while (item) {
00404 if (finder.Test(item->m_Data) == AP4_SUCCESS) {
00405 data = item->m_Data;
00406 return AP4_SUCCESS;
00407 }
00408 item = item->m_Next;
00409 }
00410
00411 data = NULL;
00412 return AP4_ERROR_NO_SUCH_ITEM;
00413 }
00414
00415
00416
00417
00418 template <typename T>
00419 inline
00420 AP4_Result
00421 AP4_List<T>::ReverseFind(const typename Item::Finder& finder, T*& data) const
00422 {
00423 Item* item = m_Tail;
00424
00425 while (item) {
00426 if (finder.Test(item->m_Data) == AP4_SUCCESS) {
00427 data = item->m_Data;
00428 return AP4_SUCCESS;
00429 }
00430 item = item->m_Prev;
00431 }
00432
00433 data = NULL;
00434 return AP4_ERROR_NO_SUCH_ITEM;
00435 }
00436
00437
00438
00439
00440 template <typename T>
00441 inline
00442 AP4_Result
00443 AP4_List<T>::DeleteReferences()
00444 {
00445 Item* item = m_Head;
00446
00447 while (item) {
00448 Item* next = item->m_Next;
00449 delete item->m_Data;
00450 delete item;
00451 item = next;
00452 }
00453
00454
00455 m_Head = m_Tail = NULL;
00456 m_ItemCount = 0;
00457
00458 return AP4_SUCCESS;
00459 }
00460
00461 #endif // _AP4_LIST_H_
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474