summaryrefslogtreecommitdiff
path: root/src/MTS_Text.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MTS_Text.cpp')
-rw-r--r--src/MTS_Text.cpp701
1 files changed, 701 insertions, 0 deletions
diff --git a/src/MTS_Text.cpp b/src/MTS_Text.cpp
new file mode 100644
index 0000000..d823bfe
--- /dev/null
+++ b/src/MTS_Text.cpp
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts.
+ *
+ * libmts is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mts/MTS_Text.h>
+//#include <mts/MTS_Logger.h>
+#include <algorithm>
+#include <sstream>
+#include <iostream>
+#include <limits>
+
+using namespace MTS;
+
+//strftime
+//%a Abbreviated weekday name * Thu
+//%A Full weekday name * Thursday
+//%b Abbreviated month name * Aug
+//%B Full month name * August
+//%c Date and time representation * Thu Aug 23 14:55:02 2001
+//%d Day of the month (01-31) 23
+//%H Hour in 24h format (00-23) 14
+//%I Hour in 12h format (01-12) 02
+//%j Day of the year (001-366) 235
+//%m Month as a decimal number (01-12) 08
+//%M Minute (00-59) 55
+//%p AM or PM designation PM
+//%S Second (00-61) 02
+//%U Week number with the first Sunday as the first day of week one (00-53) 33
+//%w Weekday as a decimal number with Sunday as 0 (0-6) 4
+//%W Week number with the first Monday as the first day of week one (00-53) 34
+//%x Date representation * 08/23/01
+//%X Time representation * 14:55:02
+//%y Year, last two digits (00-99) 01
+//%Y Year 2001
+//%Z Timezone name or abbreviation CDT
+//%% A % sign %
+
+//Example
+///* strftime example */
+//#include <stdio.h>
+//#include <time.h>
+//
+//int main ()
+//{
+// time_t rawtime;
+// struct tm * timeinfo;
+// char buffer [80];
+//
+// time ( &rawtime );
+// timeinfo = localtime ( &rawtime );
+//
+// strftime (buffer,80,"Now it's %I:%M%p.",timeinfo);
+// puts (buffer);
+//
+// return 0;
+//}
+
+std::string Text::time(const uint64_t& iTimeMicros, const TIMEFORMAT& eTime) {
+ int64_t now = iTimeMicros / 1000;
+ int64_t millis = now % 1000;
+ int64_t secs = (now / 1000) % 60;
+ int64_t mins = (now / 60000) % 60;
+ int64_t hours = (now / 3600000) % 24;
+ std::stringstream sBuffer;
+
+ switch (eTime) {
+ case HHcMMcSScmmm:
+ sBuffer << hours << ":" << mins << ":" << secs << ":" << millis;
+ return sBuffer.str();
+ break;
+ case HHcMMcSS:
+ sBuffer << (hours < 10 ? "0" : "") << hours << ":" << (mins < 10 ? "0" : "") << mins << ":" << (secs < 10 ? "0" : "") << secs;
+ return sBuffer.str();
+ break;
+
+ }
+ return std::string("UNKNOWN-TIME-FORMAT");
+}
+
+std::string Text::date(const tm& stTime, const DATEFORMAT& eDate) {
+ char buffer[80];
+
+ switch (eDate) {
+ case MMsDDsYY:
+ strftime(buffer, 80, "%x", &stTime);
+ return std::string(buffer);
+ break;
+ case MMsDDsYY_HHcMMcSS:
+ strftime(buffer, 80, "%m/%d/%Y %H:%M:%S", &stTime);
+ return std::string(buffer);
+ break;
+ case RFC_1123:
+ std::stringstream sBuffer;
+ //Thu, 01 Jan 1970 00:00:01 GMT
+ //Week
+ switch (stTime.tm_wday) {
+ case 0:
+ sBuffer << "Sun, ";
+ break;
+ case 1:
+ sBuffer << "Mon, ";
+ break;
+ case 2:
+ sBuffer << "Tue, ";
+ break;
+ case 3:
+ sBuffer << "Wed, ";
+ break;
+ case 4:
+ sBuffer << "Thu, ";
+ break;
+ case 5:
+ sBuffer << "Fri, ";
+ break;
+ case 6:
+ sBuffer << "Sat, ";
+ break;
+ }
+
+ //Day of Month
+ sBuffer << (stTime.tm_mday < 10 ? "0" : "") << stTime.tm_mday;
+
+ //Month
+ switch (stTime.tm_mon) {
+ case 0:
+ sBuffer << " Jan ";
+ break;
+ case 1:
+ sBuffer << " Feb ";
+ break;
+ case 2:
+ sBuffer << " Mar ";
+ break;
+ case 3:
+ sBuffer << " Apr ";
+ break;
+ case 4:
+ sBuffer << " May ";
+ break;
+ case 5:
+ sBuffer << " Jun ";
+ break;
+ case 6:
+ sBuffer << " Jul ";
+ break;
+ case 7:
+ sBuffer << " Aug ";
+ break;
+ case 8:
+ sBuffer << " Sep ";
+ break;
+ case 9:
+ sBuffer << " Oct ";
+ break;
+ case 10:
+ sBuffer << " Nov ";
+ break;
+ case 11:
+ sBuffer << " Dec ";
+ break;
+ }
+
+ sBuffer << (stTime.tm_year + 1900);
+ sBuffer << (stTime.tm_hour < 10 ? " 0" : " ") << stTime.tm_hour << ":" << (stTime.tm_min < 10 ? "0" : "") << stTime.tm_min << ":" << (stTime.tm_sec < 10 ? "0" : "")
+ << stTime.tm_sec;
+ sBuffer << " GMT";
+ return sBuffer.str();
+ break;
+ }
+ return std::string("UNKNOWN-DATE-FORMAT");
+}
+
+bool Text::datetimeIsBefore(const std::string& time1, const std::string& time2) {
+
+ struct tm tm1;
+ struct tm tm2;
+
+ strptime(time1.c_str(), "%x %T", &tm1);
+ strptime(time2.c_str(), "%x %T", &tm2);
+
+ return difftime(mktime(&tm2), mktime(&tm1)) > 0;
+}
+
+std::vector<std::string> Text::split(const std::string& str, char delimiter, int limit) {
+ return split(str, std::string(1, delimiter), limit);
+}
+
+std::vector<std::string> Text::split(const std::string& str, const std::string& delimiter, int limit) {
+ std::vector<std::string> result;
+ if(str.size() == 0) {
+ return result;
+ }
+ if (limit <= 0) {
+ limit = std::numeric_limits<int>::max();
+ }
+ size_t start = 0;
+ size_t end = str.find(delimiter, start);
+ for (int i = 1; (i < limit) && (end != std::string::npos); ++i) {
+ result.push_back(str.substr(start, end - start));
+ start = end + delimiter.length();
+ end = str.find(delimiter, start);
+ }
+ result.push_back(str.substr(start));
+ return result;
+}
+
+std::string Text::join(std::vector<std::string> list, char delimiter) {
+
+ std::stringstream ss;
+ for (uint32_t i = 0; i < list.size(); i++) {
+ ss << list[i];
+ if (i < list.size() - 1)
+ ss << delimiter;
+ }
+ return ss.str();
+}
+
+std::string Text::replace(const std::string& original, const std::string& from, const std::string& to) {
+ size_t start_pos = 0;
+ std::string str(original);
+ while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
+ str.replace(start_pos, from.length(), to);
+ start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
+ }
+ return str;
+}
+
+uint32_t Text::count(const std::string& str, const std::string& element) {
+ uint32_t count = 0;
+ size_t start_pos = 0;
+ while ((start_pos = str.find(element, start_pos)) != std::string::npos) {
+ start_pos++;
+ count++;
+ }
+ return count;
+}
+
+uint32_t Text::count(const std::string& str, const uint8_t& element) {
+ uint32_t count = 0;
+ size_t start_pos = 0;
+ while ((start_pos = str.find(element, start_pos)) != std::string::npos) {
+ start_pos++;
+ count++;
+ }
+ return count;
+}
+
+bool Text::endsWith(const std::string& str, const std::string& key) {
+ if (key.size() > str.size()) return false;
+ return std::equal(str.begin() + str.size() - key.size(), str.end(), key.begin());
+}
+
+std::string Text::getLine(const std::string& source, const size_t& start, size_t& cursor) {
+ char delimiters[2];
+ delimiters[0] = '\n';
+ delimiters[1] = '\r';
+ if(start > source.size()) {
+ cursor = std::string::npos;
+ return "";
+ }
+ size_t end = source.find_first_of(delimiters, start, 2);
+ std::string line(source.substr(start, end - start));
+ //printDebug("[TEXT] Start [%d] Cursor[%d] Size[%d] Line: %s", start, end, source.size(), line.c_str());
+ if (end < source.size()) {
+ if (end < source.size() - 1)
+ if ((source[end] == '\n' && source[end + 1] == '\r') || (source[end] == '\r' && source[end + 1] == '\n')) {
+ //Advance an additional character in scenarios where lines end in \r\n or \n\r
+ end++;
+ }
+ end++;
+ }
+ cursor = end;
+ return line;
+}
+
+std::string Text::trim(const std::string& str) {
+ size_t length = str.length();
+ size_t start = length;
+ for (size_t i = 0; i < length; ++i) {
+ if (!isspace(static_cast<unsigned char>(str[i]))) {
+ start = i;
+ break;
+ }
+ }
+ size_t end = std::string::npos;
+ for (size_t i = length - 1; i != std::string::npos; --i) {
+ if (!isspace(static_cast<unsigned char>(str[i]))) {
+ end = i + 1;
+ break;
+ }
+ }
+ return str.substr(start, end - start);
+}
+
+std::string Text::trim(const std::string& str, const uint8_t& element) {
+ size_t length = str.length();
+ size_t start = length;
+ for (size_t i = 0; i < length; ++i) {
+ if (static_cast<unsigned char>(str[i]) != element) {
+ start = i;
+ break;
+ }
+ }
+ size_t end = std::string::npos;
+ for (size_t i = length - 1; i != std::string::npos; --i) {
+ if (static_cast<unsigned char>(str[i]) != element) {
+ end = i + 1;
+ break;
+ }
+ }
+ return str.substr(start, end - start);
+}
+
+
+std::string Text::strip(const std::string& str, const std::vector<uint8_t>& elements) {
+ std::string result(str);
+ for (uint32_t i = 0; i < elements.size(); i++) {
+ result.erase (std::remove(result.begin(), result.end(), elements[i]), result.end());
+ }
+ return result;
+}
+
+std::string Text::strip(const std::string& str, const uint8_t& element) {
+ std::string result(str);
+ result.erase (std::remove(result.begin(), result.end(), element), result.end());
+ return result;
+}
+
+std::string Text::toLowerCase(const std::string& str) {
+ std::string result(str);
+ size_t length = result.length();
+ for (size_t i = 0; i < length; ++i) {
+ result[i] = static_cast<char>(tolower(static_cast<unsigned char>(result[i])));
+ }
+ return result;
+}
+
+std::string Text::toUpperCase(const std::string& str) {
+ std::string result(str);
+ size_t length = result.length();
+ for (size_t i = 0; i < length; ++i) {
+ result[i] = static_cast<char>(toupper(static_cast<unsigned char>(result[i])));
+ }
+ return result;
+}
+
+std::string Text::toCapitalized(const std::string& str) {
+ std::string result;
+ result = str;
+ if (str.size() == 0)
+ return result;
+ else if (str.size() == 1)
+ return toUpperCase(result);
+ else
+ return toUpperCase(result.substr(0, 1)) + toLowerCase(result.substr(1));
+}
+
+std::string Text::toCamelCase(const std::string& str) {
+ std::string result;
+ if (str.size() == 0) {
+ return result;
+ }
+
+ std::vector<std::string> parts = MTS::Text::split(str, ' ');
+
+ if (parts.size() == 0 || parts[0].size() == 0) {
+ return result;
+ }
+ result.append(MTS::Text::toLowerCase(parts[0]));
+
+ for (uint32_t i = 1; i < parts.size(); i++) {
+ result.append(MTS::Text::toCapitalized(parts[i]));
+ }
+
+ return result;
+}
+
+std::string Text::toCommandLineEscaped(const std::string& str) {
+ std::string result(str);
+ result = Text::replace(result, "#", "\\#");
+ result = Text::replace(result, ".", "\\.");
+ result = Text::replace(result, "&", "\\&");
+ result = Text::replace(result, "?", "\\?");
+ return result;
+}
+
+std::wstring Text::widen(const std::string& str) {
+ std::wstringstream wss;
+ size_t length = str.length();
+ for (size_t i = 0; i < length; ++i) {
+ wss << wss.widen(str[i]);
+ }
+ return wss.str();
+}
+
+std::string Text::narrow(const std::wstring& str) {
+ std::wstringstream wss;
+ std::stringstream ss;
+ size_t length = str.length();
+ for (size_t i = 0; i < length; ++i) {
+ ss << wss.narrow(str[i], '?');
+ }
+ return ss.str();
+}
+
+std::string Text::format(bool value) {
+ std::stringstream ss;
+ ss.setf(ss.boolalpha);
+ ss << value;
+ return ss.str();
+}
+
+std::string Text::format(double value, std::streamsize percision) {
+ std::stringstream ss;
+ ss.setf(ss.fixed, ss.floatfield);
+ ss.precision(percision);
+ ss << value;
+ std::string str = ss.str();
+ // strip trailing zeros
+ size_t pos = str.find_last_not_of('0');
+ if (pos != std::string::npos) {
+ if (str[pos] == '.') {
+ pos += 2;
+ } else {
+ pos += 1;
+ }
+ }
+ return str.substr(0, pos);
+}
+
+std::string Text::format(int8_t value) {
+ return format(static_cast<int64_t>(value));
+}
+
+std::string Text::format(int16_t value) {
+ return format(static_cast<int64_t>(value));
+}
+
+std::string Text::format(int32_t value) {
+ return format(static_cast<int64_t>(value));
+}
+
+std::string Text::format(int64_t value) {
+ std::stringstream ss;
+ ss.setf(ss.dec, ss.basefield);
+ ss << value;
+ return ss.str();
+}
+
+std::string Text::format(uint8_t value) {
+ return format(static_cast<uint64_t>(value));
+}
+
+std::string Text::format(uint16_t value) {
+ return format(static_cast<uint64_t>(value));
+}
+
+std::string Text::format(uint32_t value) {
+ return format(static_cast<uint64_t>(value));
+}
+
+std::string Text::format(uint64_t value) {
+ std::stringstream ss;
+ ss.setf(ss.dec, ss.basefield);
+ ss << value;
+ return ss.str();
+}
+
+static std::string toHexString(uint64_t value, bool pad, std::streamsize padSize) {
+ std::stringstream ss;
+ ss.unsetf(ss.showbase);
+ ss.setf(ss.hex, ss.basefield);
+ ss.setf(ss.uppercase);
+ if (pad) {
+ ss.width(padSize);
+ ss.fill('0');
+ }
+ ss << value;
+ return ss.str();
+}
+
+std::string Text::formatHex(int8_t value, bool pad) {
+ return formatHex(static_cast<uint8_t>(value), pad);
+}
+
+std::string Text::formatHex(int16_t value, bool pad) {
+ return formatHex(static_cast<uint16_t>(value), pad);
+}
+
+std::string Text::formatHex(int32_t value, bool pad) {
+ return formatHex(static_cast<uint32_t>(value), pad);
+}
+
+std::string Text::formatHex(int64_t value, bool pad) {
+ return formatHex(static_cast<uint64_t>(value), pad);
+}
+
+std::string Text::formatHex(uint8_t value, bool pad) {
+ return toHexString(value, pad, 2);
+}
+
+std::string Text::formatHex(uint16_t value, bool pad) {
+ return toHexString(value, pad, 4);
+}
+
+std::string Text::formatHex(uint32_t value, bool pad) {
+ return toHexString(value, pad, 8);
+}
+
+std::string Text::formatHex(uint64_t value, bool pad) {
+ return toHexString(value, pad, 16);
+}
+
+std::string Text::formatHex(const Buffer& value) {
+ char hex[4];
+ std::string hexstr;
+ for (uint32_t i = 0; i < value.getSize(); i++) {
+ sprintf(hex, "%X", value.at(i));
+ hexstr.append(hex);
+ }
+ return hexstr;
+}
+
+bool Text::parse(bool& value, const std::string& str) {
+ if (str.empty()) {
+ return false;
+ }
+ std::istringstream ss(str);
+ ss.setf(ss.boolalpha);
+ ss.unsetf(ss.skipws);
+ ss >> value;
+ return ((uint8_t) ss.rdstate() == RDSTATE_SUCCESS_MASK);
+}
+
+bool Text::parse(double& value, const std::string& str) {
+ if (str.empty()) {
+ return false;
+ }
+ std::istringstream ss(str);
+ ss.setf(ss.fixed, ss.basefield);
+ ss.unsetf(ss.skipws);
+ ss >> value;
+ return ((uint8_t) ss.rdstate() == RDSTATE_SUCCESS_MASK);
+}
+
+bool Text::parse(int8_t& value, const std::string& str) {
+ int64_t i64 = 0;
+ if (!parse(i64, str)) {
+ return false;
+ }
+ if (i64 < INT8_MIN || i64 > INT8_MAX) {
+ return false;
+ }
+ value = static_cast<int8_t>(i64);
+ return true;
+}
+
+bool Text::parse(int16_t& value, const std::string& str) {
+ int64_t i64 = 0;
+ if (!parse(i64, str)) {
+ return false;
+ }
+ if (i64 < INT16_MIN || i64 > INT16_MAX) {
+ return false;
+ }
+ value = static_cast<int16_t>(i64);
+ return true;
+}
+
+bool Text::parse(int32_t& value, const std::string& str) {
+ int64_t i64 = 0;
+ if (!parse(i64, str)) {
+ return false;
+ }
+ if (i64 < INT32_MIN || i64 > INT32_MAX) {
+ return false;
+ }
+ value = static_cast<int32_t>(i64);
+ return true;
+}
+
+bool Text::parse(int64_t& value, const std::string& str) {
+ if (str.empty()) {
+ return false;
+ }
+ std::istringstream ss(str);
+ ss.setf(ss.dec, ss.basefield);
+ ss.unsetf(ss.skipws);
+ ss >> value;
+ return ((uint8_t) ss.rdstate() == RDSTATE_SUCCESS_MASK);
+}
+
+bool Text::parse(uint8_t& value, const std::string& str) {
+ uint64_t u64 = 0;
+ if (!parse(u64, str)) {
+ return false;
+ }
+ if (u64 > UINT8_MAX) {
+ return false;
+ }
+ value = static_cast<uint8_t>(u64);
+ return true;
+}
+
+bool Text::parse(uint16_t& value, const std::string& str) {
+ uint64_t u64 = 0;
+ if (!parse(u64, str)) {
+ return false;
+ }
+ if (u64 > UINT16_MAX) {
+ return false;
+ }
+ value = static_cast<uint16_t>(u64);
+ return true;
+}
+
+bool Text::parse(uint32_t& value, const std::string& str) {
+ uint64_t u64 = 0;
+ if (!parse(u64, str)) {
+ return false;
+ }
+ if (u64 > UINT32_MAX) {
+ return false;
+ }
+ value = static_cast<uint32_t>(u64);
+ return true;
+}
+
+bool Text::parse(uint64_t& value, const std::string& str) {
+ if (str.empty()) {
+ return false;
+ }
+ std::istringstream ss(str);
+ ss.setf(ss.dec, ss.basefield);
+ ss.unsetf(ss.skipws);
+ ss >> value;
+ return ((uint8_t) ss.rdstate() == RDSTATE_SUCCESS_MASK);
+}
+
+bool Text::parseHex(uint8_t& value, const std::string& str) {
+ uint64_t u64 = 0;
+ if (!parseHex(u64, str)) {
+ return false;
+ }
+ if (u64 > UINT8_MAX) {
+ return false;
+ }
+ value = static_cast<uint8_t>(u64);
+ return true;
+}
+
+bool Text::parseHex(uint16_t& value, const std::string& str) {
+ uint64_t u64 = 0;
+ if (!parseHex(u64, str)) {
+ return false;
+ }
+ if (u64 > UINT16_MAX) {
+ return false;
+ }
+ value = static_cast<uint16_t>(u64);
+ return true;
+}
+
+bool Text::parseHex(uint32_t& value, const std::string& str) {
+ uint64_t u64 = 0;
+ if (!parseHex(u64, str)) {
+ return false;
+ }
+ if (u64 > UINT32_MAX) {
+ return false;
+ }
+ value = static_cast<uint32_t>(u64);
+ return true;
+}
+
+bool Text::parseHex(uint64_t& value, const std::string& str) {
+
+ if (str.empty()) {
+ return false;
+ }
+ std::istringstream ss(str);
+ ss >> std::hex >> value;
+ return ((uint8_t) ss.rdstate() == RDSTATE_SUCCESS_MASK);
+}
+