Merge "Ensured that messages are aligned to 8 byte words on 64bit ARM" into tizen
[platform/core/uifw/dali-core.git] / dali / internal / common / message-buffer.h
1 #ifndef __DALI_INTERNAL_MESSAGE_BUFFER_H__
2 #define __DALI_INTERNAL_MESSAGE_BUFFER_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstddef>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 /**
31  * Utility class to reserve a buffer for storing messages.
32  */
33 class MessageBuffer
34 {
35 public:
36   typedef std::ptrdiff_t WordType;
37
38   /**
39    * Create a new MessageBuffer
40    * @param[in] The smallest capacity which the buffer will allocate, with respect to the size of type "char".
41    * @note The buffer will not allocate memory until the first call to ReserveMessageSlot().
42    */
43   MessageBuffer( std::size_t initialCapacity );
44
45   /**
46    * Non-virtual destructor; not suitable as a base class
47    */
48   ~MessageBuffer();
49
50   /**
51    * Reserve space for another message in the buffer.
52    * @pre size is greater than zero.
53    * @param[in] size The message size with respect to the size of type "char".
54    * @return A pointer to the address allocated for the message, aligned to a word boundary
55    */
56   unsigned int* ReserveMessageSlot( std::size_t size );
57
58   /**
59    * Query the capacity of the message buffer.
60    * @return The capacity with respect to the size of type "char".
61    */
62   std::size_t GetCapacity() const;
63
64   /**
65    * Used to iterate though the messages in the buffer.
66    */
67   class Iterator
68   {
69   public:
70
71     // Constructor
72     Iterator(WordType* current);
73
74     // Inlined for performance
75     bool IsValid()
76     {
77       // Valid until end marker has been found
78       return 0 != mMessageSize;
79     }
80
81     // Inlined for performance
82     WordType* Get()
83     {
84       return ( 0 != mMessageSize ) ? mCurrent : NULL;
85     }
86
87     // Inlined for performance
88     void Next()
89     {
90       // Jump to next object and read size
91       mCurrent += mMessageSize;
92       mMessageSize = *mCurrent++;
93     }
94
95     // Copy constructor
96     Iterator(const Iterator& copy);
97
98   private:
99
100     // Undefined
101     Iterator& operator=(const Iterator& rhs);
102
103   private:
104
105     WordType* mCurrent;
106     std::size_t mMessageSize;
107   };
108
109   /**
110    * Returns an iterator to the first message in the buffer.
111    * There is no past-the-end iterator; use Iterator::IsValid() to determine when the has been reached.
112    * @note Adding more messages with ReserveMessageSlot() may corrupt this iterator.
113    * @return The iterator.
114    */
115   Iterator Begin() const;
116
117   /**
118    * Sets the size of the buffer to zero (does not deallocate memory)
119    */
120   void Reset();
121
122 private:
123
124   // Undefined
125   MessageBuffer(const MessageBuffer&);
126
127   // Undefined
128   MessageBuffer& operator=(const MessageBuffer& rhs);
129
130   /**
131    * Helper to increase the capacity of the buffer.
132    * @pre The newCapacity is greater than mCapacity.
133    * @param[in] The newCapacity
134    */
135   void IncreaseCapacity( std::size_t newCapacity );
136
137 private:
138
139   std::size_t mInitialCapacity; ///< The capacity to allocate during first call to ReserveMessageSlot
140
141   WordType* mData;     ///< The data allocated for the message buffer
142   WordType* mNextSlot; ///< The next free location in the buffer
143
144   std::size_t mCapacity; ///< The memory allocated with respect to sizeof(WordType)
145   std::size_t mSize;     ///< The memory reserved for messages with respect to sizeof(WordType)
146 };
147
148 } // namespace Internal
149
150 } // namespace Dali
151
152 #endif // __DALI_INTERNAL_MESSAGE_BUFFER_H__