ArrayString.cpp 5.1 KB

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