1 /*
2  *  Copyright (c) 2021, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for `Heap::String` (a heap allocated string).
32  */
33 
34 #ifndef HEAP_STRING_HPP_
35 #define HEAP_STRING_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/equatable.hpp"
40 #include "common/error.hpp"
41 #include "common/heap.hpp"
42 
43 namespace ot {
44 namespace Heap {
45 
46 /**
47  * Represents a heap allocated string.
48  *
49  * The buffer to store the string is allocated from heap and is managed by the `Heap::String` class itself, e.g., it may
50  * be reused and/or freed and reallocated when the string is set. The `Heap::String` destructor will always free the
51  * allocated buffer.
52  *
53  */
54 class String : public Unequatable<String>
55 {
56 public:
57     /**
58      * Initializes the `String` as null (or empty).
59      *
60      */
String(void)61     String(void)
62         : mStringBuffer(nullptr)
63     {
64     }
65 
66     /**
67      * This is the move constructor for `String`.
68      *
69      * `String` is non-copyable (copy constructor is deleted) but move constructor is provided to allow it to to be
70      * used as return type (return by value) from functions/methods (which will then use move semantics).
71      *
72      */
String(String && aString)73     String(String &&aString)
74         : mStringBuffer(aString.mStringBuffer)
75     {
76         aString.mStringBuffer = nullptr;
77     }
78 
79     /**
80      * This is the destructor for `HealString` object
81      *
82      */
~String(void)83     ~String(void) { Free(); }
84 
85     /**
86      * Indicates whether or not the `String` is null (i.e., it was never successfully set or it was
87      * freed).
88      *
89      * @retval TRUE  The `String` is null.
90      * @retval FALSE The `String` is not null.
91      *
92      */
IsNull(void) const93     bool IsNull(void) const { return (mStringBuffer == nullptr); }
94 
95     /**
96      * Returns the `String` as a C string.
97      *
98      * @returns A pointer to C string buffer or `nullptr` if the `String` is null (never set or freed).
99      *
100      */
AsCString(void) const101     const char *AsCString(void) const { return mStringBuffer; }
102 
103     /**
104      * Sets the string from a given C string.
105      *
106      * @param[in] aCString   A pointer to c string buffer. Can be `nullptr` which then frees the `String`.
107      *
108      * @retval kErrorNone     Successfully set the string.
109      * @retval kErrorNoBufs   Failed to allocate buffer for string.
110      *
111      */
112     Error Set(const char *aCString);
113 
114     /**
115      * Sets the string from another `String`.
116      *
117      * @param[in] aString   The other `String` to set from.
118      *
119      * @retval kErrorNone     Successfully set the string.
120      * @retval kErrorNoBufs   Failed to allocate buffer for string.
121      *
122      */
Set(const String & aString)123     Error Set(const String &aString) { return Set(aString.AsCString()); }
124 
125     /**
126      * Sets the string from another `String`.
127      *
128      * @param[in] aString     The other `String` to set from (rvalue reference using move semantics).
129      *
130      * @retval kErrorNone     Successfully set the string.
131      * @retval kErrorNoBufs   Failed to allocate buffer for string.
132      *
133      */
134     Error Set(String &&aString);
135 
136     /**
137      * Frees any buffer allocated by the `String`.
138      *
139      * The `String` destructor will automatically call `Free()`. This method allows caller to free buffer
140      * explicitly.
141      *
142      */
143     void Free(void);
144 
145     /**
146      * Overloads operator `==` to evaluate whether or not the `String` is equal to a given C string.
147      *
148      * @param[in]  aCString  A C string to compare with. Can be `nullptr` which then checks if `String` is null.
149      *
150      * @retval TRUE   If the two strings are equal.
151      * @retval FALSE  If the two strings are not equal.
152      *
153      */
154     bool operator==(const char *aCString) const;
155 
156     /**
157      * Overloads operator `!=` to evaluate whether or not the `String` is unequal to a given C string.
158      *
159      * @param[in]  aCString  A C string to compare with. Can be `nullptr` which then checks if `String` is not null.
160      *
161      * @retval TRUE   If the two strings are not equal.
162      * @retval FALSE  If the two strings are equal.
163      *
164      */
operator !=(const char * aCString) const165     bool operator!=(const char *aCString) const { return !(*this == aCString); }
166 
167     /**
168      * Overloads operator `==` to evaluate whether or not two `String` are equal.
169      *
170      * @param[in]  aString  The other string to compare with.
171      *
172      * @retval TRUE   If the two strings are equal.
173      * @retval FALSE  If the two strings are not equal.
174      *
175      */
operator ==(const String & aString) const176     bool operator==(const String &aString) const { return (*this == aString.AsCString()); }
177 
178     String(const String &)            = delete;
179     String &operator=(const String &) = delete;
180 
181 private:
182     char *mStringBuffer;
183 };
184 
185 } // namespace Heap
186 } // namespace ot
187 
188 #endif // HEAP_STRING_HPP_
189