Max OS 0.3
Loading...
Searching...
No Matches
string.cpp
Go to the documentation of this file.
1
9#include <common/string.h>
10
11using namespace MaxOS;
12
17
18 // String that only contains the null terminator
19 m_length = 0;
20 allocate_self();
21 m_string[0] = '\0';
22
23
24}
25
31
32 // Create the memory
33 m_length = 1;
34 allocate_self();
35
36 // Store the char
37 m_string[0] = c;
38 m_string[m_length] = '\0';
39
40
41}
42
47String::String(char const* string) {
48
49 // Get the length of the string, prevent longer than 10000 because this should mean something's gone wrong
50 m_length = 0;
51 while (string[m_length] != '\0' && m_length <= 10000)
52 m_length++;
53 allocate_self();
54
55 // Copy the string
56 for (size_t i = 0; i < m_length; i++)
57 m_string[i] = string[i];
58
59 // If the length is more than 10,000 Replace the end with a warning incase future use actually requires that
60 const char* warning = "MAXOS: String length exceeded 10000 - might be a bug";
61 if (m_length > 10000)
62 for (int i = 0; i < 52; i++)
63 m_string[m_length - 52 + i] = warning[i];
64
65 m_string[m_length] = '\0';
66}
67
74String::String(uint8_t const* string, int length) {
75 // Allocate memory for the string (and null terminator)
76 m_length = length;
77 allocate_self();
78
79 // Copy the string
80 for (int i = 0; i < length; i++)
81 m_string[i] = string[i];
82
83 // Write the null terminator
84 m_string[length] = '\0';
85}
86
92String::String(int value) {
93
94 // Convert to a string
95 const char* str = itoa(10, value);
96 m_length = strlen(str);
97
98 // Create space to store
99 allocate_self();
100
101 // Store the string
102 for (size_t i = 0; i < m_length; i++)
103 m_string[i] = str[i];
104 m_string[m_length] = '\0';
105
106}
107
113String::String(uint64_t value) {
114
115 // Convert to a string
116 const char* str = htoa(value);
117 m_length = strlen(str);
118
119 // Create space to store
120 allocate_self();
121
122 // Store the string
123 for (size_t i = 0; i < m_length; i++)
124 m_string[i] = str[i];
125 m_string[m_length] = '\0';
126}
127
132String::String(bool value) {
133
134 if (value)
135 *this = string("true");
136 else
137 *this = string("false");
138
139}
140
146String::String(String const& other) {
147 copy(other);
148}
149
154
155 // Free the memory
156 if (!m_using_small)
157 delete[] m_string;
158
159}
160
166void String::copy(String const& other) {
167
168 // Allocate memory for the string (and null terminator)
169 m_length = other.length();
170 allocate_self();
171
172 // Copy the string
173 for (size_t i = 0; i < m_length; i++)
174 m_string[i] = other[i];
175
176 // Write the null terminator
177 m_string[m_length] = '\0';
178
179}
180
187int String::lex_value(String const& string) {
188
189 // Sum the ascii values of the characters in the string
190 int sum = 0;
191 for (size_t i = 0; i < string.length(); i++)
192 sum += string[i];
193
194 return sum;
195}
196
200void String::allocate_self() {
201
202 // Clear the old buffer if in use
203 if (m_string && !m_using_small)
204 delete[] m_string;
205
206 // Try to use the small string buffer
207 m_using_small = m_length + 1 <= MAX_STRING_SMALL_STORAGE;
208 m_string = m_using_small ? m_small_string : new char[m_length + 1];
209
210}
211
219
220 // Self assignment check
221 if (this == &other)
222 return *this;
223
224 // Copy the other string
225 copy(other);
226 return *this;
227}
228
235
236 return m_string;
237}
238
244const char* String::c_str() const {
245
246 return m_string;
247}
248
255bool String::starts_with(String const& other) {
256
257 // Must at least be able to fit the other string
258 if (m_length < other.length())
259 return false;
260
261 // Check if the string starts with the other string
262 for (size_t i = 0; i < other.length(); i++)
263 if (m_string[i] != other[i])
264 return false;
265
266 // No string left over to check so it must contain other
267 return true;
268}
269
277String String::substring(size_t start, size_t length) const {
278
279 // Ensure the start is within bounds
280 if (start >= m_length)
281 return { };
282
283 // Ensure the length is within bounds
284 if (start + length > m_length)
285 return { };
286
287 // Allocate memory for the substring (and null terminator)
289 substring.m_length = length;
290 substring.allocate_self();
291
292 // Copy the substring
293 for (size_t i = 0; i < length; i++)
294 substring.m_string[i] = m_string[start + i];
295
296 // Write the null terminator
297 substring.m_string[length] = '\0';
298
299 return substring;
300}
301
310
311 // Go through the string and split it by the delimiter
312 size_t start = 0;
313 for (size_t i = 0; i <= m_length - delimiter.length(); i++) {
314
315 // Check if matches at this position
316 bool matches = true;
317 for (size_t j = 0; j < delimiter.length(); j++)
318 if (m_string[i + j] != delimiter[j]) {
319 matches = false;
320 break;
321 }
322
323 if (!matches)
324 continue;
325
326 // Add the splice of the string
327 strings.push_back(substring(start, i - start));
328 start = i + delimiter.length();
329 i += delimiter.length() - 1;
330 }
331
332 // Add the last string to the vector
333 strings.push_back(substring(start, m_length - start));
334
335 return strings;
336}
337
344size_t String::length(bool count_ansi) const {
345
346 // If ansi characters are not to be counted
347 if (count_ansi)
348 return m_length;
349
350 // Calculate the length of the string without ansi characters
351 int total_length = 0;
352 int clean_length = 0;
353 while (m_string[total_length] != '\0') {
354
355 // If the character is an ansi character, skip it
356 if (m_string[total_length] == '\033')
357 while (m_string[total_length] != 'm')
358 total_length++;
359
360 // Increment the length
361 clean_length++;
362 total_length++;
363 }
364
365 // Return the length
366 return clean_length;
367}
368
375bool String::equals(String const& other) const {
376
377 // Check if the lengths are equal
378 if (m_length != other.length())
379 return false;
380
381 // Check if the characters are equal
382 for (size_t i = 0; i < m_length; i++)
383 if (m_string[i] != other[i])
384 return false;
385
386 // The strings are equal
387 return true;
388
389}
390
397bool String::operator ==(String const& other) const {
398
399 // Check if the strings are equal
400 return equals(other);
401}
402
409bool String::operator !=(String const& other) const {
410
411 // Self assignment check
412 if (*this == other)
413 return false;
414
415 return !equals(other);
416}
417
424bool String::operator <(String const& other) const {
425
426 return lex_value(*this) < lex_value(other);
427
428}
429
436bool String::operator >(String const& other) const {
437
438 return lex_value(*this) > lex_value(other);
439
440}
441
448bool String::operator <=(String const& other) const {
449
450 return lex_value(*this) <= lex_value(other);
451
452}
453
460bool String::operator >=(String const& other) const {
461
462 return lex_value(*this) >= lex_value(other);
463
464}
465
472String String::operator +(String const& other) const {
473
474 // The concatenated string
475 String concatenated;
476 concatenated.m_length = m_length + other.length();
477 concatenated.allocate_self();
478
479 // Copy the first string
480 for (size_t i = 0; i < m_length; i++)
481 concatenated.m_string[i] = m_string[i];
482
483 // Copy the second string
484 for (size_t i = 0; i < other.length(); i++)
485 concatenated.m_string[m_length + i] = other[i];
486
487 // Write the null terminator
488 concatenated.m_string[concatenated.m_length] = '\0';
489
490 // Return the concatenated string
491 return concatenated;
492}
493
501
502 // Add the other string to this string
503 String concatenated = *this + other;
504 copy(concatenated);
505 return *this;
506}
507
508
515char& String::operator [](size_t index) {
516 return m_string[index];
517}
518
519
526char& String::operator [](size_t index) const {
527 return m_string[index];
528}
529
536String String::operator *(int times) const {
537
538 // The repeated string
539 String repeated;
540 repeated.m_length = m_length * times;
541 repeated.allocate_self();
542
543 // Copy the string
544 for (int i = 0; i < times; i++)
545 for (size_t j = 0; j < m_length; j++)
546 repeated.m_string[i * m_length + j] = m_string[j];
547
548 // Write the null terminator
549 repeated.m_string[repeated.m_length] = '\0';
550
551 // Return the repeated string
552 return repeated;
553
554}
555
563String String::center(size_t width, char fill) const {
564
565 // The number of characters to add
566 size_t add = (width - m_length) / 2;
567
568 // The centered string
569 String centered;
570 centered.m_length = width;
571 centered.allocate_self();
572
573 // Fill the right side (before)
574 for (size_t i = 0; i < add; i++)
575 centered.m_string[i] = fill;
576
577 // Copy the string (middle)
578 for (size_t i = 0; i < m_length; i++)
579 centered.m_string[add + i] = m_string[i];
580
581 // Fill the left side (after)
582 for (size_t i = add + m_length; i < width; i++)
583 centered.m_string[i] = fill;
584
585 // Write the null terminator
586 centered.m_string[width] = '\0';
587
588 return centered;
589}
590
597String String::strip(char strip_char) const {
598
599 // The stripped string
600 String stripped;
601 stripped.copy(*this);
602
603 // Search from the back for the earliest non-whitespace character
604 size_t end = m_length - 1;
605 while (end >= 0 && (m_string[end] == strip_char || m_string[end] == '\n' || m_string[end] == '\t'))
606 end--;
607
608 // Make sure there is something to strip
609 if (end < 0)
610 return stripped;
611
612 // Split the string to remove the end
613 return stripped.substring(0, end + 1);
614}
615
624String String::formatted(char const* format, ...) {
625
626 // Create a pointer to the data
627 va_list parameters;
628 va_start(parameters, format);
629
630 return formatted(format, parameters);
631
632}
633
642String String::formatted(char const* format, va_list parameters) {
643
644 String out;
645
646 // Loop through the format string
647 for (; *format != '\0'; format++) {
648
649 // If it is not a %, print the character
650 if (*format != '%') {
651 out += (string) (char) (*format);
652 continue;
653 }
654
655 // Move to the next character
656 format++;
657 switch (*format) {
658 case 'd': {
659 // Print a decimal
660 int number = va_arg (parameters, int);
661 out += (string) (number);
662 break;
663 }
664 case 'x': {
665 // Print a hex
666 uint64_t number = va_arg (parameters, uint64_t);
667 out += (string) (number);
668 break;
669 }
670 case 's': {
671 // Print a string
672 char* str = va_arg (parameters, char*);
673 out += (string) (str);
674 break;
675 }
676 }
677 }
678
679 return out;
680
681}
682
689int strlen(const char* str) {
690 int len = 0;
691 for (; str[len] != '\0'; len++);
692 return len;
693}
694
703char* itoa(int base, int64_t number) {
704
705 // If there is no buffer use a default buffer
706 static char buffer[50] = { 0 };
707
708 int i = 49;
709 bool is_negative = number < 0;
710
711 // Null terminate the string
712 buffer[i] = '\0';
713 --i;
714
715 if (number == 0) {
716 buffer[i] = '0';
717 return &buffer[i];
718 }
719
720
721 for (; number && i; --i, number /= base)
722 buffer[i] = "0123456789ABCDEF"[number % base];
723
724 if (is_negative) {
725 buffer[i] = '-';
726 return &buffer[i];
727 }
728
729 return &buffer[i + 1];
730}
731
738char* htoa(uint64_t number) {
739 // If there is no buffer use a default buffer
740 static char buffer[50] = { 0 };
741 int i = 49;
742
743 // Null terminate the string
744 buffer[i] = '\0';
745 --i;
746
747 if (number == 0) {
748 buffer[i] = '0';
749 return &buffer[i];
750 }
751
752 for (; number && i; --i, number /= 16)
753 buffer[i] = "0123456789ABCDEF"[number % 16];
754
755 return &buffer[i + 1];
756}
757
765bool strcmp(char const* str1, char const* str2) {
766
767 // Check if the strings are equal
768 for (int i = 0; str1[i] != '\0' || str2[i] != '\0'; i++)
769 if (str1[i] != str2[i])
770 return false;
771
772 // The strings are equal
773 return true;
774
775}
776
784bool strcmp(char const* str1, String const& str2) {
785
786 // Use the other strcmp function
787 return strcmp(str1, str2.c_str());
788
789}
790
798bool strcmp(String const& str1, char const* str2) {
799
800 // Use the other strcmp function
801 return strcmp(str1.c_str(), str2);
802}
803
811bool strcmp(String const& str1, String const& str2) {
812
813 // Use the other strcmp function
814 return strcmp(str1.c_str(), str2.c_str());
815
816}
817
826bool strncmp(char const* str1, char const* str2, int length) {
827
828 // Check if the strings are equal
829 for (int i = 0; i < length; i++)
830 if (str1[i] != str2[i])
831 return false;
832
833 // Strings are equal
834 return true;
835
836}
837
846bool strncmp(char const* str1, String const& str2, int length) {
847
848 // Use the other strncmp function
849 return strncmp(str1, str2.c_str(), length);
850
851}
852
861bool strncmp(String const& str1, char const* str2, int length) {
862
863 // Use the other strncmp function
864 return strncmp(str1.c_str(), str2, length);
865
866}
867
876bool strncmp(String const& str1, String const& str2, int length) {
877
878 // Use the other strncmp function
879 return strncmp(str1.c_str(), str2.c_str(), length);
880}
881
889 out += string(str);
890 return *this;
891}
892
900 out += other;
901 return *this;
902}
903
911 out += string(value);
912 return *this;
913}
914
922 out += string(value);
923 return *this;
924}
925
933 out += string(value);
934 return *this;
935}
Creates a string using a using a combination of parts with the '<<' operator. Simmilar to the logger.
Definition string.h:97
StringBuilder & operator<<(char const *str)
Append C-string to the StringBuilder.
Definition string.cpp:888
String out
The output string.
Definition string.h:99
Dynamically sized string with various operations.
Definition string.h:26
String operator+(String const &other) const
Adds the other string to the string.
Definition string.cpp:472
bool operator>=(String const &other) const
Checks if the sum of the ascii values of the characters in the string is greater than or equal to the...
Definition string.cpp:460
bool operator<(String const &other) const
Checks if the sum of the ascii values of the characters in the string is less than the sum of the asc...
Definition string.cpp:424
bool operator==(String const &other) const
Checks if one string is equal to another.
Definition string.cpp:397
String strip(char strip_char=' ') const
Strips the string of whitespace.
Definition string.cpp:597
bool operator<=(String const &other) const
Checks if the sum of the ascii values of the characters in the string is less than or equal to the su...
Definition string.cpp:448
static String formatted(char const *format,...)
Creates a formated string. s = string, x = hex, d = decimal.
Definition string.cpp:624
bool operator>(String const &other) const
Checks if the sum of the ascii values of the characters in the string is greater than the sum of the ...
Definition string.cpp:436
String center(size_t width, char fill=' ') const
Centers the string in a specified width.
Definition string.cpp:563
void copy(String const &other)
Copies the other string.
Definition string.cpp:166
common::Vector< String > split(String const &delimiter) const
Splits the string by the delimiter.
Definition string.cpp:308
String substring(size_t start, size_t length) const
Get a section of the string.
Definition string.cpp:277
size_t length(bool count_ansi=true) const
Returns the length of the string.
Definition string.cpp:344
String()
Construct a String, 0 length and only contains the null terminator.
Definition string.cpp:16
bool starts_with(String const &other)
Checks if the string starts with the other string (must contain the same characters in the same order...
Definition string.cpp:255
String & operator=(String const &other)
Sets the string to the other string.
Definition string.cpp:218
String operator*(int times) const
Returns the string repeated a number of times.
Definition string.cpp:536
bool equals(String const &other) const
Checks if one string is equal to another.
Definition string.cpp:375
bool operator!=(String const &other) const
Checks if one string is not equal to another.
Definition string.cpp:409
~String()
Destructor for the string, cleans up memory if needed.
Definition string.cpp:153
String & operator+=(String const &other)
Adds the other string to the string.
Definition string.cpp:500
char * c_str()
The char pointer representation of the current string.
Definition string.cpp:234
char & operator[](size_t index)
Returns the character at the specified index.
Definition string.cpp:515
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
Defines a String class for dynamically sized strings with various operations.
char * itoa(int base, int64_t number)
Converts integer to string.
Definition string.cpp:703
constexpr int MAX_STRING_SMALL_STORAGE
How many characters can be stored in the small string optimization array.
Definition string.h:20
class MaxOS::String string
Typedef for String.
bool strcmp(char const *str1, char const *str2)
Checks if one string pointer is equal to another string pointer.
Definition string.cpp:765
bool strncmp(char const *str1, char const *str2, int length)
Checks if one string pointer is equal to another string pointer up to a specified length (each must b...
Definition string.cpp:826
char * htoa(uint64_t number)
Converts hex to string.
Definition string.cpp:738
int strlen(const char *str)
Gets the length of a string.
Definition string.cpp:689