/*
Copyright (C) 2005-2007 Michel de Boer <michel@twinklephone.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <iostream>
#include <cassert>
#include <cctype>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <sys/time.h>
#include "util.h"
#include "twinkle_config.h"
string month_abbrv[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"};
string month_full[] = {"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"};
string day_abbrv[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
string random_token(int length) {
string s;
for (int i = 0; i < length; i++) {
s += char(rand() % 26 + 97);
}
return s;
}
string random_hexstr(int length) {
string s;
int x;
for (int i = 0; i < length; i++) {
x = rand() % 15;
if (x <= 9)
s += '0' + x;
else
s += 'a' + x;
}
return s;
}
string float2str(float f, const char *format) {
char buf[128];
snprintf(buf, 128, format, f);
return string(buf);
}
string int2str(int i, const char *format) {
char buf[32];
snprintf(buf, 32, format, i);
return string(buf);
}
string int2str(int i) {
return int2str(i, "%d");
}
string ulong2str(unsigned long i, const char *format) {
char buf[32];
snprintf(buf, 32, format, i);
return string(buf);
}
string ulong2str(unsigned long i) {
return ulong2str(i, "%u");
}
string ptr2str(void *p) {
char buf[32];
snprintf(buf, 32, "%p", p);
return string(buf);
}
string bool2str(bool b) {
return (b ? "true" : "false");
}
string time2str(time_t t, const char *format) {
struct tm tm;
char buf[64];
localtime_r(&t, &tm);
strftime(buf, 64, format, &tm);
return string(buf);
}
string current_time2str(const char *format) {
struct timeval t;
gettimeofday(&t, NULL);
return time2str(t.tv_sec, format);
}
string weekday2str(int wkday) {
if (wkday >= 0 && wkday <= 6) return day_abbrv[wkday];
return "XXX";
}
string month2str(int month) {
if (month >= 0 && month <= 11) return month_abbrv[month];
return "XXX";
}
int str2month_full(const string &month) {
for (int i = 0; i < 12; i++) {
if (cmp_nocase(month_full[i], month) == 0) {
return i;
}
}
return 0;
}
string duration2str(unsigned long seconds) {
string result;
long remainder, h, m, s;
h = seconds / 3600;
remainder = seconds % 3600;
m = remainder / 60;
s = remainder % 60;
if (h > 0) {
result = ulong2str(h);
result += "h ";
}
if (!result.empty() || m > 0) {
result += ulong2str(m);
result += "m ";
}
result += ulong2str(s);
result += "s";
return result;
}
string timer2str(unsigned long seconds) {
string result;
long remainder, h, m, s;
h = seconds / 3600;
remainder = seconds % 3600;
m = remainder / 60;
s = remainder % 60;
char buf[16];
snprintf(buf, 16, "%01d:%02d:%02d", h, m, s);
return string(buf);
}
unsigned long hex2int(const string &h) {
unsigned long u = 0;
int power = 1;
for (string::const_reverse_iterator i = h.rbegin(); i != h.rend(); ++i) {
if (*i >= '0' && *i <= '9')
u += (*i - '0') * power;
else if (*i >= 'a' && *i <= 'f')
u += (*i - 'a' + 10) * power;
else if (*i >= 'A' && *i <= 'F')
u += (*i - 'A' + 10) * power;
power = power * 16;
}
return u;
}
string tolower(const string &s) {
string result;
for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
result += tolower(*i);
}
return result;
}
string toupper(const string &s) {
string result;
for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
result += toupper(*i);
}
return result;
}
string rtrim(const string &s) {
string::size_type i;
i = s.find_last_not_of(' ');
if (i == string::npos) return "";
if (i == s.size()-1) return s;
return s.substr(0, i+1);
}
string ltrim(const string &s) {
string::size_type i;
i = s.find_first_not_of(' ');
if (i == string::npos) return "";
if (i == 0) return s;
return s.substr(i, s.size()-i+1);
}
string trim(const string &s) {
return ltrim(rtrim(s));
}
int cmp_nocase(const string &s1, const string &s2) {
string::const_iterator i1 = s1.begin();
string::const_iterator i2 = s2.begin();
while (i1 != s1.end() && i2 != s2.end()) {
if (toupper(*i1) != toupper(*i2)) {
return (toupper(*i1) < toupper(*i2)) ? -1 : 1;
}
++i1;
++i2;
}
if (s1.size() == s2.size()) return 0;
if (s1.size() < s2.size()) return -1;
return 1;
}
bool must_quote(const string &s) {
string special("()<>@,;:\\\"/[]?={} \t");
if (s.size() == 0) return true;
return (s.find_first_of(special) != string::npos);
}
string escape(const string &s, char c) {
string result;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '\\' || s[i] == c) {
result += '\\';
}
result += s[i];
}
return result;
}
string unescape(const string &s) {
string result;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '\\' && i < s.size() - 1) {
i++;
}
result += s[i];
}
return result;
}
string escape_hex(const string &s, const string &unreserved) {
string result;
for (int i = 0; i < s.size(); i++) {
if (unreserved.find(s[i], 0) != string::npos) {
// Unreserved symbol
result += s[i];
} else {
// Reserved symbol
result += int2str((int)s[i], "%%%02x");
}
}
return result;
}
string unescape_hex(const string &s) {
string result;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '%' && i < s.size() - 2 &&
isxdigit(s[i+1]) && isxdigit(s[i+2]))
{
// Escaped hex-value
string hexval = s.substr(i+1, 2);
result += static_cast<char>(hex2int(hexval));
i += 2;
} else {
result += s[i];
}
}
return result;
}
string replace_char(const string &s, char from, char to) {
string result = s;
for (int i = 0; i < result.size(); i++) {
if (result[i] == from) result[i] = to;
}
return result;
}
string replace_first(const string &s, const string &from, const string &to) {
string result = s;
string::size_type i = result.find(from, 0);
if (i != string::npos) {
result.replace(i, from.size(), to);
}
return result;
}
vector<string> split(const string &s, char c) {
string::size_type i;
string::size_type j = 0;
vector<string> l;
while (true) {
i = s.find(c, j);
if (i == string::npos) {
l.push_back(s.substr(j));
return l;
}
if (i == j)
l.push_back("");
else
l.push_back(s.substr(j, i-j));
j = i+1;
if (j == s.size()) {
l.push_back("");
return l;
}
}
}
vector<string> split(const string &s, const string& separator) {
string::size_type i;
string::size_type j = 0;
vector<string> l;
while (true) {
i = s.find(separator, j);
if (i == string::npos) {
l.push_back(s.substr(j));
return l;
}
if (i == j)
l.push_back("");
else
l.push_back(s.substr(j, i-j));
j = i + separator.size();
if (j == s.size()) {
l.push_back("");
return l;
}
}
}
vector<string> split_linebreak(const string &s) {
if (s.find("\r\n") != string::npos) {
return split(s, "\r\n");
} else if (s.find("\r") != string::npos) {
return split(s, "\r");
}
return split(s, "\n");
}
vector<string> split_on_first(const string &s, char c) {
vector<string> l;
string::size_type i = s.find(c);
if (i == string::npos) {
l.push_back(s);
} else {
if (i == 0) {
l.push_back("");
} else {
l.push_back(s.substr(0, i));
}
if (i == s.size() - 1) {
l.push_back("");
} else {
l.push_back(s.substr(i + 1));
}
}
return l;
}
vector<string> split_escaped(const string &s, char c) {
vector<string> l;
int start_pos = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '\\') {
// Skip escaped character
if (i < s.size()) i++;
continue;
}
if (s[i] == c) {
l.push_back(unescape(s.substr(start_pos, i - start_pos)));
start_pos = i + 1;
}
}
if (start_pos < s.size()) {
l.push_back(unescape(s.substr(start_pos, s.size() - start_pos)));
} else if (start_pos == s.size()) {
l.push_back("");
}
return l;
}
vector<string> split_ws(const string &s, bool quote_sensitive) {
vector<string> l;
bool in_quotes = false;
int start_pos = 0;
for (int i = 0; i < s.size(); i++ ) {
if (quote_sensitive && s[i] == '"') {
in_quotes = !in_quotes;
continue;
}
if (in_quotes) continue;
if (s[i] == ' ' || s[i] == '\t') {
// Skip consecutive white space
if (start_pos != i) {
l.push_back(s.substr(start_pos, i - start_pos));
}
start_pos = i + 1;
}
}
if (start_pos < s.size()) {
l.push_back(s.substr(start_pos, s.size() - start_pos));
}
return l;
}
string join_strings(const vector<string> &v, const string &separator) {
string text;
for (vector<string>::const_iterator it = v.begin(); it != v.end(); ++it)
{
if (it != v.begin()) {
text += separator;
}
text += *it;
}
return text;
}
string unquote(const string &s) {
if (s.size() <= 1) return s;
if (s[0] == '"' && s[s.size() - 1] == '"')
return s.substr(1, s.size() - 2);
return s;
}
bool is_number(const string &s) {
if (s.empty()) return false;
for (int i = 0; i < s.size(); i++ ) {
if (!isdigit(s[i])) return false;
}
return true;
}
bool is_ipaddr(const string &s) {
vector<string> l = split(s, '.');
if (l.size() != 4) return false;
for (vector<string>::iterator i = l.begin(); i != l.end(); ++i) {
if (!is_number(*i) || atoi(i->c_str()) > 255) return false;
}
return true;
}
bool yesno2bool(const string &yesno) {
return (yesno == "yes" ? true : false);
}
string bool2yesno(bool b) {
return (b ? "yes" : "no");
}
string str2dtmf(const string &s) {
string result;
string to_convert = tolower(s);
for (int i = 0; i < to_convert.size(); i++) {
switch (to_convert[i]) {
case '1':
result += '1';
break;
case '2':
case 'a':
case 'b':
case 'c':
result += '2';
break;
case '3':
case 'd':
case 'e':
case 'f':
result += '3';
break;
case '4':
case 'g':
case 'h':
case 'i':
result += '4';
break;
case '5':
case 'j':
case 'k':
case 'l':
result += '5';
break;
case '6':
case 'm':
case 'n':
case 'o':
result += '6';
break;
case '7':
case 'p':
case 'q':
case 'r':
case 's':
result += '7';
break;
case '8':
case 't':
case 'u':
case 'v':
result += '8';
break;
case '9':
case 'w':
case 'x':
case 'y':
case 'z':
result += '9';
break;
case '0':
case ' ':
result += '0';
break;
case '#':
case '*':
result += to_convert[i];
break;
}
}
return result;
}
bool looks_like_phone(const string &s, const string &special_symbols) {
string phone_symbols= special_symbols + "0123456789*#+ \t";
string t;
for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
if (phone_symbols.find(*i) == string::npos) return false;
}
return true;
}
string remove_symbols(const string &s, const string &special_symbols) {
string result;
for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
if (special_symbols.find(*i) == string::npos) {
result += *i;
}
}
return result;
}
string remove_white_space(const string &s) {
string result;
for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
if (*i != ' ' && *i != '\t') {
result += *i;
}
}
return result;
}
string dotted_truncate(const string &s, int len) {
if (len >= s.size()) return s;
return s.substr(0, len) + "...";
}
string to_printable(const string &s) {
string result;
for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
if (isprint(*i) || *i == '\n' || *i == '\r') {
result += *i;
} else {
result += '.';
}
}
return result;
}
string get_error_str(int errnum) {
#if HAVE_STRERROR_R
char buf[81];
memset(buf, 0, sizeof(buf));
#if STRERROR_R_CHAR_P
string errmsg(strerror_r(errnum, buf, sizeof(buf)-1));
#else
string errmsg;
if (strerror_r(errnum, buf, sizeof(buf)-1) == 0) {
errmsg = buf;
} else {
errmsg = "unknown error: ";
errmsg += int2str(errnum);
}
#endif
#else
string errmsg("strerror_r is not available: ");
errmsg += int2str(errnum);
#endif
return errmsg;
}
syntax highlighted by Code2HTML, v. 0.9.1