123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- #include "stringbuilder.h"
- #include <string.h>
- #include <stdio.h>
- #include <inttypes.h>
- stringbuilder_node::stringbuilder_node()
- {
- // This constructor is only used for fast_nodes.
- }
- stringbuilder_node::stringbuilder_node(datastring node,bool should_delete)
- {
- data.item = node;
- need_to_delete = should_delete;
- is_number = false;
- }
- stringbuilder_node::stringbuilder_node(int64_t value)
- {
- data.number = value;
- need_to_delete = false;
- is_number = true;
- }
- void stringbuilder_node::clear()
- {
- if ((!is_number) && (data.item.data != nullptr)) {
- if (need_to_delete) {
- delete data.item.data;
- }
- data.item.data = nullptr;
- }
- return;
- }
-
- stringbuilder::stringbuilder()
- {
- index = 0;
- }
- stringbuilder::~stringbuilder()
- {
- clear();
- }
- stringbuilder &stringbuilder::addparameter(int item)
- {
- // Appends the number, then a comma.
- return addparameter((int64_t)item);
- }
- stringbuilder &stringbuilder::addparameter(int64_t item)
- {
- // Appends the number, then a comma.
- operator+=(item);
- operator+=(",");
- return *this;
- }
- stringbuilder &stringbuilder::addparameter(datastring item)
- {
- // Appends the length first, then a comma, then the data.
- operator+=(item.length);
- operator+=(",");
- append(item,false);
- return *this;
- }
- stringbuilder &stringbuilder::operator+=(const char *item)
- {
- datastring temp;
- temp.data = (char *)item;
- temp.length = item == nullptr ? 0 : strlen(item);
- temp.null_terminated = true;
- append(temp, false);
- return *this;
- }
- stringbuilder &stringbuilder::operator+=(datastring item)
- {
- append(item, false);
- return *this;
- }
- stringbuilder &stringbuilder::operator+=(int item)
- {
- return append((int64_t)item);
- }
- stringbuilder &stringbuilder::operator+=(int64_t item)
- {
- return append(item);
- }
- stringbuilder &stringbuilder::append(int64_t item)
- {
- auto node = nodes[index];
- node->used = true;
- if (index < FAST_NODE_COUNT) {
- node->item = fast_nodes + index;
- node->item->data.number = item;
- node->item->is_number = true;
- node->item->need_to_delete = false;
- } else {
- node->item = new stringbuilder_node(item);
- }
- index++;
- return *this;
- }
- stringbuilder &stringbuilder::append(datastring item, bool need_to_delete)
- {
- auto node = nodes[index];
- node->used = true;
- if (index < FAST_NODE_COUNT) {
- node->item = fast_nodes + index;
- node->item->data.item = item;
- node->item->is_number = false;
- node->item->need_to_delete = need_to_delete;
- } else {
- node->item = new stringbuilder_node(item,need_to_delete);
- }
- index++;
- return *this;
- }
- int stringbuilder::length()
- {
- int loop;
- int total = 0;
- int64_t number;
- for(loop=0;loop<index;loop++) {
- auto node = nodes[loop];
- if (node->item->is_number) {
- // Figure out the length of the number when converted to base 10.
- number = node->item->data.number;
- if (number < 0) {
- // Minus sign.
- number = -number;
- total++;
- }
- total++; // First digit.
- // Count other digits.
- while (number >= 10000) {
- total += 4;
- number /= 10000;
- }
- while (number >= 10) {
- total++;
- number /= 10;
- }
- } else {
- total += node->item->data.item.length;
- }
- }
- return total;
- }
- void stringbuilder::clear()
- {
- // Clears the list and deletes any allocated items.
- int loop;
- for(loop=0;loop<index;loop++) {
- auto node = nodes[loop];
- node->item->clear();
- if (loop >= FAST_NODE_COUNT) {
- delete node->item;
- }
- node->item = nullptr;
- node->used = false;
- }
- index = 0;
- return;
- }
- void stringbuilder::print()
- {
- biglist<stringbuilder_node *>nodes;
- biglist_iterator<stringbuilder_node *>loop(&nodes);
- while(!loop.eof()) {
- if (loop.item->is_number) {
- printf("%" PRId64,loop.item->data.number);
- } else {
- loop.item->data.item.print();
- }
- loop.movenext();
- }
- return;
- }
- void stringbuilder::println()
- {
- print();
- printf("\n");
- }
- int stringbuilder::tostring(char *buffer)
- {
- // Save this string to a buffer.
- // It assumes that the buffer was allocated already
- // by calling the length() function.
- // Be sure to allow an extra byte for the end of line.
- int message_length;
- int buffersize;
- char *pos;
- int node_loop;
- int item_length;
- int node_count;
- int64_t number;
- int64_t divisor;
- int64_t remainder;
- bool showzero;
-
- pos = buffer;
- node_count = index;
- for(node_loop=0;node_loop<node_count;node_loop++) {
- auto node = nodes[node_loop];
- auto node_item = node->item;
- if (node_item->is_number) {
- number = node->item->data.number;
- if (number < 0) {
- number = -number;
- *(pos++) = '-';
- }
- divisor = 1000000000000000000L;
- showzero = false;
- while (true) {
- remainder = number / divisor;
- if ((showzero) || (remainder > 0) || (divisor == 1)) {
- *(pos++) = (char)remainder + '0';
- showzero = true;
- number -= divisor * remainder;
- }
- if (divisor == 1) {
- break;
- }
- divisor /= 10;
- }
- } else {
- item_length = node_item->data.item.length;
- if (item_length > 0) {
- memcpy(pos,node_item->data.item.data,item_length);
- pos+=item_length;
- }
- }
- }
- *pos = 0;
- return pos - buffer;
- }
|