1 /*
2  * Copyright © 2014 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *     Wei Lin<wei.w.lin@intel.com>
26  *     Yuting Yang<yuting.yang@intel.com>
27  */
28 
29 #include "cm_array.h"
CmDynamicArray(const DWORD initSize)30 CmDynamicArray::CmDynamicArray(const DWORD initSize)
31 {
32 	m_pArrayBuffer = NULL;
33 
34 	m_UsedSize = 0;
35 	m_ActualSize = 0;
36 
37 	CreateArray(initSize);
38 }
39 
CmDynamicArray()40 CmDynamicArray::CmDynamicArray()
41 {
42 	m_pArrayBuffer = NULL;
43 	m_UsedSize = 0;
44 	m_ActualSize = 0;
45 }
46 
~CmDynamicArray(void)47 CmDynamicArray::~CmDynamicArray(void)
48 {
49 	Delete();
50 }
51 
GetElement(const DWORD index)52 void *CmDynamicArray::GetElement(const DWORD index)
53 {
54 
55 	void *element;
56 
57 	if (m_pArrayBuffer && IsValidIndex(index)) {
58 		element = m_pArrayBuffer[index];
59 	} else {
60 		CM_ASSERT(0);
61 		CmSafeMemSet(&element, 0, sizeof(void *));
62 	}
63 	return element;
64 }
65 
SetElement(const DWORD index,const void * element)66 bool CmDynamicArray::SetElement(const DWORD index, const void *element)
67 {
68 
69 	bool success = false;
70 
71 	if (!IsValidIndex(index)) {
72 		CreateArray(index + 1);
73 	}
74 
75 	if (m_pArrayBuffer && IsValidIndex(index)) {
76 		m_pArrayBuffer[index] = (void *)element;
77 		success = true;
78 	}
79 
80 	CM_ASSERT(success);
81 	return success;
82 }
83 
GetSize(void)84 DWORD CmDynamicArray::GetSize(void)
85 {
86 	const DWORD size = m_UsedSize;
87 	return size;
88 }
89 
Delete(void)90 void CmDynamicArray::Delete(void)
91 {
92 	DeleteArray();
93 	m_UsedSize = 0;
94 }
95 
operator =(const CmDynamicArray & array)96 CmDynamicArray & CmDynamicArray::operator=(const CmDynamicArray & array)
97 {
98 
99 	if (array.m_pArrayBuffer) {
100 		if (m_UsedSize < array.m_UsedSize) {
101 			CreateArray(array.m_UsedSize);
102 		}
103 
104 		if (m_pArrayBuffer && (m_UsedSize >= array.m_UsedSize)) {
105 			for (DWORD i = 0; i < array.m_UsedSize; i++) {
106 				m_pArrayBuffer[i] = array.m_pArrayBuffer[i];
107 			}
108 		}
109 	}
110 
111 	return *this;
112 }
113 
CreateArray(const DWORD size)114 void CmDynamicArray::CreateArray(const DWORD size)
115 {
116 	if (size) {
117 		if (size > GetMaxSize()) {
118 			DWORD actualSize = GetMaxSize() * 2;
119 
120 			if (size > actualSize) {
121 				actualSize = (DWORD) Round(Max(size, 32), 32);
122 			}
123 
124 			CM_ASSERT(actualSize >= size);
125 			CM_ASSERT(actualSize > m_ActualSize);
126 
127 			const DWORD allocSize = actualSize * sizeof(void *);
128 
129 			void **pArrayBuffer =
130 			    new(std::nothrow) void *[allocSize];
131 
132 			if (pArrayBuffer) {
133 				CmSafeMemSet(pArrayBuffer, 0, allocSize);
134 
135 				if (m_pArrayBuffer) {
136 					for (DWORD i = 0; i < m_UsedSize; i++) {
137 						pArrayBuffer[i] =
138 						    m_pArrayBuffer[i];
139 					}
140 
141 					DeleteArray();
142 				}
143 
144 				m_pArrayBuffer = pArrayBuffer;
145 				m_ActualSize = actualSize;
146 				m_UsedSize = size;
147 			} else {
148 				CM_ASSERT(0);
149 				return;
150 			}
151 		} else {
152 			m_UsedSize = size;
153 		}
154 	}
155 }
156 
DeleteArray(void)157 void CmDynamicArray::DeleteArray(void)
158 {
159 
160 	if (m_pArrayBuffer) {
161 		delete[]m_pArrayBuffer;
162 		m_pArrayBuffer = NULL;
163 	}
164 
165 	m_ActualSize = 0;
166 }
167 
GetMaxSize(void)168 DWORD CmDynamicArray::GetMaxSize(void)
169 {
170 	return m_ActualSize;
171 }
172 
IsValidIndex(const DWORD index)173 bool CmDynamicArray::IsValidIndex(const DWORD index)
174 {
175 	return (index < GetSize());
176 }
177 
GetFirstFreeIndex()178 DWORD CmDynamicArray::GetFirstFreeIndex()
179 {
180 	DWORD index = 0;
181 	for (index = 0; index < GetMaxSize(); index++) {
182 		if (m_pArrayBuffer[index] == NULL) {
183 			return index;
184 		}
185 	}
186 	return index;
187 }
188 
SetElementIntoFreeSlot(const void * element)189 bool CmDynamicArray::SetElementIntoFreeSlot(const void *element)
190 {
191 	DWORD index = GetFirstFreeIndex();
192 
193 	return SetElement(index, element);
194 }
195