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