00001 /***************************************************************** 00002 | 00003 | AP4 - Arrays 00004 | 00005 | Copyright 2002-2006 Gilles Boccon-Gibod & Julien Boeuf 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 ****************************************************************/ 00033 #ifndef _AP4_ARRAY_H_ 00034 #define _AP4_ARRAY_H_ 00035 00036 /*---------------------------------------------------------------------- 00037 | includes 00038 +---------------------------------------------------------------------*/ 00039 #include <new> 00040 #include "Ap4Types.h" 00041 #include "Ap4Results.h" 00042 00043 /*---------------------------------------------------------------------- 00044 | constants 00045 +---------------------------------------------------------------------*/ 00046 const int AP4_ARRAY_INITIAL_COUNT = 64; 00047 00048 /*---------------------------------------------------------------------- 00049 | AP4_Array 00050 +---------------------------------------------------------------------*/ 00051 template <typename T> 00052 class AP4_Array 00053 { 00054 public: 00055 // methods 00056 AP4_Array(): m_AllocatedCount(0), m_ItemCount(0), m_Items(0) {} 00057 AP4_Array(const T* items, AP4_Size count); 00058 virtual ~AP4_Array(); 00059 AP4_Cardinal ItemCount() const { return m_ItemCount; } 00060 AP4_Result Append(const T& item); 00061 T& operator[](unsigned long idx) { return m_Items[idx]; } 00062 const T& operator[](unsigned long idx) const { return m_Items[idx]; } 00063 AP4_Result Clear(); 00064 AP4_Result EnsureCapacity(AP4_Cardinal count); 00065 00066 protected: 00067 // members 00068 AP4_Cardinal m_AllocatedCount; 00069 AP4_Cardinal m_ItemCount; 00070 T* m_Items; 00071 }; 00072 00073 /*---------------------------------------------------------------------- 00074 | AP4_Array<T>::AP4_Array<T> 00075 +---------------------------------------------------------------------*/ 00076 template <typename T> 00077 AP4_Array<T>::AP4_Array(const T* items, AP4_Size count) : 00078 m_AllocatedCount(count), 00079 m_ItemCount(count), 00080 m_Items((T*)::operator new(count*sizeof(T))) 00081 { 00082 for (unsigned int i=0; i<count; i++) { 00083 new ((void*)&m_Items[i]) T(items[i]); 00084 } 00085 } 00086 00087 /*---------------------------------------------------------------------- 00088 | AP4_Array<T>::~AP4_Array<T> 00089 +---------------------------------------------------------------------*/ 00090 template <typename T> 00091 AP4_Array<T>::~AP4_Array() 00092 { 00093 Clear(); 00094 ::operator delete((void*)m_Items); 00095 } 00096 00097 /*---------------------------------------------------------------------- 00098 | NPT_Array<T>::Clear 00099 +---------------------------------------------------------------------*/ 00100 template <typename T> 00101 AP4_Result 00102 AP4_Array<T>::Clear() 00103 { 00104 // destroy all items 00105 for (AP4_Ordinal i=0; i<m_ItemCount; i++) { 00106 m_Items[i].~T(); 00107 } 00108 00109 m_ItemCount = 0; 00110 00111 return AP4_SUCCESS; 00112 } 00113 00114 /*---------------------------------------------------------------------- 00115 | AP4_Array<T>::EnsureCapacity 00116 +---------------------------------------------------------------------*/ 00117 template <typename T> 00118 AP4_Result 00119 AP4_Array<T>::EnsureCapacity(AP4_Cardinal count) 00120 { 00121 // check if we already have enough 00122 if (count <= m_AllocatedCount) return AP4_SUCCESS; 00123 00124 // (re)allocate the items 00125 T* new_items = (T*) ::operator new (count*sizeof(T)); 00126 if (new_items == NULL) { 00127 return AP4_ERROR_OUT_OF_MEMORY; 00128 } 00129 if (m_ItemCount && m_Items) { 00130 for (unsigned int i=0; i<m_ItemCount; i++) { 00131 new ((void*)&new_items[i]) T(m_Items[i]); 00132 m_Items[i].~T(); 00133 } 00134 ::operator delete((void*)m_Items); 00135 } 00136 m_Items = new_items; 00137 m_AllocatedCount = count; 00138 00139 return AP4_SUCCESS; 00140 } 00141 00142 /*---------------------------------------------------------------------- 00143 | AP4_Array<T>::Append 00144 +---------------------------------------------------------------------*/ 00145 template <typename T> 00146 AP4_Result 00147 AP4_Array<T>::Append(const T& item) 00148 { 00149 // ensure that we have enough space 00150 if (m_AllocatedCount < m_ItemCount+1) { 00151 // try double the size, with a minimum 00152 unsigned long new_count = m_AllocatedCount?2*m_AllocatedCount:AP4_ARRAY_INITIAL_COUNT; 00153 00154 // if that's still not enough, just ask for what we need 00155 if (new_count < m_ItemCount+1) new_count = m_ItemCount+1; 00156 00157 // reserve the space 00158 AP4_Result result = EnsureCapacity(new_count); 00159 if (result != AP4_SUCCESS) return result; 00160 } 00161 00162 // store the item 00163 new ((void*)&m_Items[m_ItemCount++]) T(item); 00164 00165 return AP4_SUCCESS; 00166 } 00167 00168 #endif // _AP4_ARRAY_H_ 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181