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