Conversion to Apache 2.0 license
[platform/core/uifw/dali-core.git] / dali / public-api / common / dali-vector.cpp
1 /*
2  * Copyright (c) 2014 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 // CLASS HEADER
19 #include <dali/public-api/common/dali-vector.h>
20
21 // EXTERNAL INCLUDES
22 #include <stdlib.h>
23 #include <memory.h>
24
25 namespace Dali
26 {
27
28 VectorBase::VectorBase()
29   : mData( NULL )
30 {
31 }
32
33 VectorBase::~VectorBase()
34 {
35 }
36
37 VectorBase::SizeType VectorBase::Capacity() const
38 {
39   SizeType capacity = 0;
40   if( mData )
41   {
42     SizeType* metadata = reinterpret_cast< SizeType* >( mData );
43     capacity = *(metadata - 2);
44   }
45   return capacity;
46 }
47
48
49 void VectorBase::Release()
50 {
51   if( mData )
52   {
53     // adjust pointer to real beginning
54     SizeType* metadata = reinterpret_cast< SizeType* >( mData );
55     // TODO would be nice to memset to a bitpattern to catch illegal use of container after release
56     // but that would require knowledge of the itemsize
57     free( metadata - 2 );
58     mData = 0;
59   }
60 }
61
62 void VectorBase::SetCount( SizeType count )
63 {
64   // Setcount is internal so should not be called on empty vector
65   DALI_ASSERT_DEBUG( mData && "Vector is empty" );
66   SizeType* metadata = reinterpret_cast< SizeType* >( mData );
67   *(metadata - 1) = count;
68 }
69
70 void VectorBase::Reserve( SizeType capacity, SizeType elementSize )
71 {
72   SizeType oldCapacity = Capacity();
73   SizeType oldCount = Count();
74   if( capacity > oldCapacity )
75   {
76     const SizeType wholeAllocation = sizeof(SizeType) * 2 + capacity * elementSize;
77     void* wholeData = (void*)malloc( wholeAllocation );
78 #if defined( DEBUG_ENABLED )
79     // in debug build this will help identify a vector of uninitialized data
80     memset( wholeData, 0xaa, wholeAllocation );
81 #endif
82     SizeType* metaData = reinterpret_cast< SizeType* >( wholeData );
83     *metaData++ = capacity;
84     *metaData++ = oldCount;
85     if( mData )
86     {
87       // copy over the old data
88       memcpy( metaData, mData, oldCount * elementSize );
89       // release old buffer
90       Release();
91     }
92     mData = metaData;
93   }
94 }
95
96 void VectorBase::Copy( const VectorBase& vector, SizeType elementSize )
97 {
98   if( this != &vector )
99   {
100     // release old data
101     Release();
102     // reserve space based on source capacity
103     const SizeType capacity = vector.Capacity();
104     Reserve( capacity, elementSize );
105     // copy over whole data
106     const SizeType wholeAllocation = sizeof(SizeType) * 2 + capacity * elementSize;
107     SizeType* srcData = reinterpret_cast< SizeType* >( vector.mData );
108     SizeType* dstData = reinterpret_cast< SizeType* >( mData );
109     memcpy( dstData - 2, srcData - 2, wholeAllocation );
110   }
111 }
112
113 void VectorBase::Swap( VectorBase& vector )
114 {
115   // just swap the data pointers, metadata will swap as side effect
116   std::swap( mData, vector.mData );
117 }
118
119 void VectorBase::Erase( char* address, SizeType elementSize )
120 {
121   char* startAddress = address + elementSize;
122   const char* endAddress = reinterpret_cast< char* >( mData ) + Count() * elementSize;
123   SizeType numberOfBytes = endAddress - startAddress;
124   // addresses overlap so use memmove
125   memmove( address, startAddress, numberOfBytes );
126   SetCount( Count() - 1 );
127 }
128
129 } // namespace Dali
130