Merge "Remove uniform hash" into devel/master
[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) 2021 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> // size_t
23 #include <cstdint> // uint32_t
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29 /**
30  * Utility class to reserve a buffer for storing messages.
31  */
32 class MessageBuffer
33 {
34 public:
35   using WordType = std::ptrdiff_t;
36
37   /**
38    * Create a new MessageBuffer
39    * @param[in] The smallest capacity which the buffer will allocate, with respect to the size of type "char".
40    * @note The buffer will not allocate memory until the first call to ReserveMessageSlot().
41    */
42   MessageBuffer(std::size_t initialCapacity);
43
44   /**
45    * Non-virtual destructor; not suitable as a base class
46    */
47   ~MessageBuffer();
48
49   /**
50    * Reserve space for another message in the buffer.
51    * @pre size is greater than zero.
52    * @param[in] size The message size with respect to the size of type "char".
53    * @return A pointer to the address allocated for the message, aligned to a word boundary
54    */
55   uint32_t* ReserveMessageSlot(std::size_t size);
56
57   /**
58    * Query the capacity of the message buffer.
59    * @return The capacity with respect to the size of type "char".
60    */
61   std::size_t GetCapacity() const;
62
63   /**
64    * Used to iterate though the messages in the buffer.
65    */
66   class Iterator
67   {
68   public:
69     // Constructor
70     Iterator(WordType* current);
71
72     // Inlined for performance
73     bool IsValid()
74     {
75       // Valid until end marker has been found
76       return 0 != mMessageSize;
77     }
78
79     // Inlined for performance
80     WordType* Get()
81     {
82       return (0 != mMessageSize) ? mCurrent : nullptr;
83     }
84
85     // Inlined for performance
86     void Next()
87     {
88       // Jump to next object and read size
89       mCurrent += mMessageSize;
90       mMessageSize = *mCurrent++;
91     }
92
93     // Copy constructor
94     Iterator(const Iterator& copy);
95
96   private:
97     // Undefined
98     Iterator& operator=(const Iterator& rhs);
99
100   private:
101     WordType*   mCurrent;
102     std::size_t mMessageSize;
103   };
104
105   /**
106    * Returns an iterator to the first message in the buffer.
107    * There is no past-the-end iterator; use Iterator::IsValid() to determine when the has been reached.
108    * @note Adding more messages with ReserveMessageSlot() may corrupt this iterator.
109    * @return The iterator.
110    */
111   Iterator Begin() const;
112
113   /**
114    * Sets the size of the buffer to zero (does not deallocate memory)
115    */
116   void Reset();
117
118 private:
119   // Undefined
120   MessageBuffer(const MessageBuffer&);
121
122   // Undefined
123   MessageBuffer& operator=(const MessageBuffer& rhs);
124
125   /**
126    * Helper to increase the capacity of the buffer.
127    * @pre The newCapacity is greater than mCapacity.
128    * @param[in] The newCapacity
129    */
130   void IncreaseCapacity(std::size_t newCapacity);
131
132 private:
133   std::size_t mInitialCapacity; ///< The capacity to allocate during first call to ReserveMessageSlot
134
135   WordType* mData;     ///< The data allocated for the message buffer
136   WordType* mNextSlot; ///< The next free location in the buffer
137
138   std::size_t mCapacity; ///< The memory allocated with respect to sizeof(WordType)
139   std::size_t mSize;     ///< The memory reserved for messages with respect to sizeof(WordType)
140 };
141
142 } // namespace Internal
143
144 } // namespace Dali
145
146 #endif // DALI_INTERNAL_MESSAGE_BUFFER_H