1 /*
2  * The contents of this file are subject to the Mozilla Public
3  * License Version 1.1 (the "License"); you may not use this file
4  * except in compliance with the License. You may obtain a copy of
5  * the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS
8  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9  * implied. See the License for the specific language governing
10  * rights and limitations under the License.
11  *
12  * The Original Code is MPEG4IP.
13  *
14  * The Initial Developer of the Original Code is Cisco Systems Inc.
15  * Portions created by Cisco Systems Inc. are
16  * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
17  *
18  * Contributor(s):
19  *		Dave Mackie		dmackie@cisco.com
20  */
21 
22 #ifndef __MP4_ARRAY_INCLUDED__
23 #define __MP4_ARRAY_INCLUDED__
24 
25 typedef u_int32_t MP4ArrayIndex;
26 
27 class MP4Array {
28 public:
MP4Array()29 	MP4Array() {
30 		m_numElements = 0;
31 		m_maxNumElements = 0;
32 	}
33 
ValidIndex(MP4ArrayIndex index)34 	inline bool ValidIndex(MP4ArrayIndex index) {
35 		if (m_numElements == 0 || index > m_numElements - 1) {
36 			return false;
37 		}
38 		return true;
39 	}
40 
Size(void)41 	inline MP4ArrayIndex Size(void) {
42 		return m_numElements;
43 	}
44 
MaxSize(void)45 	inline MP4ArrayIndex MaxSize(void) {
46 		return m_maxNumElements;
47 	}
48 
49 protected:
50 	MP4ArrayIndex	m_numElements;
51 	MP4ArrayIndex	m_maxNumElements;
52 };
53 
54 // macro to generate subclasses
55 // we use this as an alternative to templates
56 // due to the excessive compile time price of extensive template usage
57 
58 #define MP4ARRAY_DECL(name, type) \
59 	class name##Array : public MP4Array { \
60 	public: \
61 		name##Array() { \
62 			m_elements = NULL; \
63 		} \
64 		\
65 		~name##Array() { \
66 			MP4Free(m_elements); \
67 		} \
68 		\
69 		inline void Add(type newElement) { \
70 			Insert(newElement, m_numElements); \
71 		} \
72 		\
73 		void Insert(type newElement, MP4ArrayIndex newIndex) { \
74 			if (newIndex > m_numElements) { \
75 				throw new MP4Error(ERANGE, "MP4Array::Insert"); \
76 			} \
77 			if (m_numElements == m_maxNumElements) { \
78 				m_maxNumElements = MAX(m_maxNumElements, 1) * 2; \
79 				m_elements = (type*)MP4Realloc(m_elements, \
80 					m_maxNumElements * sizeof(type)); \
81 			} \
82 			memmove(&m_elements[newIndex + 1], &m_elements[newIndex], \
83 				(m_numElements - newIndex) * sizeof(type)); \
84 			m_elements[newIndex] = newElement; \
85 			m_numElements++; \
86 		} \
87 		\
88 		void Delete(MP4ArrayIndex index) { \
89 			if (!ValidIndex(index)) { \
90 				throw new MP4Error(ERANGE, "MP4Array::Delete"); \
91 			} \
92 			m_numElements--; \
93 			if (index < m_numElements) { \
94 			  memmove(&m_elements[index], &m_elements[index + 1], \
95 			   	  (m_numElements - index) * sizeof(type)); \
96 			} \
97 		} \
98 		void Resize(MP4ArrayIndex newSize) { \
99 			m_numElements = newSize; \
100 			m_maxNumElements = newSize; \
101 			m_elements = (type*)MP4Realloc(m_elements, \
102 				m_maxNumElements * sizeof(type)); \
103 		} \
104 		\
105 		type& operator[](MP4ArrayIndex index) { \
106 			if (!ValidIndex(index)) { \
107 				throw new MP4Error(ERANGE, "index %u of %u", "MP4Array::[]", index, m_numElements); \
108 			} \
109 			return m_elements[index]; \
110 		} \
111 		\
112 	protected: \
113 		type*	m_elements; \
114 	};
115 
116 MP4ARRAY_DECL(MP4Integer8, u_int8_t)
117 
118 MP4ARRAY_DECL(MP4Integer16, u_int16_t)
119 
120 MP4ARRAY_DECL(MP4Integer32, u_int32_t)
121 
122 MP4ARRAY_DECL(MP4Integer64, u_int64_t)
123 
124 MP4ARRAY_DECL(MP4Float32, float)
125 
126 MP4ARRAY_DECL(MP4Float64, double)
127 
128 MP4ARRAY_DECL(MP4String, char*)
129 
130 MP4ARRAY_DECL(MP4Bytes, u_int8_t*)
131 
132 #endif /* __MP4_ARRAY_INCLUDED__ */
133