ArrayString.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "core/utils/ArrayString.hpp"
  2. #include <limits.h>
  3. #include <stdlib.h>
  4. #include <uchar.h>
  5. #include "core/data/Array.hpp"
  6. #include "core/math/Math.hpp"
  7. #include "core/utils/Error.hpp"
  8. #include "core/utils/Utility.hpp"
  9. using BufferString = Core::BufferString;
  10. using Error = Core::Error;
  11. constexpr size_t stringLength(const c32* c) {
  12. const c32* i = c + 1;
  13. while(*(c++) != '\0') {}
  14. return static_cast<size_t>(c - i);
  15. }
  16. using C32Buffer = Core::Array<char, MB_LEN_MAX + 1>;
  17. static C32Buffer convertC32(c32 c) {
  18. C32Buffer buffer;
  19. size_t n = c32rtomb(buffer.begin(), c, nullptr);
  20. if(n >= buffer.getLength()) {
  21. buffer[0] = '?';
  22. buffer[1] = '\0';
  23. } else {
  24. buffer[n] = '\0';
  25. }
  26. return buffer;
  27. }
  28. BufferString::BufferString(char* buffer, size_t bufferSize)
  29. : length(0), capacity(bufferSize <= 0 ? 0 : bufferSize - 1), data(buffer) {
  30. data[0] = '\0';
  31. }
  32. BufferString& BufferString::operator=(const BufferString& other) {
  33. clear();
  34. other.toString(*this);
  35. return *this;
  36. }
  37. bool BufferString::operator==(const char* s) const {
  38. return strcmp(data, s) == 0;
  39. }
  40. bool BufferString::operator==(const BufferString& other) const {
  41. return length == other.length && strcmp(data, other.data) == 0;
  42. }
  43. bool BufferString::operator!=(const char* s) const {
  44. return !((*this) == s);
  45. }
  46. bool BufferString::operator!=(const BufferString& other) const {
  47. return !((*this) == other);
  48. }
  49. char BufferString::operator[](size_t index) const {
  50. return data[index];
  51. }
  52. size_t BufferString::getLength() const {
  53. return length;
  54. }
  55. size_t BufferString::getCapacity() const {
  56. return capacity;
  57. }
  58. BufferString& BufferString::append(char c) {
  59. if(length < capacity) {
  60. data[length++] = c;
  61. data[length] = '\0';
  62. }
  63. return *this;
  64. }
  65. BufferString& BufferString::append(signed char c) {
  66. return append(static_cast<char>(c));
  67. }
  68. BufferString& BufferString::append(unsigned char c) {
  69. return append(static_cast<char>(c));
  70. }
  71. BufferString& BufferString::append(wchar_t c) {
  72. return append(static_cast<c32>(c));
  73. }
  74. BufferString& BufferString::append(c32 c) {
  75. return append(static_cast<const char*>(convertC32(c).begin()));
  76. }
  77. BufferString& BufferString::append(const char* s) {
  78. // stringLength as s could be some part of data
  79. for(size_t i = strlen(s); i > 0; i--) {
  80. append(*(s++));
  81. }
  82. return *this;
  83. }
  84. BufferString& BufferString::append(const c32* s) {
  85. // stringLength as s could be some part of data
  86. for(size_t i = stringLength(s); i > 0; i--) {
  87. append(*(s++));
  88. }
  89. return *this;
  90. }
  91. BufferString& BufferString::append(const signed char* s) {
  92. return append(reinterpret_cast<const char*>(s));
  93. }
  94. BufferString& BufferString::append(const unsigned char* s) {
  95. return append(reinterpret_cast<const char*>(s));
  96. }
  97. BufferString& BufferString::append(bool b) {
  98. return b ? append("true") : append("false");
  99. }
  100. void BufferString::toString(BufferString& s) const {
  101. size_t l = length; // length changes if &s == this
  102. for(size_t i = 0; i < l; i++) {
  103. s.append(data[i]);
  104. }
  105. }
  106. void BufferString::clear() {
  107. length = 0;
  108. data[0] = '\0';
  109. }
  110. void BufferString::print() const {
  111. Core::print(data);
  112. }
  113. void BufferString::printLine() const {
  114. Core::printLine(data);
  115. }
  116. bool BufferString::startsWith(const BufferString& other, size_t from) const {
  117. return length >= from + other.getLength() &&
  118. strncmp(data + from, other.data, other.getLength()) == 0;
  119. }
  120. size_t BufferString::search(const BufferString& other, size_t from) const {
  121. char* f = strstr(data + from, other.data);
  122. return f == nullptr ? SIZE_MAX : static_cast<size_t>(f - data);
  123. }
  124. bool BufferString::contains(const BufferString& other, size_t from) const {
  125. return search(other, from) != SIZE_MAX;
  126. }
  127. size_t BufferString::search(char u, size_t from) const {
  128. char* f = strchr(data + from, u);
  129. return f == nullptr ? SIZE_MAX : static_cast<size_t>(f - data);
  130. }
  131. bool BufferString::contains(char u, size_t from) const {
  132. return search(u, from) != SIZE_MAX;
  133. }
  134. void BufferString::substring(BufferString& s, size_t from, size_t to) const {
  135. s.clear();
  136. to = Math::min(to + 1, length);
  137. for(size_t i = from; i < to; i++) {
  138. s.append(data[i]);
  139. }
  140. }
  141. void BufferString::substring(BufferString& s, size_t from) const {
  142. substring(s, from, length - 1);
  143. }
  144. void BufferString::replace(BufferString& s, const BufferString& search,
  145. const BufferString& replace) {
  146. size_t i = 0;
  147. while(i < length) {
  148. if(startsWith(search, i)) {
  149. s.append(replace);
  150. i += search.getLength();
  151. } else {
  152. s.append(data[i]);
  153. i++;
  154. }
  155. }
  156. *this = s;
  157. }
  158. void BufferString::replace(char search, char replace) {
  159. for(size_t i = 0; i < length; i++) {
  160. if(data[i] == search) {
  161. data[i] = replace;
  162. }
  163. }
  164. }
  165. BufferString::operator const char*() const {
  166. return data;
  167. }