Advertisement
bobmarley12345

StringBuilder.h

Aug 23rd, 2021
914
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.97 KB | None | 0 0
  1. #ifndef __STRING_BUILDER
  2. #define __STRING_BUILDER
  3.  
  4. #include <stdlib.h>
  5. #include <math.h>
  6. // sd https://github.com/AngryCarrot789/REghZyIOWrapper
  7. // A buffer than autoresizes itself, and supports appending strings and integers
  8. class StringBuilder {
  9. public:
  10.     static inline int stringlen(const char* str, int startIndex) {
  11.         int c = 0;
  12.         while (str[startIndex++] != 0) { c++; }
  13.         return c;
  14.     }
  15.  
  16.     static int intlen(const char* str, int startIndex) {
  17.         int count = 0;
  18.         char c = str[startIndex++];
  19.         while (c >= '0' && c <= '9') {
  20.             count++;
  21.             c = str[startIndex++];
  22.         }
  23.         return count;
  24.     }
  25.  
  26.     int stoi(const char* str, int len, int startIndex) {
  27.         int i = 0, j = startIndex, end = j + len;
  28.         while (j < end) {
  29.             i = (i * 10) + (str[j++] - '0');
  30.         }
  31.         return i;
  32.     }
  33.  
  34.     int itostr(int value, char* str, int startIndex) {
  35.         int i = ((int)log10((double)value)) + startIndex;
  36.         int len = 0;
  37.         while (value > 0) {
  38.             str[i--] = ((value % 10) + '0');
  39.             value = value / 10;
  40.             len++;
  41.         }
  42.         return len;
  43.     }
  44.  
  45.     void charset(char* buf, int value, int len) {
  46.         for (int i = 0; i < len; i++) {
  47.             buf[i] = value;
  48.         }
  49.     }
  50.  
  51.     // Creates an empty StringBuilder with the given capacity
  52.     StringBuilder(int capacity) {
  53.         mCapacity = capacity;
  54.         mNextIndex = 0;
  55.         createCapacityBuffer();
  56.         setLastAsNull();
  57.     }
  58.  
  59.     // Creates a StringBuilder, and appends the given char array (with the given size (srcLen)) to this stringbuilder
  60.     StringBuilder(const char* src, int srcLen, int capacity) {
  61.         mCapacity = capacity;
  62.         mNextIndex = srcLen;
  63.         createCapacityBuffer();
  64.         for (int i = 0; i < srcLen; i++) {
  65.             mBuffer[i] = src[i];
  66.         }
  67.  
  68.         setLastAsNull();
  69.     }
  70.  
  71.     // Creates a StringBuilder, and concatinates 2 char arrays
  72.     StringBuilder(const char* a, const int lenA, const char* b, const int lenB) {
  73.         mCapacity = (lenA + lenB);
  74.         mNextIndex = 0;
  75.         createCapacityBuffer();
  76.         for (int i = 0; i < lenA; i++) {
  77.             mBuffer[i] = a[i];
  78.         }
  79.         for (int i = lenA, j = 0; i < lenB; i++, j++) {
  80.             mBuffer[i] = b[j];
  81.         }
  82.  
  83.         setLastAsNull();
  84.     }
  85.  
  86.     // Creates a StringBuilder, and appends the given string
  87.     StringBuilder(const char* src) {
  88.         int len = stringlen(src, 0);
  89.         mCapacity = len;
  90.         mNextIndex = len;
  91.         createCapacityBuffer();
  92.         for (int i = 0; i < len; i++) {
  93.             mBuffer[i] = src[i];
  94.         }
  95.         setLastAsNull();
  96.     }
  97.  
  98.     // Appends a substring of the given char array (starting at the startIndex (inclusive) and ending at the endIndex (exclusive). Similar to java's substring)
  99.     StringBuilder& appendSubstring(const char* str, int startIndex, int endIndex) {
  100.         ensureBufferSize(endIndex - startIndex);
  101.         for (int i = startIndex; i < endIndex; i++) {
  102.             mBuffer[mNextIndex++] = str[i];
  103.         }
  104.  
  105.         return ref();
  106.     }
  107.  
  108.     // Appends a string (with the given size) to this StringBuilder
  109.     StringBuilder& appendString(const char* str, int len) {
  110.         ensureBufferSize(len);
  111.         for (int i = 0; i < len; i++) {
  112.             mBuffer[mNextIndex++] = str[i];
  113.         }
  114.  
  115.         return ref();
  116.     }
  117.  
  118.     StringBuilder& appendString(const char* str) {
  119.         return appendString(str, stringlen(str, 0));
  120.     }
  121.  
  122.     StringBuilder& appendChar(const char c) {
  123.         ensureBufferSize(1);
  124.         mBuffer[mNextIndex++] = c;
  125.     }
  126.  
  127.     // Appends an integer
  128.     StringBuilder& appendInt(int value) {
  129.         char c[10];
  130.         charset(c, 0, 10);
  131.         int intLen = itostr(value, c, 0);
  132.         return appendString(c, intLen);
  133.     }
  134.  
  135.     StringBuilder& appendLine() {
  136.         return appendChar('\n');
  137.     }
  138.  
  139.     // Returns the number of characters that have been appended to this StringBuilder
  140.     int getSize() {
  141.         return this->mNextIndex;
  142.     }
  143.  
  144.     // Returns the capacity of the internal buffer (not including the null-termination char)
  145.     int getCapacity() {
  146.         return this->mCapacity;
  147.     }
  148.  
  149.     // Returns the pointer to the internal null-terminated char buffer (aka c_str)
  150.     char* toString() {
  151.         setNonCharToNull();
  152.         return this->mBuffer;
  153.     }
  154.  
  155.     // Returns a reference to this StringBuilder
  156.     StringBuilder& ref() {
  157.         return *this;
  158.     }
  159.  
  160.     // Returns the pointer to this StringBuilder
  161.     StringBuilder* ptr() {
  162.         return this;
  163.     }
  164.  
  165.     inline StringBuilder operator+(const StringBuilder& right) { return StringBuilder(mBuffer, mNextIndex, right.mBuffer, right.mNextIndex); }
  166.  
  167.     StringBuilder operator+(const char value) {
  168.         StringBuilder sb = StringBuilder(mBuffer, mNextIndex, mNextIndex + 1);
  169.         sb.appendChar(value);
  170.         return sb;
  171.     }
  172.  
  173.     StringBuilder operator+(const int value) {
  174.         char c[10];
  175.         charset(c, 0, 10);
  176.         int intLen = itostr(value, c, 0);
  177.         return StringBuilder(mBuffer, mNextIndex, c, intLen);
  178.     }
  179.  
  180.     inline StringBuilder& operator+=(const StringBuilder& right) { return appendString(right.mBuffer, right.mNextIndex); }
  181.     inline StringBuilder& operator<<(const StringBuilder& right) { return appendString(right.mBuffer, right.mNextIndex); }
  182.  
  183.     inline StringBuilder& operator+=(const int value) { return appendInt(value); }
  184.     inline StringBuilder& operator<<(const int value) { return appendInt(value); }
  185.  
  186.     inline StringBuilder& operator+=(const char value) { return appendChar(value); }
  187.     inline StringBuilder& operator<<(const char value) { return appendChar(value); }
  188.  
  189.     // Ensures the internal buffer can fit the given number of extra characters (extraSize)
  190.     // Returns true if the buffer didn't require a resize, or if it was successfully resized
  191.     // Returns false if the buffer failed to resize (possibly due to memory fragmentation)
  192.     bool ensureBufferSize(int extraSize) {
  193.         if (requireResize(extraSize)) {
  194.             return resizeBuffer(mCapacity + extraSize, true);
  195.         }
  196.  
  197.         return true;
  198.     }
  199.  
  200.     // Checks if the internal buffer needs to be resized to fit the given number of extra characters (extraSize)
  201.     bool requireResize(const int extraSize) {
  202.         if ((extraSize + mNextIndex) > mCapacity) {
  203.             return true;
  204.         }
  205.  
  206.         return false;
  207.     }
  208.  
  209. private:
  210.     // Sets the last character in this StringBuilder as 0 (aka a null character, allowing strlen to be used)
  211.     void setLastAsNull() {
  212.         setNonCharToNull();
  213.         this->mBuffer[this->mCapacity] = 0;
  214.     }
  215.  
  216.     // Resizes the internal buffer to the given size, optionally copying the old buffer into the new one
  217.     bool resizeBuffer(const int newSize, const bool copyBuffer) {
  218.         if (copyBuffer) {
  219.             // hopefully prevents lots of cases of heap fragmentation on
  220.             // things that dont have much ram... like arduinos
  221.             void* newBuffer = realloc(mBuffer, newSize);
  222.             if (newBuffer == nullptr) {
  223.                 return false;
  224.             }
  225.  
  226.             mCapacity = newSize;
  227.             mBuffer = (char*)newBuffer;
  228.             setLastAsNull();
  229.             return true;
  230.         }
  231.         else {
  232.             delete[](mBuffer);
  233.             mBuffer = new char[newSize + 1];
  234.             mCapacity = newSize;
  235.             mNextIndex = 0;
  236.             setLastAsNull();
  237.             return true;
  238.         }
  239.     }
  240.  
  241.     // Sets all of the chars including (and past) the next write index, to null
  242.     // So that toString() wont return extra stuff
  243.     void setNonCharToNull() {
  244.         for (int i = mNextIndex;
  245.             i < mCapacity;
  246.             i++) {
  247.             mBuffer[i] = 0;
  248.         }
  249.     }
  250.  
  251.     void createCapacityBuffer() {
  252.         mBuffer = new char[mCapacity + 1];
  253.     }
  254.  
  255. private:
  256.     int mCapacity;
  257.     int mNextIndex;
  258.     char* mBuffer;
  259. };
  260.  
  261. #endif // !__STRING_BUILDER
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement