summaryrefslogtreecommitdiffhomepage
path: root/FoundationEx/Text.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2024-03-12 01:08:39 +0100
committerAki <please@ignore.pl>2024-03-12 01:08:39 +0100
commitf43d32d6d2cc7ecd04f4f06f20d5a6fc2c87c9ae (patch)
tree0f82962432f9cd4fae60dd37c8935c1bc28f29e5 /FoundationEx/Text.cpp
parent2914a714cebae7f30d47362dfe50c39cb6621163 (diff)
downloadstarshatter-f43d32d6d2cc7ecd04f4f06f20d5a6fc2c87c9ae.zip
starshatter-f43d32d6d2cc7ecd04f4f06f20d5a6fc2c87c9ae.tar.gz
starshatter-f43d32d6d2cc7ecd04f4f06f20d5a6fc2c87c9ae.tar.bz2
Another reorganization change that diverts me from crying unable to get rid off singleton madness
Diffstat (limited to 'FoundationEx/Text.cpp')
-rw-r--r--FoundationEx/Text.cpp678
1 files changed, 0 insertions, 678 deletions
diff --git a/FoundationEx/Text.cpp b/FoundationEx/Text.cpp
deleted file mode 100644
index 442a048..0000000
--- a/FoundationEx/Text.cpp
+++ /dev/null
@@ -1,678 +0,0 @@
-/* Starshatter: The Open Source Project
- Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors
- Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
- Copyright (c) 1997-2006, Destroyer Studios LLC.
-
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Implementation of the Text class
-*/
-
-#include "Text.h"
-
-#include <cctype>
-#include <cstdarg>
-#include <cstring>
-
-// +-------------------------------------------------------------------+
-// SPECIAL TEXT REP FOR NULL STRINGS
-// This is used only by the default constructor for the Text object,
-// to prevent extra rep allocation when constructing empty strings.
-
-TextRep TextRep::nullrep;
-
-TextRep::TextRep()
- : ref(1234567), data(0), length(0), hash(0), sensitive(true)
-{
- data = new char[4];
-
- if (data)
- std::memset(data, 0, 4);
-}
-
-// +-------------------------------------------------------------------+
-
-
-TextRep::TextRep(const char* s)
- : ref(1), length(0), sensitive(true)
-{
- if (s) length = std::strlen(s);
-
- data = new char[length+1];
-
- if (data) {
- if (s) std::strcpy(data, s);
- else data[length] = '\0';
-
- dohash();
- }
-}
-
-TextRep::TextRep(const char* s, int len)
- : ref(1), length(len), sensitive(true)
-{
- if (length < 0) length = 0;
-
- data = new char[length+1];
-
- if (data) {
- std::memcpy(data, s, length);
- data[length] = '\0';
- dohash();
- }
-}
-
-TextRep::TextRep(char c, int len)
- : ref(1), length(len), sensitive(true)
-{
- if (length < 0) length = 0;
-
- data = new char[length+1];
-
- if (data) {
- std::memset(data, c, length);
- data[length] = '\0';
- dohash();
- }
-}
-
-TextRep::TextRep(const TextRep* rep)
- : ref(1)
-{
- length = rep->length;
-
- data = new char[length+1];
-
- hash = rep->hash;
- sensitive = rep->sensitive;
-
- if (data)
- std::strcpy(data, rep->data);
-}
-
-TextRep::~TextRep()
-{
- delete[] data;
-}
-
-void
-TextRep::addref()
-{
- ref++;
-}
-
-long
-TextRep::deref()
-{
- long r = --ref;
- return r;
-}
-
-inline static void mash(unsigned& hash, unsigned chars)
-{
- hash = (chars ^ ((hash << 5) | (hash >> (8*sizeof(unsigned) - 5))));
-}
-
-void
-TextRep::dohash()
-{
- unsigned hv = (unsigned)length; // Mix in the string length.
- unsigned i = length*sizeof(char)/sizeof(unsigned);
- const unsigned* p = (const unsigned*)data;
-
- while (i--)
- mash(hv, *p++); // XOR in the characters.
-
- // XOR in any remaining characters:
- i = length*sizeof(char)%sizeof(unsigned);
- if (i) {
- unsigned h = 0;
- const char* c = (const char*)p;
- while (i--)
- h = ((h << 8*sizeof(char)) | *c++);
- mash(hv, h);
- }
-
- hash = hv;
-}
-
-// +-------------------------------------------------------------------+
-
-Text::Text()
-{
- rep = &TextRep::nullrep;
- rep->addref();
- sym = rep->data;
-}
-
-Text::Text(char c)
-{
- char buf[2]; buf[0] = c; buf[1] = '\0';
-
- rep = new TextRep(buf);
-
- if (!rep) {
- rep = &TextRep::nullrep;
- rep->addref();
- }
-
- sym = rep->data;
-}
-
-Text::Text(const char* s)
-{
- rep = new TextRep(s);
-
- if (!rep) {
- rep = &TextRep::nullrep;
- rep->addref();
- }
-
- sym = rep->data;
-}
-
-Text::Text(const char* s, int len)
-{
- rep = new TextRep(s, len);
-
- if (!rep) {
- rep = &TextRep::nullrep;
- rep->addref();
- }
-
- sym = rep->data;
-}
-
-Text::Text(char c, int len)
-{
- rep = new TextRep(c, len);
-
- if (!rep) {
- rep = &TextRep::nullrep;
- rep->addref();
- }
-
- sym = rep->data;
-}
-
-Text::Text(const Text& s)
-{
- rep = s.rep;
- rep->addref();
- sym = rep->data;
-}
-
-Text::~Text()
-{
- if (rep->deref() == 0) delete rep;
-
- rep = &TextRep::nullrep;
- sym = rep->data;
-}
-
-Text&
-Text::operator=(const char* s)
-{
- if (rep->deref() == 0) delete rep;
- rep = new TextRep(s);
-
- if (!rep)
- rep = &TextRep::nullrep;
- sym = rep->data;
- return *this;
-}
-
-Text&
-Text::operator=(const Text& s)
-{
- s.rep->addref();
- if (rep->deref() == 0) delete rep;
- rep = s.rep;
- sym = rep->data;
- return *this;
-}
-
-Text
-Text::operator+(char c)
-{
- char* buf = new char[rep->length + 2];
-
- if (buf) {
- std::strcpy(buf, sym);
- buf[rep->length] = c;
- buf[rep->length+1] = '\0';
- Text retval(buf);
- delete [] buf;
- return retval;
- }
-
- else {
- return *this;
- }
-}
-
-Text
-Text::operator+(const char* s)
-{
- char* buf = new char[std::strlen(s) + rep->length + 1];
-
- if (buf) {
- std::strcpy(buf, sym);
- std::strcat(buf, s);
- Text retval(buf);
- delete [] buf;
- return retval;
- }
-
- else {
- return *this;
- }
-}
-
-Text
-Text::operator+(const Text& s)
-{
- char* buf = new char[s.rep->length + rep->length + 1];
-
- if (buf) {
- std::strcpy(buf, sym);
- std::strcat(buf, s.sym);
- Text retval(buf);
- delete [] buf;
- return retval;
- }
-
- else {
- return *this;
- }
-}
-
-bool
-Text::isSensitive() const
-{
- return rep->sensitive;
-}
-
-void
-Text::setSensitive(bool s)
-{
- rep->sensitive = s;
-}
-
-Text&
-Text::append(char c)
-{
- char* buf = new char[rep->length + 2];
-
- if (buf) {
- std::strcpy(buf, sym);
- buf[rep->length] = c;
- buf[rep->length+1] = '\0';
- if (rep->deref() == 0) delete rep;
-
- rep = new TextRep(buf);
-
- if (!rep)
- rep = &TextRep::nullrep;
-
- sym = rep->data;
- delete [] buf;
- }
-
- return *this;
-}
-
-Text&
-Text::append(const char* s)
-{
- char* buf = new char[std::strlen(s) + rep->length + 1];
-
- if (buf) {
- std::strcpy(buf, sym);
- std::strcat(buf, s);
- if (rep->deref() == 0) delete rep;
-
- rep = new TextRep(buf);
-
- if (!rep)
- rep = &TextRep::nullrep;
-
- sym = rep->data;
- delete [] buf;
- }
-
- return *this;
-}
-
-Text&
-Text::append(const Text& s)
-{
- char* buf = new char[s.rep->length + rep->length + 1];
-
- if (buf) {
- int lenA = rep->length;
- int lenB = s.rep->length;
-
- std::memcpy(buf, sym, lenA);
- std::memcpy(buf + lenA, s.sym, lenB);
- buf[lenA + lenB] = 0;
-
- if (rep->deref() == 0) delete rep;
-
- rep = new TextRep(buf);
-
- if (!rep)
- rep = &TextRep::nullrep;
-
- sym = rep->data;
- delete [] buf;
- }
-
- return *this;
-}
-
-void
-Text::clone()
-{
- if (rep->ref > 1) {
- rep->deref();
-
- TextRep* t = new TextRep(rep);
-
- rep = t;
-
- if (!rep)
- rep = &TextRep::nullrep;
-
- sym = rep->data;
- }
-}
-
-char
-Text::operator[](int index) const
-{
- if (index < (int) rep->length)
- return sym[index];
- else
- throw "BOUNDS ERROR";
-
- return '\0';
-}
-
-char
-Text::operator()(int index) const
-{
- return sym[index];
-}
-
-char&
-Text::operator[](int index)
-{
- if (index < (int) rep->length) {
- clone();
- return (char&) sym[index];
- }
- else
- throw "BOUNDS ERROR";
-
- return (char&) sym[0];
-}
-
-char&
-Text::operator()(int index)
-{
- clone();
- return (char&) sym[index];
-}
-
-Text
-Text::operator()(int start, int len) const
-{
- if (start > rep->length || len <= 0)
- return Text();
-
- if (start + len > rep->length)
- len = rep->length - start;
-
- char* buf = new char[len+1];
-
- if (buf) {
- std::strncpy(buf, sym+start, len);
- buf[len] = '\0';
-
- Text retval(buf);
- delete [] buf;
- return retval;
- }
-
- return Text();
-}
-
-bool
-Text::contains(char c) const
-{
- if (rep->length > 0) {
- if (!rep->sensitive) {
- char alt = c;
- if (std::islower(alt)) alt = std::toupper(alt);
- else if (std::isupper(alt)) alt = std::tolower(alt);
-
- if (std::strchr(rep->data, alt) != 0)
- return true;
- }
-
- if (std::strchr(rep->data, c) != 0)
- return true;
- }
-
- return false;
-}
-
-bool
-Text::contains(const char* pattern) const
-{
- if (rep->length > 0 && pattern && *pattern) {
- if (rep->sensitive) {
- if (std::strstr(rep->data, pattern) != 0)
- return true;
- }
- else {
- Text smash1(*this);
- smash1.toLower();
- Text smash2(pattern);
- smash2.toLower();
-
- if (std::strstr(smash1.data(), smash2.data()) != 0)
- return true;
- }
- }
-
- return false;
-}
-
-bool
-Text::containsAnyOf(const char* charSet) const
-{
- if (rep->length > 0 && charSet && *charSet) {
- if (rep->sensitive) {
- if (strpbrk(rep->data, charSet) != 0)
- return true;
- }
- else {
- Text smash1(*this);
- smash1.toLower();
- Text smash2(charSet);
- smash2.toLower();
-
- if (strpbrk(smash1.data(), smash2.data()) != 0)
- return true;
- }
- }
-
- return false;
-}
-
-int
-Text::indexOf(char c) const
-{
- if (rep->length > 0) {
- if (!rep->sensitive) {
- char alt = c;
- if (std::islower(alt)) alt = std::toupper(alt);
- else if (std::isupper(alt)) alt = std::tolower(alt);
-
- const char* p = std::strchr(rep->data, alt);
-
- if (p)
- return (p - rep->data);
- }
-
- const char* p = std::strchr(rep->data, c);
-
- if (p)
- return (p - rep->data);
- }
-
- return -1;
-}
-
-int
-Text::indexOf(const char* pattern) const
-{
- if (rep->length > 0 && pattern && *pattern) {
- if (rep->sensitive) {
- const char* p = std::strstr(rep->data, pattern);
- if (p) return (p - rep->data);
- }
- else {
- Text smash1(*this);
- smash1.toLower();
- Text smash2(pattern);
- smash2.toLower();
-
- const char* p = std::strstr(smash1.data(), smash2.data());
- if (p) return (p - smash1.data());
- }
- }
-
- return -1;
-}
-
-void
-Text::toLower()
-{
- clone();
- size_t n = rep->length;
- char* p = (char*) sym;
- while (n--) {
- *p = std::tolower((unsigned char)*p);
- p++;
- }
-
- rep->dohash();
-}
-
-void
-Text::toUpper()
-{
- clone();
- size_t n = rep->length;
- char* p = (char*) sym;
- while ( n-- ) {
- *p = std::toupper((unsigned char)*p);
- p++;
- }
-
- rep->dohash();
-}
-
-Text
-Text::substring(int start, int length)
-{
- Text result;
-
- if (start >= 0 && start < (int) rep->length && length > 0) {
- if (start + length > (int) rep->length)
- length = (int) rep->length - start;
-
- const char* s = sym + start;
-
- result.rep = new TextRep(s, length);
-
- if (!result.rep)
- result.rep = &TextRep::nullrep;
-
- result.sym = result.rep->data;
- }
-
- return result;
-}
-
-Text
-Text::trim()
-{
- Text result;
-
- if (rep->length) {
- const char* p = sym;
- const char* q = sym + rep->length-1;
-
- while (p && *p && isspace(*p)) p++;
- while (q>p && *q && isspace(*q)) q--;
-
- result = substring(p-sym, q-p+1);
- }
-
- return result;
-}
-
-Text
-Text::replace(const char* pattern, const char* substitution)
-{
- Text result;
-
- if (rep->length && pattern && *pattern) {
- const char* pos = rep->data;
- const char* bound = rep->data + rep->length;
- int skip = std::strlen(pattern);
- do {
- const char* p = std::strstr(pos, pattern);
- if (p) {
- int len = p - pos;
- result.append(Text(pos, len));
- result.append(substitution);
- pos = p + skip;
- }
- else if (pos < bound) {
- result.append(pos);
- break;
- }
- }
- while (pos < bound);
- }
-
- return result;
-}
-
-Text
-Text::concat(const char* tail) const
-{
- Text result(*this);
- result.append(tail);
- return result;
-}
-
-Text
-Text::format(const char* fmt, ...)
-{
- char buf[2048];
- std::va_list args;
- va_start(args, fmt);
- int len = std::vsnprintf(buf, 2048, fmt, args);
- Text result(buf, len);
- va_end(args);
- return result;
-}