624 lines
15 KiB
C++
624 lines
15 KiB
C++
#include "ZString.h"
|
|
#include "Log.h"
|
|
#include "Exception.h"
|
|
#include <stdlib.h>
|
|
#include <iostream>
|
|
|
|
namespace coreutils {
|
|
|
|
std::ostream &operator<<(std::ostream &os, const ZString &zstring) {
|
|
for (char *ix = zstring.data; ix < (zstring.data + zstring.length); ++ix)
|
|
os << *ix;
|
|
return os;
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &os, const std::string &string) {
|
|
os << string;
|
|
return os;
|
|
}
|
|
|
|
std::ostream &operator+(std::ostream &os, const ZString &zstring) {
|
|
os << zstring;
|
|
return os;
|
|
}
|
|
|
|
std::ostream &operator+(std::ostream &os, const char *value) {
|
|
os << value;
|
|
return os;
|
|
}
|
|
|
|
ZString::ZString() {
|
|
data = NULL;
|
|
length = 0;
|
|
cursor = data;
|
|
}
|
|
|
|
ZString::ZString(const char *data) {
|
|
if((char *)data != NULL) {
|
|
this->data = (char *)data;
|
|
this->length = strlen(data);
|
|
this->cursor = (char *)data;
|
|
} else {
|
|
this->data = NULL;
|
|
this->length = 0;
|
|
this->cursor = NULL;
|
|
}
|
|
}
|
|
|
|
ZString::ZString(char *data, size_t length) : data(data), length(length), cursor(data) {}
|
|
|
|
ZString::ZString(unsigned char *data, size_t length) : data((char *)data), length(length), cursor((char *)data) {}
|
|
|
|
ZString::ZString(const char *data, size_t length) : data((char *)data), length(length), cursor((char *)data) {}
|
|
|
|
ZString::ZString(const unsigned char *data, size_t length) : data((char *)data), length(length), cursor((char *)data) {}
|
|
|
|
ZString::ZString(const ZString &zstring) {
|
|
data = zstring.data;
|
|
length = zstring.length;
|
|
cursor = zstring.cursor;
|
|
}
|
|
|
|
ZString::ZString(std::string &data) {
|
|
this->data = (char *)data.c_str();
|
|
length = data.length();
|
|
cursor = (char *)data.c_str();
|
|
}
|
|
|
|
ZString::~ZString() {
|
|
if(cdata != NULL) {
|
|
std::cout << "********" << cdata << "********" << strlen(cdata) << std::endl;
|
|
free(cdata);
|
|
}
|
|
}
|
|
|
|
bool ZString::operator<(const ZString &valuex) const {
|
|
char *end1 = data + length;
|
|
char *end2 = valuex.getData() + valuex.getLength();
|
|
char *cursor1 = cursor;
|
|
char *cursor2 = valuex.getCursor();
|
|
while((cursor1 < end1) && (cursor2 < end2)) {
|
|
if(*cursor1 < *cursor2)
|
|
return 1;
|
|
if(*cursor1 > *cursor2)
|
|
return 0;
|
|
++cursor1;
|
|
++cursor2;
|
|
}
|
|
if((cursor1 == end1) && (cursor2 != end2))
|
|
return 1;
|
|
if((cursor2 == end2) && (cursor1 != end1))
|
|
return 0;
|
|
return 0;
|
|
}
|
|
|
|
// TODO: Fix the following comparison operators to handle the length problem appropriately.
|
|
|
|
bool ZString::operator<=(const ZString &valuex) const {
|
|
return (strncmp(data, valuex.data, valuex.length <= length ? valuex.length : length) <= 0);
|
|
}
|
|
|
|
bool ZString::operator>=(const ZString &valuex) const {
|
|
return (strncmp(data, valuex.data, valuex.length <= length ? valuex.length : length) >= 0);
|
|
}
|
|
|
|
bool ZString::operator>(const ZString &valuex) const {
|
|
return (strncmp(data, valuex.data, valuex.length <= length ? valuex.length : length) > 0);
|
|
}
|
|
|
|
bool ZString::operator==(const ZString valuex) {
|
|
if(valuex.getLength() != length)
|
|
return false;
|
|
return (strncmp(data, valuex.data, length) == 0);
|
|
}
|
|
|
|
bool ZString::operator!=(const ZString &valuex) const {
|
|
// if(length != valuex.getLength())
|
|
// return false;
|
|
return (strncmp(data, valuex.data, length) != 0);
|
|
}
|
|
|
|
bool ZString::operator!=(const char *valuex) const {
|
|
if(strlen(valuex) != length)
|
|
return true;
|
|
return (strncmp(data, valuex, length) != 0);
|
|
}
|
|
|
|
std::vector<ZString> &ZString::getList() {
|
|
return list;
|
|
}
|
|
|
|
int ZString::asInteger() {
|
|
int value = 0;
|
|
bool negative = false;
|
|
char *end = data + length;
|
|
if(*cursor == '-') {
|
|
negative = true;
|
|
++cursor;
|
|
} else if(*cursor == '+')
|
|
++cursor;
|
|
if(cursor == end)
|
|
return 0;
|
|
while((*cursor >= '0') && (*cursor <= '9')) {
|
|
value *= 10;
|
|
value += *cursor - 48;
|
|
++cursor;
|
|
if(cursor == end) {
|
|
if(negative)
|
|
return -value;
|
|
else
|
|
return value;
|
|
}
|
|
}
|
|
if(negative)
|
|
return -value;
|
|
return value;
|
|
}
|
|
|
|
double ZString::asDouble() {
|
|
double value = 0;
|
|
bool negative = false;
|
|
char *end = data + length;
|
|
if(*cursor == '-') {
|
|
negative = true;
|
|
++cursor;
|
|
} else if(*cursor == '+')
|
|
++cursor;
|
|
if(cursor == end)
|
|
return 0;
|
|
while((*cursor >= '0') && (*cursor <= '9')) {
|
|
value *= 10;
|
|
value += *cursor - 48;
|
|
++cursor;
|
|
if(cursor == end) {
|
|
if(negative)
|
|
return -value;
|
|
else
|
|
return value;
|
|
}
|
|
}
|
|
if(*cursor != '.') {
|
|
if(negative)
|
|
return -value;
|
|
else
|
|
return value;
|
|
}
|
|
++cursor;
|
|
if(cursor == end) {
|
|
if(negative)
|
|
return -value;
|
|
else
|
|
return value;
|
|
}
|
|
double div = 10;
|
|
while((*cursor >= '0') && (*cursor <= '9')) {
|
|
value += (*cursor - 48) / div;
|
|
div *= 10;
|
|
++cursor;
|
|
if(cursor == end) {
|
|
if(negative)
|
|
return -value;
|
|
else
|
|
return value;
|
|
}
|
|
}
|
|
if(negative)
|
|
return -value;
|
|
return value;
|
|
}
|
|
|
|
int ZString::incrementCursor(int length) {
|
|
char *temp = cursor;
|
|
if((cursor + length) > (data + this->length))
|
|
cursor = data + this->length;
|
|
else
|
|
cursor += length;
|
|
return cursor - temp;
|
|
}
|
|
|
|
void ZString::push() {
|
|
stack.push(cursor);
|
|
}
|
|
|
|
void ZString::pop() {
|
|
cursor = stack.top();
|
|
stack.pop();
|
|
}
|
|
|
|
std::string ZString::str() {
|
|
return std::string(data, length);
|
|
}
|
|
|
|
std::string ZString::str(int len) {
|
|
return std::string(data, len);
|
|
}
|
|
|
|
char* ZString::c_str() {
|
|
cdata = (char *)malloc(length + 1);
|
|
strncpy(cdata, data, length);
|
|
cdata[length] = '\0';
|
|
return cdata;
|
|
}
|
|
|
|
ZString ZString::substring(int start) {
|
|
char *end = data + length;
|
|
char *startChar = data + start;
|
|
if(startChar < end) {
|
|
return ZString(startChar, end - startChar);
|
|
}
|
|
return ZString();
|
|
}
|
|
|
|
ZString ZString::substring(int start, int len) {
|
|
char *end = data + length;
|
|
char *startChar = data + start;
|
|
char *endChar = startChar + len;
|
|
char newlen = endChar > end ? endChar - end: len;
|
|
if(startChar < end)
|
|
return ZString(startChar, newlen);
|
|
return ZString();
|
|
}
|
|
|
|
std::vector<ZString> &ZString::split(std::string delimiter, size_t maxSize) {
|
|
coreutils::ZString zDelimiter((char *)delimiter.c_str(), delimiter.size());
|
|
return split(zDelimiter, maxSize);
|
|
}
|
|
|
|
std::vector<ZString> &ZString::split(ZString &delimiter, size_t maxSize) {
|
|
list.clear();
|
|
if (length == 0) {
|
|
list.push_back(ZString(""));
|
|
return list;
|
|
}
|
|
maxSize = maxSize == 0 ? 255: maxSize;
|
|
char *end = data + length;
|
|
char *pos = cursor;
|
|
while ((pos + delimiter.getLength()) <= end) {
|
|
if ((strncmp(pos, delimiter.getData(), delimiter.getLength()) == 0) && (maxSize != 0)) {
|
|
list.push_back(ZString(cursor, pos - cursor));
|
|
cursor = pos + delimiter.getLength();
|
|
pos = cursor;
|
|
--maxSize;
|
|
}
|
|
else {
|
|
++pos;
|
|
}
|
|
}
|
|
list.push_back(ZString(cursor, pos - cursor));
|
|
cursor = data;
|
|
return list;
|
|
}
|
|
|
|
bool ZString::isCharacter(char ch, ZString include) {
|
|
for (int ix = 0; ix < include.getLength(); ++ix) {
|
|
if (ch == include.charAt(ix))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ZString::ifNextInclude(ZString include) {
|
|
if((cursor <= (data + length)) && isCharacter(*cursor, include))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
|
|
ZString ZString::getTokenInclude(const char *include) {
|
|
char *start = cursor;
|
|
while ((cursor <= (data + length)) && isCharacter(*cursor, include))
|
|
++cursor;
|
|
return ZString(start, cursor - start);
|
|
}
|
|
|
|
ZString ZString::getTokenExclude(const char *exclude) {
|
|
char previous = 0;
|
|
char *start = cursor;
|
|
do {
|
|
while ((cursor < (data + length)) && !isCharacter(*cursor, exclude)) {
|
|
previous = *cursor;
|
|
++cursor;
|
|
}
|
|
++cursor;
|
|
} while(previous == '\\');
|
|
--cursor;
|
|
return ZString(start, cursor - start);
|
|
}
|
|
|
|
ZString ZString::getTokenExclude(std::string exclude) {
|
|
return getTokenExclude(exclude.c_str());
|
|
}
|
|
|
|
ZString ZString::getContainer() {
|
|
char term = *cursor == '"' ? '"': *cursor == '(' ? ')': *cursor == '[' ? ']': *cursor == '{' ? '}': 0;
|
|
if(!term)
|
|
return ZString();
|
|
char *start = cursor;
|
|
char nest = *cursor;
|
|
char *end = cursor + length;
|
|
int level = 0;
|
|
++cursor;
|
|
while(cursor != end) {
|
|
if(*cursor == term) {
|
|
if(!level) {
|
|
++cursor;
|
|
return ZString(start, cursor - start);
|
|
}
|
|
--level;
|
|
} else if(*cursor == nest) {
|
|
++level;
|
|
}
|
|
++cursor;
|
|
}
|
|
return ZString();
|
|
}
|
|
|
|
ZString &ZString::operator[](int index) {
|
|
return list[index];
|
|
}
|
|
|
|
bool ZString::eod() {
|
|
return cursor >= data + length;
|
|
}
|
|
|
|
bool ZString::startsWith(const char *value) {
|
|
return strncmp(cursor, value, strlen(value)) == 0;
|
|
}
|
|
|
|
bool ZString::startsWithNumber() {
|
|
return ((*cursor >= '0') && (*cursor <= '9'));
|
|
}
|
|
|
|
int ZString::compare(ZString zstring) {
|
|
char *end1 = data + length;
|
|
char *end2 = zstring.getData() + zstring.getLength();
|
|
char *cursor1 = cursor;
|
|
char *cursor2 = zstring.getCursor();
|
|
while((cursor1 < end1) && (cursor2 < end2)) {
|
|
if(*cursor1 < *cursor2)
|
|
return -1;
|
|
if(*cursor1 > *cursor2)
|
|
return 1;
|
|
++cursor1;
|
|
++cursor2;
|
|
}
|
|
if((cursor1 == end1) && (cursor2 != end2))
|
|
return -1;
|
|
if((cursor2 == end2) && (cursor1 != end1))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
bool ZString::equals(const char *value) {
|
|
if (strlen(value) != length)
|
|
return false;
|
|
return strncmp(data, value, length) == 0;
|
|
}
|
|
|
|
bool ZString::equals(char *value) {
|
|
if (strlen(value) != length)
|
|
return false;
|
|
return strncmp(data, value, length) == 0;
|
|
}
|
|
|
|
bool ZString::equals(ZString &zstring) {
|
|
if (zstring.getLength() != length)
|
|
return false;
|
|
return strncmp(data, zstring.getData(), length) == 0;
|
|
}
|
|
|
|
bool ZString::equals(std::string &string) {
|
|
return string == std::string(data, length);
|
|
}
|
|
|
|
bool ZString::ifNext(ZString value) {
|
|
if (((data + length) - cursor) < value.getLength())
|
|
return false;
|
|
bool test = (strncmp(cursor, value.getCursor(), value.getLength()) == 0);
|
|
if (test)
|
|
cursor += value.getLength();
|
|
return test;
|
|
}
|
|
|
|
bool ZString::ifNextIgnoreCase(ZString value) {
|
|
if (((data + length) - cursor) < value.getLength())
|
|
return false;
|
|
bool test = (strncasecmp(cursor, value.getCursor(), value.getLength()) == 0);
|
|
if (test)
|
|
cursor += value.getLength();
|
|
return test;
|
|
}
|
|
|
|
int ZString::ifEqualsCount(ZString &comparator) {
|
|
int count = 0;
|
|
while (cursor < (data + length)) {
|
|
if (*cursor == *comparator.cursor) {
|
|
++count;
|
|
++cursor;
|
|
++comparator.cursor;
|
|
}
|
|
else {
|
|
return count;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int ZString::skipWhitespace() {
|
|
char *end = data + length;
|
|
int len = 0;
|
|
while((cursor < end) && ((*cursor == ' ') || (*cursor == '\n') || (*cursor == '\t'))) {
|
|
++cursor;
|
|
++len;
|
|
}
|
|
return len;
|
|
}
|
|
|
|
bool ZString::lineIsWhitespace() {
|
|
char *end = data + length;
|
|
char *temp = cursor;
|
|
while(temp < end) {
|
|
if(*temp == '\n')
|
|
return true;
|
|
if((*temp != ' ') && (*temp != '\t'))
|
|
return false;
|
|
++temp;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
ZString ZString::goeol() {
|
|
bool set = false;
|
|
char *temp = cursor;
|
|
char *tempend = data + length;
|
|
while (cursor <= (data + length)) {
|
|
if (*cursor == '\r') {
|
|
tempend = cursor++;
|
|
set = true;
|
|
}
|
|
if (*cursor == '\n') {
|
|
if (!set)
|
|
tempend = cursor;
|
|
++cursor;
|
|
break;
|
|
}
|
|
++cursor;
|
|
}
|
|
return ZString(temp, tempend - temp);
|
|
}
|
|
|
|
ZString ZString::goeolwithContinuation() {
|
|
ZString temp = goeol();
|
|
while(ifNextInclude(" \t"))
|
|
goeol();
|
|
return temp;
|
|
}
|
|
|
|
ZString ZString::trim() {
|
|
skipWhitespace();
|
|
return unparsed();
|
|
}
|
|
|
|
int ZString::find(ZString comparator) {
|
|
int count = 0;
|
|
char *temp = cursor;
|
|
char *temp2 = cursor;
|
|
while(!ifNext(comparator)) {
|
|
++count;
|
|
++cursor;
|
|
++temp2;
|
|
if(cursor > (data + length)) {
|
|
cursor = temp;
|
|
return -1;
|
|
}
|
|
}
|
|
cursor = temp2;
|
|
return count;
|
|
}
|
|
|
|
ZString ZString::readBlock(size_t size) {
|
|
char *temp = cursor;
|
|
cursor += size;
|
|
return ZString(temp, size);
|
|
}
|
|
|
|
char *ZString::getData() const {
|
|
return data;
|
|
}
|
|
|
|
char *ZString::getCursor() const {
|
|
return cursor;
|
|
}
|
|
|
|
void ZString::setCursor(char *cursor) {
|
|
if((cursor < data) || (cursor > (data + length)))
|
|
throw Exception("Cursor out of range on setCursor.");
|
|
this->cursor = cursor;
|
|
}
|
|
|
|
size_t ZString::getLength() const {
|
|
return length - (cursor - data);
|
|
}
|
|
|
|
void ZString::setZString(ZString zstring) {
|
|
data = zstring.getData();
|
|
length = zstring.getLength();
|
|
cursor = data;
|
|
}
|
|
|
|
ZString ZString::parsed() {
|
|
return ZString(data, cursor - data);
|
|
}
|
|
|
|
ZString ZString::unparsed() {
|
|
return ZString(cursor, data + length - cursor);
|
|
}
|
|
|
|
void ZString::reset() {
|
|
cursor = data;
|
|
}
|
|
|
|
char ZString::charAt(int index) {
|
|
return *(cursor + index);
|
|
}
|
|
|
|
bool ZString::trimCRLF() {
|
|
int len = length;
|
|
if (*(data + length - 1) == '\n')
|
|
--length;
|
|
if (*(data + length - 1) == '\r')
|
|
--length;
|
|
if (cursor >= (data + length))
|
|
cursor = data + length;
|
|
return len != length;
|
|
}
|
|
|
|
bool ZString::boolValue() {
|
|
if(this->equals("false"))
|
|
return false;
|
|
else if(this->equals("0"))
|
|
return false;
|
|
else if(this->equals(""))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
ZString ZString::removeTrailingZeros() {
|
|
if(length > 2) {
|
|
while((*(data + length - 1)) == '0')
|
|
--length;
|
|
if(*(data + length - 1) == '.')
|
|
--length;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
char ZString::nextChar() {
|
|
char temp = 0;
|
|
if(!eod())
|
|
temp = *cursor++;
|
|
return temp;
|
|
}
|
|
|
|
int ZString::getLineNumberAtCursor() {
|
|
char *temp = cursor;
|
|
int line = 1;
|
|
while(temp != data)
|
|
if(*temp-- == '\n')
|
|
++line;
|
|
return line;
|
|
}
|
|
|
|
void ZString::moveBackToLineStart() {
|
|
while(cursor != data) {
|
|
if(*cursor == '\n') {
|
|
cursor++;
|
|
break;
|
|
}
|
|
cursor--;
|
|
}
|
|
return;
|
|
}
|
|
|
|
}
|