[dali_2.0.4] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / common / const-string.h
1 #ifndef DALI_INTERNAL_CONST_STRING_H
2 #define DALI_INTERNAL_CONST_STRING_H
3
4 /*
5  * Copyright (c) 2020 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 #include <string_view>
22
23 namespace Dali
24 {
25 namespace Internal
26 {
27 /**
28  * A uniqued constant string class.
29  *
30  * Provides an efficient way to store strings as uniqued strings. After the
31  * strings are uniqued, finding strings that are equal to one another is very
32  * fast as just the pointers need to be compared. It also allows for many
33  * common strings from many different sources to be shared to keep the memory
34  * footprint low.
35  *
36  * No reference counting is done on strings that are added to the string
37  * pool, once strings are added they are in the string pool for the life of
38  * the program.
39  */
40 class ConstString
41 {
42 public:
43   /**
44    * Default constructor
45    *
46    * Initializes the string to an empty string.
47    */
48   ConstString() = default;
49
50   explicit ConstString(std::string_view str);
51
52   /**
53    * Convert to bool operator.
54    *
55    * This allows code to check a ConstString object to see if it contains a
56    * valid string using code such as:
57    *
58    * \code
59    * ConstString str(...);
60    * if (str)
61    * { ...
62    * \endcode
63    *
64    * \return
65    *     /b True this object contains a valid non-empty C string, \b
66    *     false otherwise.
67    */
68   explicit operator bool() const
69   {
70     return !IsEmpty();
71   }
72
73   /**
74    * Equal to operator
75    *
76    * Returns true if this string is equal to the string in \a rhs. This
77    * operation is very fast as it results in a pointer comparison since all
78    * strings are in a uniqued in a global string pool.
79    *
80    * \param[in] rhs
81    *     Another string object to compare this object to.
82    *
83    * \return
84    *     true if this object is equal to \a rhs.
85    *     false if this object is not equal to \a rhs.
86    */
87   bool operator==(ConstString rhs) const
88   {
89     // We can do a pointer compare to compare these strings since they must
90     // come from the same pool in order to be equal.
91     return mString == rhs.mString;
92   }
93
94   /**
95    * Equal to operator against a non-ConstString value.
96    *
97    * Returns true if this string is equal to the string in \a rhs.
98    *
99    * \param[in] rhs
100    *     Another string object to compare this object to.
101    *
102    * \return
103    *     \b true if this object is equal to \a rhs.
104    *     \b false if this object is not equal to \a rhs.
105    */
106   bool operator==(const char* rhs) const
107   {
108     // ConstString differentiates between empty strings and nullptr strings, but
109     // StringRef doesn't. Therefore we have to do this check manually now.
110     if(mString == nullptr && rhs != nullptr)
111       return false;
112     if(mString != nullptr && rhs == nullptr)
113       return false;
114
115     return GetStringView() == rhs;
116   }
117
118   /**
119    * Not equal to operator
120    *
121    * Returns true if this string is not equal to the string in \a rhs. This
122    * operation is very fast as it results in a pointer comparison since all
123    * strings are in a uniqued in a global string pool.
124    *
125    * \param[in] rhs
126    *     Another string object to compare this object to.
127    *
128    * \return
129    *     \b true if this object is not equal to \a rhs.
130    *     \b false if this object is equal to \a rhs.
131    */
132   bool operator!=(ConstString rhs) const
133   {
134     return mString != rhs.mString;
135   }
136
137   /**
138    * Not equal to operator against a non-ConstString value.
139    *
140    * Returns true if this string is not equal to the string in \a rhs.
141    *
142    * \param[in] rhs
143    *     Another string object to compare this object to.
144    *
145    * \return \b true if this object is not equal to \a rhs, false otherwise.
146    */
147   bool operator!=(const char* rhs) const
148   {
149     return !(*this == rhs);
150   }
151
152   /**
153    * Get the string value as a std::string_view
154    *
155    * \return
156    *     Returns a new std::string_view object filled in with the
157    *     needed data.
158    */
159   std::string_view GetStringView() const
160   {
161     return mString ? std::string_view(mString, GetLength()) : std::string_view();
162   }
163
164   /**
165    * Get the string value as a C string.
166    *
167    * Get the value of the contained string as a NULL terminated C string
168    * value. This function will always return nullptr if the string is not valid.
169    *  So this function is a direct accessor to the string pointer value.
170    *
171    * \return
172    *     Returns nullptr the string is invalid, otherwise the C string
173    *     value contained in this object.
174    */
175   const char* GetCString() const
176   {
177     return mString;
178   }
179
180   /**
181    * Get the length in bytes of string value.
182    *
183    * The string pool stores the length of the string, so we can avoid calling
184    * strlen() on the pointer value with this function.
185    *
186    * \return
187    *     Returns the number of bytes that this string occupies in
188    *     memory, not including the NULL termination byte.
189    */
190   size_t GetLength() const;
191
192   /**
193    * Clear this object's state.
194    *
195    * Clear any contained string and reset the value to the empty string
196    * value.
197    */
198   void Clear()
199   {
200     mString = nullptr;
201   }
202
203   /**
204    * Test for empty string.
205    *
206    * \return
207    *     \b true if the contained string is empty.
208    *     \b false if the contained string is not empty.
209    */
210   bool IsEmpty() const
211   {
212     return mString == nullptr || mString[0] == '\0';
213   }
214
215   /**
216    * Set the string_view value.
217    *
218    * Set the string value in the object by uniquing the \a str string value
219    * in our global string pool.
220    *
221    * If the string is already exists in the global string pool, it finds the
222    * current entry and returns the existing value. If it doesn't exist, it is
223    * added to the string pool.
224    *
225    * \param[in] str
226    *     A string_view to add to the string pool.
227    */
228   void SetString(std::string_view str);
229
230 private:
231   const char* mString{nullptr};
232 };
233
234 } // namespace Internal
235
236 } // namespace Dali
237
238 #endif // DALI_INTERNAL_CONST_STRING_H