Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / base / collection / FBaseColQueue.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file        FBaseColQueue.cpp
19  * @brief       This is the implementation for Queue class.
20  */
21 #include <new>
22 #include <unique_ptr.h>
23 #include <FBaseColQueue.h>
24 #include <FBaseResult.h>
25 #include <FBaseSysLog.h>
26
27 namespace Tizen { namespace Base { namespace Collection
28 {
29
30 /**
31  * @class       _QueueEnumerator
32  * @brief       This is an implementation of IEnumerator for Queue.
33  */
34 class _QueueEnumerator
35         : public IEnumerator
36         , public Object
37 {
38 public:
39         _QueueEnumerator(const Queue& queue, int modCount);
40         virtual ~_QueueEnumerator(void);
41
42         virtual Object* GetCurrent(void) const;
43         virtual result MoveNext(void);
44         virtual result Reset(void);
45
46 private:
47         const Queue& __queue;
48         int __modCount;
49         int __position;
50 };
51
52 _QueueEnumerator::_QueueEnumerator(const Queue& queue, int modCount)
53         : __queue(queue)
54         , __modCount(modCount)
55         , __position(-1)
56 {
57 }
58
59 _QueueEnumerator::~_QueueEnumerator(void)
60 {
61 }
62
63 Object*
64 _QueueEnumerator::GetCurrent(void) const
65 {
66         SysTryReturn(NID_BASE_COL, __modCount == __queue.__modCount, null, E_INVALID_OPERATION, "[%s] The source collection was modified after the creation of this enumerator.", GetErrorMessage(E_INVALID_OPERATION));
67         SysTryReturn(NID_BASE_COL, (__position >= __queue.__tail) && (__position < __queue.__head), null, E_INVALID_OPERATION, "[%s] Current position is before the first element or past the last element.", GetErrorMessage(E_INVALID_OPERATION));
68
69         SetLastResult(E_SUCCESS);
70         return __queue.__pObjArray[__position % __queue.__capacity];
71 }
72
73 result
74 _QueueEnumerator::MoveNext(void)
75 {
76         SysTryReturnResult(NID_BASE_COL, __modCount == __queue.__modCount, E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
77
78         if ((__position + 1) >= __queue.__head)
79         {
80                 return E_OUT_OF_RANGE;
81         }
82
83         if (__position == -1)
84         {
85                 __position = __queue.__tail;
86         }
87         else
88         {
89                 __position++;
90         }
91
92         return E_SUCCESS;
93 }
94
95 result
96 _QueueEnumerator::Reset(void)
97 {
98         SysTryReturnResult(NID_BASE_COL, __modCount == __queue.__modCount, E_INVALID_OPERATION, "The source collection was modified after the creation of this enumerator.");
99
100         __position = -1;
101         return E_SUCCESS;
102 }
103
104 Queue::Queue(void)
105         : __capacity(0)
106         , __head(0)
107         , __tail(0)
108         , __pObjArray(null)
109         , __modCount(0)
110         , __pQueueImpl(null)
111 {
112 }
113
114 Queue::~Queue(void)
115 {
116         __modCount++;
117
118         delete[] __pObjArray;
119 }
120
121 result
122 Queue::Construct(int capacity)
123 {
124         SysTryReturn(NID_BASE_COL, capacity >= 0, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument(s) is used. The capacity(%d) MUST be greater than or equal to 0.", GetErrorMessage(E_INVALID_ARG), capacity);
125
126         result r = E_SUCCESS;
127
128         if (capacity > 0)
129         {
130                 __pObjArray = new (std::nothrow) Object*[capacity];
131                 SysTryCatch(NID_BASE_COL, __pObjArray != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
132         }
133         __capacity = capacity;
134
135         return r;
136
137 CATCH:
138         return r;
139 }
140
141 result
142 Queue::Construct(const ICollection& collection)
143 {
144         result r = E_SUCCESS;
145         int count = collection.GetCount();
146         r = Construct(count);
147         SysTryReturnResult(NID_BASE_COL, r == E_SUCCESS, r, "Propagating.");
148
149         if (count > 0)
150         {
151                 std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
152                 SysTryCatch(NID_BASE_COL, pEnum != null, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
153
154                 while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
155                 {
156                         SysTryCatch(NID_BASE_COL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
157
158                         Object* pTemp = pEnum->GetCurrent();
159                         SysTryCatch(NID_BASE_COL, pTemp != null, r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
160
161                         __pObjArray[__head % __capacity] = pTemp;
162                         __head++;
163                 }
164         }
165
166         return E_SUCCESS;
167
168 CATCH:
169         delete[] __pObjArray;
170         __pObjArray = null;
171
172         return r;
173 }
174
175 Object*
176 Queue::Dequeue(void)
177 {
178         SysTryReturn(NID_BASE_COL, __head > __tail, null, E_UNDERFLOW, "[%s] Dequeue operation failed.", GetErrorMessage(E_UNDERFLOW));
179
180         __modCount++;
181
182         SetLastResult(E_SUCCESS);
183         return __pObjArray[(__tail++) % __capacity];
184 }
185
186 result
187 Queue::Enqueue(Object* pObj)
188 {
189         SysTryReturnResult(NID_BASE_COL, pObj != null, E_INVALID_ARG, "Invalid argument used. The pObj is null");
190
191         if (__pObjArray == null)
192         {
193                 __pObjArray = new (std::nothrow) Object*[DEFAULT_CAPACITY];
194                 SysTryReturnResult(NID_BASE_COL, __pObjArray != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
195
196                 __capacity = DEFAULT_CAPACITY;
197         }
198         else if ((__head - __tail) >= __capacity)
199         {
200                 Object** pNewArray = new (std::nothrow) Object*[__capacity + DEFAULT_CAPACITY];
201                 SysTryReturnResult(NID_BASE_COL, pNewArray != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
202                 for (int i = 0, j = __tail; i < __capacity; i++, j++)
203                 {
204                         pNewArray[i] = __pObjArray[j % __capacity];
205                 }
206
207                 delete[] __pObjArray;
208
209                 __pObjArray = pNewArray;
210                 __tail = 0;
211                 __head = __capacity;
212                 __capacity += DEFAULT_CAPACITY;
213         }
214
215         __modCount++;
216
217         __pObjArray[__head % __capacity] = pObj;
218         __head++;
219
220         return E_SUCCESS;
221 }
222
223 IEnumerator*
224 Queue::GetEnumeratorN(void) const
225 {
226         std::unique_ptr< _QueueEnumerator > pEnum(new (std::nothrow) _QueueEnumerator(*this, __modCount));
227         SysTryReturn(NID_BASE_COL, pEnum != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
228
229         SetLastResult(E_SUCCESS);
230         return pEnum.release();
231 }
232
233 const Object*
234 Queue::Peek(void) const
235 {
236         SysTryReturn(NID_BASE_COL, __head > __tail, null, E_UNDERFLOW, "[%s] Peek operation failed.", GetErrorMessage(E_UNDERFLOW));
237
238         SetLastResult(E_SUCCESS);
239         return __pObjArray[__tail % __capacity];
240 }
241
242 void
243 Queue::RemoveAll(bool deallocate)
244 {
245         __modCount++;
246         int count = GetCount();
247         for (int i = 0; i < count; i++)
248         {
249                 if (deallocate)
250                 {
251                         delete __pObjArray[(__tail + i) % __capacity];
252                 }
253
254                 __pObjArray[(__tail + i) % __capacity] = null;
255         }
256
257         __head = 0;
258         __tail = 0;
259 }
260
261 int
262 Queue::GetCount(void) const
263 {
264         return(__head - __tail);
265 }
266
267 bool
268 Queue::Contains(const Object& obj) const
269 {
270         int count = GetCount();
271         for (int i = 0; i < count; i++)
272         {
273                 if (__pObjArray[(__tail + i) % __capacity]->Equals(obj))
274                 {
275                         return true;
276                 }
277         }
278
279         return false;
280 }
281
282 bool
283 Queue::ContainsAll(const ICollection& collection) const
284 {
285         result r = E_SUCCESS;
286         SetLastResult(r);
287
288         std::unique_ptr< IEnumerator > pEnum(collection.GetEnumeratorN());
289         SysTryReturn(NID_BASE_COL, pEnum != null, false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
290
291         while ((r = pEnum->MoveNext()) != E_OUT_OF_RANGE)
292         {
293                 SysTryReturn(NID_BASE_COL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
294
295                 Object* pItem = pEnum->GetCurrent();
296                 SysTryReturn(NID_BASE_COL, pItem != null, false, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
297
298                 if (!Contains(*pItem))
299                 {
300                         return false;
301                 }
302         }
303
304         return true;
305 }
306
307 bool
308 Queue::Equals(const Object& obj) const
309 {
310         const Queue* pOther = dynamic_cast< const Queue* >(&obj);
311         if (pOther == null)
312         {
313                 return false;
314         }
315         else if (pOther == this)
316         {
317                 return true;
318         }
319         else if (GetCount() != pOther->GetCount())
320         {
321                 return false;
322         }
323         else
324         {
325                 int count = GetCount();
326                 for (int i = 0; i < count; i++)
327                 {
328                         if (!(__pObjArray[(__tail + i) % __capacity]->Equals(*(pOther->__pObjArray[(pOther->__tail + i) % pOther->__capacity]))))
329                         {
330                                 return false;
331                         }
332                 }
333         }
334
335         return true;
336 }
337
338 int
339 Queue::GetHashCode(void) const
340 {
341         int hash = 0;
342         int count = GetCount();
343         for (int i = 0; i < count; i++)
344         {
345                 if (__pObjArray[(__tail + i) % __capacity] != null)
346                 {
347                         hash += __pObjArray[(__tail + i) % __capacity]->GetHashCode();
348                 }
349         }
350         return hash;
351 }
352 }}}  // Tizen::Base::Collection