Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file lib.BaseString.hpp | ||
3 | * @author Sergey Baigudin, sergey@baigudin.software | ||
4 | * @copyright 2017-2022, Sergey Baigudin, Baigudin Software | ||
5 | */ | ||
6 | #ifndef LIB_BASESTRING_HPP_ | ||
7 | #define LIB_BASESTRING_HPP_ | ||
8 | |||
9 | #include "lib.AbstractBaseString.hpp" | ||
10 | |||
11 | namespace eoos | ||
12 | { | ||
13 | namespace lib | ||
14 | { | ||
15 | |||
16 | /** | ||
17 | * @class BaseString<T,L,R,A> | ||
18 | * @brief Static base string class. | ||
19 | * | ||
20 | * Primary template implements the static string class. | ||
21 | * | ||
22 | * @tparam T A data type of string characters. | ||
23 | * @tparam L A maximum number of string characters, or 0 for dynamic allocation. | ||
24 | * @tparam R A character traits. | ||
25 | * @tparam A A heap memory allocator class. | ||
26 | */ | ||
27 | template <typename T, int32_t L, class R = CharTrait<T>, class A = Allocator> | ||
28 | class BaseString : public AbstractBaseString<T,R,A> | ||
29 | { | ||
30 | typedef AbstractBaseString<T,R,A> Parent; | ||
31 | |||
32 | public: | ||
33 | |||
34 | using Parent::isConstructed; | ||
35 | using Parent::convert; | ||
36 | |||
37 | /** | ||
38 | * @brief Constructor. | ||
39 | */ | ||
40 | 44 | BaseString() | |
41 | 44 | : AbstractBaseString<T,R,A>() { | |
42 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
44 | bool_t const isConstructed( construct() ); |
43 | 44 | setConstructed( isConstructed ); | |
44 | 44 | } | |
45 | |||
46 | /** | ||
47 | * @brief Constructor. | ||
48 | * | ||
49 | * @param source A source object interface. | ||
50 | */ | ||
51 | 10 | BaseString(api::String<T> const& source) | |
52 | 10 | : AbstractBaseString<T,R,A>() { | |
53 |
2/4✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
|
10 | bool_t const isConstructed( construct( source.getChar() ) ); |
54 | 10 | setConstructed( isConstructed ); | |
55 | 10 | } | |
56 | |||
57 | /** | ||
58 | * @brief Constructor. | ||
59 | * | ||
60 | * @param source A source character string. | ||
61 | */ | ||
62 | 216 | BaseString(T const* const source) | |
63 | 216 | : AbstractBaseString<T,R,A>() { | |
64 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
216 | bool_t const isConstructed( construct( source ) ); |
65 | 216 | setConstructed( isConstructed ); | |
66 | 216 | } | |
67 | |||
68 | /** | ||
69 | * @brief Constructor. | ||
70 | * | ||
71 | * @param value A source numerical value. | ||
72 | * @param base A numerical base used to represent a value as this string. | ||
73 | */ | ||
74 | 34 | explicit BaseString(int32_t const value, Number::Base const base = Number::BASE_10) | |
75 | 34 | : AbstractBaseString<T,R,A>() { | |
76 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
34 | bool_t isConstructed( construct() ); |
77 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
34 | if( isConstructed ) |
78 | { | ||
79 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
34 | isConstructed = convert(value, base); |
80 | } | ||
81 | 34 | setConstructed( isConstructed ); | |
82 | 34 | } | |
83 | |||
84 | /** | ||
85 | * @brief Destructor. | ||
86 | */ | ||
87 | 324 | virtual ~BaseString() | |
88 | { | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * @copydoc eoos::Object::Object(Object const&) | ||
93 | */ | ||
94 | 18 | BaseString(BaseString const& obj) ///< SCA MISRA-C++:2008 Justified Rule 12-8-1 | |
95 | 18 | : AbstractBaseString<T,R,A>(obj) { | |
96 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
18 | bool_t const isConstructed( construct( obj.getChar() ) ); |
97 | 18 | setConstructed( isConstructed ); | |
98 | 18 | } | |
99 | |||
100 | /** | ||
101 | * @copydoc eoos::Object::operator=(Object const&) | ||
102 | */ | ||
103 | 3 | BaseString& operator=(BaseString const& obj) | |
104 | { | ||
105 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 | if( isConstructed() && (this != &obj) ) |
106 | { | ||
107 | 3 | copyRaw3(str_, obj.str_, L); | |
108 | 3 | Parent::operator=(obj); | |
109 | } | ||
110 | 3 | return *this; | |
111 | } | ||
112 | |||
113 | #if EOOS_CPP_STANDARD >= 2011 | ||
114 | |||
115 | /** | ||
116 | * @copydoc eoos::Object::Object(Object&&) | ||
117 | */ | ||
118 | 1 | BaseString(BaseString&& obj) noexcept | |
119 | 1 | : AbstractBaseString<T,R,A>( move(obj) ) { | |
120 | 1 | copyRaw3(str_, obj.str_, L); | |
121 | 1 | } | |
122 | |||
123 | /** | ||
124 | * @copydoc eoos::Object::operator=(Object&&) | ||
125 | */ | ||
126 | 22 | BaseString& operator=(BaseString&& obj) & noexcept | |
127 | { | ||
128 |
5/6✓ Branch 1 taken 10 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 1 times.
|
22 | if( isConstructed() && (this != &obj) ) |
129 | { | ||
130 | 20 | copyRaw3(str_, obj.str_, L); | |
131 | 20 | Parent::operator=( move(obj) ); | |
132 | } | ||
133 | 22 | return *this; | |
134 | } | ||
135 | |||
136 | #endif // EOOS_CPP_STANDARD >= 2011 | ||
137 | |||
138 | /** | ||
139 | * @copydoc eoos::api::Collection::getLength() | ||
140 | */ | ||
141 | 292 | virtual size_t getLength() const | |
142 | { | ||
143 | 292 | size_t length( 0U ); | |
144 |
2/2✓ Branch 1 taken 116 times.
✓ Branch 2 taken 30 times.
|
292 | if( isConstructed() ) |
145 | { | ||
146 | // @todo Rework here not to calculate length, but take it form a class member. | ||
147 | 232 | length = getLengthRaw(str_); | |
148 | } | ||
149 | 292 | return length; | |
150 | } | ||
151 | |||
152 | /** | ||
153 | * @copydoc eoos::api::String::getChar() | ||
154 | */ | ||
155 | 594 | virtual T const* getChar() const | |
156 | { | ||
157 | 594 | T const* str( NULLPTR ); | |
158 |
2/2✓ Branch 1 taken 275 times.
✓ Branch 2 taken 22 times.
|
594 | if( isConstructed() ) |
159 | { | ||
160 | 550 | str = str_; | |
161 | } | ||
162 | 594 | return str; | |
163 | } | ||
164 | |||
165 | protected: | ||
166 | |||
167 | using Parent::setConstructed; | ||
168 | using Parent::getLengthRaw; | ||
169 | using Parent::copyRaw3; | ||
170 | using Parent::concatenateRaw3; | ||
171 | using Parent::isEqualRaw2; | ||
172 | |||
173 | private: | ||
174 | |||
175 | /** | ||
176 | * @copydoc eoos::lib::AbstractBaseString::copyRaw(T const*) | ||
177 | */ | ||
178 | 442 | virtual bool_t copyRaw(T const* const str) | |
179 | { | ||
180 | 442 | bool_t res( false ); | |
181 |
3/6✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 221 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 221 times.
✗ Branch 6 not taken.
|
442 | if( isConstructed() && (str != NULLPTR) ) |
182 | { | ||
183 | 442 | copyRaw3(str_, str, L); | |
184 | 442 | res = true; | |
185 | } | ||
186 | 442 | return res; | |
187 | } | ||
188 | |||
189 | /** | ||
190 | * @copydoc eoos::lib::AbstractBaseString::concatenate(T const*) | ||
191 | */ | ||
192 | 24 | virtual bool_t concatenateRaw(T const* const str) | |
193 | { | ||
194 | 24 | bool_t res( false ); | |
195 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
24 | if( isConstructed() && (str != NULLPTR) ) |
196 | { | ||
197 | 24 | concatenateRaw3(str_, str, L); | |
198 | 24 | res = true; | |
199 | } | ||
200 | 24 | return res; | |
201 | |||
202 | } | ||
203 | |||
204 | /** | ||
205 | * @copydoc eoos::lib::AbstractBaseString::isEqualToRaw(T const*) | ||
206 | */ | ||
207 | 24 | virtual bool_t isEqualToRaw(T const* const str) const | |
208 | { | ||
209 | 24 | bool_t res( false ); | |
210 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
24 | if( isConstructed() && (str != NULLPTR) ) |
211 | { | ||
212 | 24 | res = isEqualRaw2(str_, str); | |
213 | } | ||
214 | 24 | return res; | |
215 | |||
216 | } | ||
217 | |||
218 | /** | ||
219 | * @brief Constructs this object. | ||
220 | * | ||
221 | * @param str A string to be copied on construction. | ||
222 | * @return True if this object has been constructed successfully. | ||
223 | */ | ||
224 | 322 | bool_t construct(T const* const str = NULLPTR) | |
225 | { | ||
226 | 322 | str_[0] = R::getTerminator(); | |
227 | 322 | bool_t res( false ); | |
228 | do | ||
229 | { | ||
230 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 160 times.
|
322 | if( !isConstructed() ) |
231 | { | ||
232 | 2 | break; | |
233 | } | ||
234 |
3/4✓ Branch 0 taken 121 times.
✓ Branch 1 taken 39 times.
✓ Branch 3 taken 121 times.
✗ Branch 4 not taken.
|
320 | res = ( str == NULLPTR ) ? true : copyRaw(str); |
235 | } while(false); | ||
236 | 322 | return res; | |
237 | } | ||
238 | |||
239 | |||
240 | /** | ||
241 | * @brief The buffer of characters of this string. | ||
242 | */ | ||
243 | T str_[L + 1]; | ||
244 | |||
245 | }; | ||
246 | |||
247 | #ifdef EOOS_ENABLE_DYNAMIC_HEAP_MEMORY | ||
248 | |||
249 | /** | ||
250 | * @class BaseString<T,0,R,A> | ||
251 | * @brief Dynamic base string class. | ||
252 | * | ||
253 | * Partial specialization of the template implements the dynamic string class. | ||
254 | * | ||
255 | * @tparam T Data type of string characters. | ||
256 | * @tparam R A character traits. | ||
257 | * @tparam A Heap memory allocator class. | ||
258 | */ | ||
259 | template <typename T, class R, class A> | ||
260 | class BaseString<T,0,R,A> : public AbstractBaseString<T,R,A> | ||
261 | { | ||
262 | typedef AbstractBaseString<T,R,A> Parent; | ||
263 | |||
264 | public: | ||
265 | |||
266 | using Parent::isConstructed; | ||
267 | using Parent::convert; | ||
268 | |||
269 | /** | ||
270 | * @brief Constructor. | ||
271 | */ | ||
272 | 22 | BaseString() | |
273 | : AbstractBaseString<T,R,A>() | ||
274 | 22 | , len_(0) | |
275 | 22 | , str_(NULLPTR){ | |
276 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | bool_t const isConstructed( construct() ); |
277 | 22 | setConstructed( isConstructed ); | |
278 | 22 | } | |
279 | |||
280 | /** | ||
281 | * @brief Constructor. | ||
282 | * | ||
283 | * @param source A source object interface. | ||
284 | */ | ||
285 | 3 | BaseString(api::String<T> const& source) | |
286 | : AbstractBaseString<T,R,A>() | ||
287 | 3 | , len_(0) | |
288 | 3 | , str_(NULLPTR){ | |
289 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | bool_t const isConstructed( construct( source.getChar() ) ); |
290 | 3 | setConstructed( isConstructed ); | |
291 | 3 | } | |
292 | |||
293 | /** | ||
294 | * @brief Constructor. | ||
295 | * | ||
296 | * @param source A source character string. | ||
297 | */ | ||
298 | 109 | BaseString(T const* const source) | |
299 | : AbstractBaseString<T,R,A>() | ||
300 | 109 | , len_(0) | |
301 | 109 | , str_(NULLPTR){ | |
302 |
1/2✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
|
109 | bool_t const isConstructed( construct( source ) ); |
303 | 109 | setConstructed( isConstructed ); | |
304 | 109 | } | |
305 | |||
306 | /** | ||
307 | * @brief Constructor. | ||
308 | * | ||
309 | * @param value A source numerical value. | ||
310 | * @param base A numerical base used to represent a value as this string. | ||
311 | */ | ||
312 | 11 | explicit BaseString(int32_t const value, Number::Base const base = Number::BASE_10) | |
313 | : AbstractBaseString<T,R,A>() | ||
314 | 11 | , len_(0) | |
315 | 11 | , str_(NULLPTR){ | |
316 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | bool_t isConstructed( construct() ); |
317 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if( isConstructed ) |
318 | { | ||
319 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | isConstructed = convert(value, base); |
320 | } | ||
321 | 11 | setConstructed( isConstructed ); | |
322 | 11 | } | |
323 | |||
324 | /** | ||
325 | * @brief Destructor. | ||
326 | */ | ||
327 | 308 | virtual ~BaseString() | |
328 | { | ||
329 | 308 | free(); | |
330 | } | ||
331 | |||
332 | /** | ||
333 | * @copydoc eoos::Object::Object(Object const&) | ||
334 | */ | ||
335 | 9 | BaseString(BaseString const& obj) ///< SCA MISRA-C++:2008 Justified Rule 12-8-1 | |
336 | : AbstractBaseString<T,R,A>(obj) | ||
337 | 9 | , len_(0) | |
338 | 9 | , str_(NULLPTR){ | |
339 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | bool_t const isConstructed( construct( obj.getChar() ) ); |
340 | 9 | setConstructed( isConstructed ); | |
341 | 9 | } | |
342 | |||
343 | /** | ||
344 | * @copydoc eoos::Object::operator=(Object const&) | ||
345 | */ | ||
346 | 3 | BaseString& operator=(BaseString const& obj) | |
347 | { | ||
348 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
3 | if( isConstructed() && (this != &obj) ) |
349 | { | ||
350 | 3 | static_cast<void>( copyRaw( obj.getChar() ) ); | |
351 | 3 | Parent::operator=(obj); | |
352 | } | ||
353 | 3 | return *this; | |
354 | } | ||
355 | |||
356 | #if EOOS_CPP_STANDARD >= 2011 | ||
357 | |||
358 | /** | ||
359 | * @copydoc eoos::Object::Object(Object&&) | ||
360 | */ | ||
361 | 1 | BaseString(BaseString&& obj) noexcept | |
362 | 1 | : AbstractBaseString<T,R,A>( move(obj) ) | |
363 | 1 | , len_(obj.len_) | |
364 | 1 | , str_(obj.str_){ | |
365 | 1 | obj.clean(); | |
366 | 1 | } | |
367 | |||
368 | /** | ||
369 | * @copydoc eoos::Object::operator=(Object&&) | ||
370 | */ | ||
371 | 11 | BaseString& operator=(BaseString&& obj) & noexcept | |
372 | { | ||
373 |
5/6✓ Branch 1 taken 10 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 1 times.
|
11 | if( isConstructed() && (this != &obj) ) |
374 | { | ||
375 | 10 | free(); | |
376 | 10 | len_ = obj.len_; | |
377 | 10 | str_ = obj.str_; | |
378 | 10 | obj.clean(); | |
379 | 10 | Parent::operator=( move(obj) ); | |
380 | } | ||
381 | 11 | return *this; | |
382 | } | ||
383 | |||
384 | #endif // EOOS_CPP_STANDARD >= 2011 | ||
385 | |||
386 | /** | ||
387 | * @copydoc eoos::api::Collection::getLength() | ||
388 | */ | ||
389 | 146 | virtual size_t getLength() const | |
390 | { | ||
391 | 146 | size_t length( 0U ); | |
392 |
2/2✓ Branch 1 taken 116 times.
✓ Branch 2 taken 30 times.
|
146 | if( isConstructed() ) |
393 | { | ||
394 | // @todo Rework here not to calculate length, but take it form a class member. | ||
395 | 116 | length = getLengthRaw(str_); | |
396 | } | ||
397 | 146 | return length; | |
398 | } | ||
399 | |||
400 | /** | ||
401 | * @copydoc eoos::api::String::getChar() | ||
402 | */ | ||
403 | 289 | virtual T const* getChar() const | |
404 | { | ||
405 | 289 | T const* str( NULLPTR ); | |
406 |
2/2✓ Branch 1 taken 266 times.
✓ Branch 2 taken 23 times.
|
289 | if( isConstructed() ) |
407 | { | ||
408 | 266 | str = str_; | |
409 | } | ||
410 | 289 | return str; | |
411 | } | ||
412 | |||
413 | protected: | ||
414 | |||
415 | using Parent::setConstructed; | ||
416 | using Parent::getLengthRaw; | ||
417 | using Parent::copyRaw3; | ||
418 | using Parent::concatenateRaw3; | ||
419 | using Parent::isEqualRaw2; | ||
420 | |||
421 | private: | ||
422 | |||
423 | /** | ||
424 | * @copydoc eoos::lib::AbstractBaseString::copyRaw(T const*) | ||
425 | */ | ||
426 | 216 | virtual bool_t copyRaw(T const* const str) | |
427 | { | ||
428 | 216 | bool_t res( false ); | |
429 |
5/6✓ Branch 1 taken 216 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 215 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 215 times.
✓ Branch 6 taken 1 times.
|
216 | if( isConstructed() && (str != NULLPTR) ) |
430 | { | ||
431 | 215 | size_t const length( getLengthRaw(str) ); | |
432 | 215 | bool_t isPrepared( prepareCopy(length) ); | |
433 |
1/2✓ Branch 0 taken 215 times.
✗ Branch 1 not taken.
|
215 | if( isPrepared ) |
434 | { | ||
435 | 215 | copyRaw3(str_, str, len_); | |
436 | 215 | res = true; | |
437 | } | ||
438 | } | ||
439 | 216 | return res; | |
440 | } | ||
441 | |||
442 | /** | ||
443 | * @copydoc eoos::lib::AbstractBaseString::concatenate(T const*) | ||
444 | */ | ||
445 | 12 | virtual bool_t concatenateRaw(T const* const str) | |
446 | { | ||
447 | 12 | bool_t res( false ); | |
448 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | if( isConstructed() && (str != NULLPTR) ) |
449 | { | ||
450 | 12 | size_t const length( getLength() + getLengthRaw(str) ); | |
451 | 12 | bool_t isPrepared( prepareConcatenate(length) ); | |
452 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | if( isPrepared ) |
453 | { | ||
454 | 12 | concatenateRaw3(str_, str, len_); | |
455 | 12 | res = true; | |
456 | } | ||
457 | } | ||
458 | 12 | return res; | |
459 | |||
460 | } | ||
461 | |||
462 | /** | ||
463 | * @copydoc eoos::lib::AbstractBaseString::isEqualToRaw(T const*) | ||
464 | */ | ||
465 | 12 | virtual bool_t isEqualToRaw(T const* const str) const | |
466 | { | ||
467 | 12 | bool_t res( false ); | |
468 |
3/6✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
12 | if( isConstructed() && (str != NULLPTR) ) |
469 | { | ||
470 | 12 | res = isEqualRaw2(str_, str); | |
471 | } | ||
472 | 12 | return res; | |
473 | |||
474 | } | ||
475 | |||
476 | /** | ||
477 | * @brief Constructs this object. | ||
478 | * | ||
479 | * @param str A string to be copied on construction. | ||
480 | * @return True if this object has been constructed successfully. | ||
481 | */ | ||
482 | 154 | bool_t construct(T const* const str = NULLPTR) | |
483 | { | ||
484 | 154 | bool_t res( false ); | |
485 | do | ||
486 | { | ||
487 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 152 times.
|
154 | if( !isConstructed() ) |
488 | { | ||
489 | 1 | break; | |
490 | } | ||
491 | 153 | size_t length( LENGTH_ON_CONSTRUCTION ); | |
492 |
2/2✓ Branch 0 taken 119 times.
✓ Branch 1 taken 33 times.
|
153 | if( str != NULLPTR ) |
493 | { | ||
494 | 120 | length = getLengthRaw(str); | |
495 | } | ||
496 | 153 | bool_t isAllocated( allocate(length) ); | |
497 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 151 times.
|
153 | if( !isAllocated ) |
498 | { | ||
499 | 2 | break; | |
500 | } | ||
501 |
3/4✓ Branch 0 taken 118 times.
✓ Branch 1 taken 33 times.
✓ Branch 3 taken 118 times.
✗ Branch 4 not taken.
|
151 | res = ( str == NULLPTR ) ? true : copyRaw(str); |
502 | } while(false); | ||
503 | 154 | return res; | |
504 | } | ||
505 | |||
506 | /** | ||
507 | * @brief Prepare this string for a new length to copy. | ||
508 | * | ||
509 | * @param length A number of string characters. | ||
510 | * @return True if the the string is prepared. | ||
511 | */ | ||
512 | 215 | bool_t prepareCopy(size_t length) | |
513 | { | ||
514 | 215 | bool_t res(true); | |
515 |
2/2✓ Branch 1 taken 33 times.
✓ Branch 2 taken 182 times.
|
215 | if( !isFit(length) ) |
516 | { | ||
517 | 33 | free(); | |
518 | 33 | res = allocate(length); | |
519 | } | ||
520 | 215 | return res; | |
521 | } | ||
522 | |||
523 | /** | ||
524 | * @brief Prepare this string for a new length to copy. | ||
525 | * | ||
526 | * @param length A number of string characters. | ||
527 | * @return True if the the string is prepared. | ||
528 | */ | ||
529 | 12 | bool_t prepareConcatenate(size_t length) | |
530 | { | ||
531 | 12 | bool_t res(true); | |
532 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 1 times.
|
12 | if( !isFit(length) ) |
533 | { | ||
534 | // @todo Refactor this implementation to make it be more clear. | ||
535 | 11 | T* const str( str_ ); | |
536 | 11 | size_t const len( len_ ); | |
537 | 11 | clean(); | |
538 | 11 | res = allocate(length); | |
539 |
1/2✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
|
11 | if( res ) |
540 | { | ||
541 | 11 | copyRaw3(str_, str, len); | |
542 | } | ||
543 | 11 | A::free(str); | |
544 | } | ||
545 | 12 | return res; | |
546 | } | ||
547 | |||
548 | /** | ||
549 | * @brief Allocates memory for a string. | ||
550 | * | ||
551 | * @param length A number of string characters. | ||
552 | * @return True if the context has been allocated successfully. | ||
553 | */ | ||
554 | 197 | bool_t allocate(size_t const length) | |
555 | { | ||
556 | 197 | bool_t res( false ); | |
557 |
2/4✓ Branch 0 taken 196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 196 times.
✗ Branch 3 not taken.
|
197 | if( (str_ == NULLPTR) && (length != 0U) ) |
558 | { | ||
559 | 197 | size_t const size( calculateSize(length) ); | |
560 | 197 | T* const string( reinterpret_cast<T*>( A::allocate(size) ) ); | |
561 |
2/2✓ Branch 0 taken 195 times.
✓ Branch 1 taken 1 times.
|
197 | if(string != NULLPTR) |
562 | { | ||
563 | 195 | str_ = string; | |
564 | 195 | len_ = length; | |
565 | 195 | str_[0] = R::getTerminator(); | |
566 | 195 | res = true; | |
567 | } | ||
568 | } | ||
569 | 197 | return res; | |
570 | } | ||
571 | |||
572 | /** | ||
573 | * @brief Frees this contex. | ||
574 | */ | ||
575 | 198 | void free() | |
576 | { | ||
577 |
2/2✓ Branch 0 taken 184 times.
✓ Branch 1 taken 13 times.
|
198 | if(str_ != NULLPTR) |
578 | { | ||
579 | 184 | A::free(str_); | |
580 | 184 | str_ = NULLPTR; | |
581 | 184 | len_ = 0U; | |
582 | } | ||
583 | 198 | } | |
584 | |||
585 | /** | ||
586 | * @brief Cleans this contex. | ||
587 | */ | ||
588 | 22 | void clean() | |
589 | { | ||
590 | 22 | str_ = NULLPTR; | |
591 | 22 | len_ = 0U; | |
592 | 22 | } | |
593 | |||
594 | /** | ||
595 | * @brief Returns size in byte for a string length. | ||
596 | * | ||
597 | * @param len A number of string characters. | ||
598 | * @return Size in byte for a passed string. | ||
599 | */ | ||
600 | 197 | static size_t calculateSize(size_t len) | |
601 | { | ||
602 | 197 | return (len * sizeof(T)) + sizeof(T); | |
603 | } | ||
604 | |||
605 | /** | ||
606 | * @brief Tests if a passed length fits to allocated available length. | ||
607 | * | ||
608 | * @param len A number of string characters. | ||
609 | * @return True if this length will be fit successfully. | ||
610 | */ | ||
611 | 227 | bool_t isFit(size_t len) const ///< SCA MISRA-C++:2008 Justified Rule 2-10-2 | |
612 | { | ||
613 | 227 | return len <= len_; | |
614 | } | ||
615 | |||
616 | /** | ||
617 | * @brief Lenght of the buffer of characters on construction. | ||
618 | * | ||
619 | * @note Cannot be zero. | ||
620 | */ | ||
621 | static const size_t LENGTH_ON_CONSTRUCTION = 7U; | ||
622 | |||
623 | /** | ||
624 | * @brief Lenght of the buffer of characters of this string. | ||
625 | */ | ||
626 | size_t len_; | ||
627 | |||
628 | /** | ||
629 | * @brief The buffer of characters of this string. | ||
630 | * | ||
631 | * @todo Refactor this to be array on construction, | ||
632 | * and if new assigned string is more than LENGTH_ON_CONSTRUCTION, | ||
633 | * allocate a new array dynamically. To implement this approach and | ||
634 | * reduce size of the class object, revise using a `union` type. | ||
635 | */ | ||
636 | T* str_; | ||
637 | }; | ||
638 | |||
639 | #endif // EOOS_ENABLE_DYNAMIC_HEAP_MEMORY | ||
640 | |||
641 | /** | ||
642 | * @brief Concatenates two strings. | ||
643 | * | ||
644 | * @param source1 A source object 1. | ||
645 | * @param source2 A source object 2. | ||
646 | * @return This string object with the concatenated strings. | ||
647 | */ | ||
648 | template <typename T, int32_t L, class R, class A> | ||
649 | 2 | inline BaseString<T,L,R,A> operator+(BaseString<T,L,R,A> const& source1, BaseString<T,L,R,A> const& source2) | |
650 | { | ||
651 | 2 | BaseString<T,L,R,A> string(source1); | |
652 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | string += source2; |
653 | 2 | return string; | |
654 | } | ||
655 | |||
656 | /** | ||
657 | * @brief Concatenates two strings. | ||
658 | * | ||
659 | * @param source1 A source object 1. | ||
660 | * @param source2 A source object interface 2. | ||
661 | * @return This string object with the concatenated strings. | ||
662 | */ | ||
663 | template <typename T, int32_t L, class R, class A> | ||
664 | 2 | inline BaseString<T,L,R,A> operator+(BaseString<T,L,R,A> const& source1, api::String<T> const& source2) | |
665 | { | ||
666 | 2 | BaseString<T,L,R,A> string(source1); | |
667 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | string += source2; |
668 | 2 | return string; | |
669 | } | ||
670 | |||
671 | /** | ||
672 | * @brief Concatenates two strings. | ||
673 | * | ||
674 | * @param source1 A source object interface 1. | ||
675 | * @param source2 A source object 2. | ||
676 | * @return This string object with the concatenated strings. | ||
677 | */ | ||
678 | template <typename T, int32_t L, class R, class A> | ||
679 | 2 | inline BaseString<T,L,R,A> operator+(api::String<T> const& source1, BaseString<T,L,R,A> const& source2) | |
680 | { | ||
681 | 2 | BaseString<T,L,R,A> string(source1); | |
682 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | string += source2; |
683 | 2 | return string; | |
684 | } | ||
685 | |||
686 | /** | ||
687 | * @brief Concatenates two strings. | ||
688 | * | ||
689 | * @param source1 A source object 1. | ||
690 | * @param source2 A source character string 2. | ||
691 | * @return This string object with the concatenated strings. | ||
692 | */ | ||
693 | template <typename T, int32_t L, class R, class A> | ||
694 | 2 | inline BaseString<T,L,R,A> operator+(BaseString<T,L,R,A> const& source1, T const* const source2) | |
695 | { | ||
696 | 2 | BaseString<T,L,R,A> string(source1); | |
697 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | string += source2; |
698 | 2 | return string; | |
699 | } | ||
700 | |||
701 | /** | ||
702 | * @brief Concatenates two strings. | ||
703 | * | ||
704 | * @param source1 A source character string 1. | ||
705 | * @param source2 A source object 2. | ||
706 | * @return This string object with the concatenated strings. | ||
707 | */ | ||
708 | template <typename T, int32_t L, class R, class A> | ||
709 | 2 | inline BaseString<T,L,R,A> operator+(T const* const source1, BaseString<T,L,R,A> const& source2) | |
710 | { | ||
711 | 2 | BaseString<T,L,R,A> string(source1); | |
712 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | string += source2; |
713 | 2 | return string; | |
714 | } | ||
715 | |||
716 | } // namespace lib | ||
717 | } // namespace eoos | ||
718 | #endif // LIB_BASESTRING_HPP_ | ||
719 |