Merge "[devel_3.0_main] Cherry-pick Beautified source code of appfw/inc. 80914" into...
[platform/framework/native/appfw.git] / src / base / FBaseBufferBase.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                FBaseBufferBase.cpp
19  * @brief               This is the implementation for BufferBase class.
20  */
21 #include <stdlib.h>
22 #include <string.h>
23 #include <math.h>
24 #include <FBaseBufferBase.h>
25 #include <FBaseSysLog.h>
26
27 namespace Tizen { namespace Base
28 {
29
30 BufferBase::BufferBase(void)
31         : _capacity(0)
32         , _position(0)
33         , _limit(0)
34         , _mark(-1)
35         , _pData(null)
36         , __pArrayStart(null)
37         , __pBufferBaseImpl(null)
38 {
39 }
40
41 BufferBase::~BufferBase(void)
42 {
43         if ((_pData != null) && (Release() == 0))
44         {
45                 free(_pData);
46                 _pData = null;
47         }
48 }
49
50 result
51 BufferBase::Construct(int capacity)
52 {
53         SysTryReturn(NID_BASE, capacity >= 0, E_INVALID_ARG, E_INVALID_ARG,
54                 "[%s] Invalid argument is used. The capacity is negative", GetErrorMessage(E_INVALID_ARG));
55
56         result r = E_SUCCESS;
57         void* pTemp = null;
58
59         // check whether the size of memory is larger than the maximum of unsigned int
60         unsigned long long size = static_cast< unsigned long long >(sizeof(_BufferData)) +
61                 static_cast< unsigned long long >(capacity) * static_cast< unsigned long long >(GetTypeSize());
62         SysTryReturnResult(NID_BASE, size <= static_cast< unsigned long long >((unsigned int) -1), E_OUT_OF_MEMORY,
63                 "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
64
65         pTemp = malloc(static_cast< unsigned int >(size));
66         SysTryReturnResult(NID_BASE, 0 != pTemp, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.",
67                 GetErrorMessage(E_OUT_OF_MEMORY));
68
69         memset(pTemp, 0, static_cast< unsigned int >(size));
70
71         _pData = static_cast< _BufferData* >(pTemp);
72
73         _pData->refCount = 1;
74         _pData->capacityInByte = capacity * GetTypeSize();
75
76         _capacity = capacity;
77         _limit = capacity;
78
79         if (capacity > 0)
80         {
81                 __pArrayStart = _pData->GetArray();
82         }
83
84         return r;
85 }
86
87 void
88 BufferBase::Clear(void)
89 {
90         _position = 0;
91         _limit = _capacity;
92         _mark = -1;
93 }
94
95 void
96 BufferBase::Compact(void)
97 {
98         int remaining = GetRemaining();
99         if (HasRemaining() && (0 != _position))
100         {
101                 int offset = _position * GetTypeSize();
102                 int byteNum = remaining * GetTypeSize();
103                 for (int i = 0; i < byteNum; i++)
104                 {
105                         __pArrayStart[i] = __pArrayStart[offset + i];
106                 }
107         }
108         _position = remaining;
109         _mark = -1;
110         _limit = _capacity;
111 }
112
113 void
114 BufferBase::Flip(PositionTo to)
115 {
116         _limit = _position;
117         if ((to == POSITION_TO_MARK) && (_mark > -1))
118         {
119                 _position = _mark;
120         }
121         else
122         {
123                 _position = 0;
124                 _mark = -1;
125         }
126 }
127
128 int
129 BufferBase::GetHashCode(void) const
130 {
131         int len = (GetRemaining() * GetTypeSize()) / sizeof(len);
132
133         // s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
134         int hash = 0;
135         int offset = _position * GetTypeSize();
136         for (int i = 0; i < len; ++i)
137         {
138                 hash += (int) __pArrayStart[offset + (i * sizeof(hash))] * (int) pow((double) 31, len - (i + 1));
139         }
140
141         return hash;
142 }
143
144 void
145 BufferBase::InvalidateMark(void)
146 {
147         _mark = -1;
148 }
149
150 result
151 BufferBase::Reset(void)
152 {
153         SysTryReturnResult(NID_BASE, _mark >= 0, E_INVALID_OPERATION, "[%s] The mark has not been set.",
154                 GetErrorMessage(E_INVALID_OPERATION));
155
156         _position = _mark;
157         return E_SUCCESS;
158 }
159
160 void
161 BufferBase::Rewind(void)
162 {
163         _position = 0;
164         _mark = -1;
165 }
166
167 result
168 BufferBase::ShiftLimit(int amount)
169 {
170         SysTryReturnResult(NID_BASE, (((_limit + amount) <= _capacity) && ((_limit + amount) >= 0)), E_OUT_OF_RANGE,
171                 "The amount(%d) is larger than the capacity(%d), or smaller than zero starting from the current limit(%d).",
172                 amount, _capacity, _limit);
173
174         return SetLimit(_limit + amount);
175 }
176
177 int
178 BufferBase::GetCapacity(void) const
179 {
180         return _capacity;
181 }
182
183 int
184 BufferBase::GetLimit(void) const
185 {
186         return _limit;
187 }
188
189 int
190 BufferBase::GetMark(void) const
191 {
192         return _mark;
193 }
194
195 int
196 BufferBase::GetPosition(void) const
197 {
198         return _position;
199 }
200
201 int
202 BufferBase::GetRemaining(void) const
203 {
204         return _limit - _position;
205 }
206
207 result
208 BufferBase::SetLimit(int limit)
209 {
210         SysTryReturnResult(NID_BASE, limit <= _capacity && limit >= 0, E_OUT_OF_RANGE,
211                 "The limit(%d) MUST be greater than or equal to 0 and less than the current capacity(%d).", limit, _capacity);
212
213         if (limit != _limit)
214         {
215                 _limit = limit;
216                 if (_position > limit)
217                 {
218                         _position = limit;
219                         if (_mark > limit)
220                         {
221                                 _mark = -1;
222                         }
223                 }
224         }
225         return E_SUCCESS;
226 }
227
228 void
229 BufferBase::SetMark(void)
230 {
231         _mark = _position;
232 }
233
234 result
235 BufferBase::SetPosition(int position)
236 {
237         SysTryReturnResult(NID_BASE, position <= _limit && position >= 0, E_OUT_OF_RANGE,
238                 "The position(%d) MUST be greater than or equal to 0 and less than the current limit(%d).", position, _limit);
239
240         _position = position;
241         if (_mark > _position)
242         {
243                 _mark = -1;
244         }
245
246         return E_SUCCESS;
247 }
248
249 bool
250 BufferBase::HasRemaining(void) const
251 {
252         return _limit > _position;
253 }
254
255 result
256 BufferBase::ExpandCapacity(int newCapacity)
257 {
258         SysTryReturnResult(NID_BASE, newCapacity > _capacity, E_INVALID_ARG,
259                 "The capacity is less than the current capacity.");
260
261         // check whether the size of memory is larger than the maximum of unsigned int
262         unsigned long long size = static_cast< unsigned long long >(sizeof(_BufferData)) +
263                 static_cast< unsigned long long >(newCapacity) * static_cast< unsigned long long >(GetTypeSize());
264
265         SysTryReturnResult(NID_BASE, size <= static_cast< unsigned long long >((unsigned int) -1), E_OUT_OF_MEMORY,
266                 "Memory allocation failed.");
267
268         _pData = static_cast< _BufferData* >(realloc(_pData, static_cast< unsigned int >(size)));
269         SysTryReturnResult(NID_BASE, 0 != _pData, E_OUT_OF_MEMORY, "Memory allocation failed.");
270
271         _capacity = newCapacity;
272         _limit = newCapacity;
273
274         __pArrayStart = _pData->GetArray();
275
276         return E_SUCCESS;
277 }
278
279 long
280 BufferBase::AddRef(void) const
281 {
282         SysAssertf(_pData->refCount > 0, "refCount(%d) is not greater than zero.", _pData->refCount);
283
284         _pData->refCount++;
285
286         return _pData->refCount;
287 }
288
289 long
290 BufferBase::Release(void) const
291 {
292         SysAssertf(_pData->refCount > 0, "refCount is not greater than zero(impossible!).");
293
294         _pData->refCount--;
295
296         return _pData->refCount;
297 }
298
299 void
300 BufferBase::Dispose(void)
301 {
302 }
303
304 BufferBase::_BufferData::_BufferData()
305         : capacityInByte(0)
306         , refCount(0)
307 {
308 }
309
310 BufferBase::_BufferData::~_BufferData()
311 {
312 }
313
314 byte*
315 BufferBase::_BufferData::GetArray(void)
316 {
317         return reinterpret_cast< byte* >(this + 1);
318 }
319
320 }} // Tizen::Base