23 #define errno GetLastError()
24 #define strcasecmp _stricmp
43 p =
string + strlen(
string) - 1;
46 if (*p ==
'\r' || *p ==
'\n')
71 q =
string + strlen(
string) - 1;
73 while (q >= p && isspace(*q))
93 while (*p != 0 && *p != c)
116 size_t alen = strlen(a);
117 size_t blen = strlen(b);
122 while (a[alen-1] == sep)
129 s.setsize(alen + blen + 2);
130 char *cptr = s.
edit();
132 memcpy(cptr, a, alen);
141 while (b[boffset] == sep)
146 memcpy(cptr+alen+1, b.cstr()+boffset, blen-boffset);
147 cptr[alen+1+blen-boffset] = 0;
163 if (isspace(*
string))
171 char *nbstr =
new char[s.len() + 1];
172 return strcpy(nbstr, s.
edit());
180 char *
string = (
char *)_string;
181 for (
int i=0; i < length; i++)
182 if (*(
string+i) == c1)
193 char *p = strstr(haystack, needle);
194 if(!p || p != haystack)
197 return haystack + strlen(needle);
247 const unsigned char *buf = (
const unsigned char *)_buf;
248 size_t count, count2, top;
251 out.setsize(len / 16 * 80 + 80);
252 char *cptr = out.
edit();
254 for (count = 0; count < len; count+=16)
256 top = len-count < 16 ? len-count : 16;
257 cptr += sprintf(cptr,
"[%03X] ", (
unsigned int)count);
260 for (count2 = 0; count2 < top; count2++)
262 if (count2 && !(count2 % 4))
264 cptr += sprintf(cptr,
"%02X", buf[count+count2]);
268 for (count2 = top; count2 < 16; count2++)
270 if (count2 && !(count2 % 4))
287 for (count2 = 0; count2 < top; count2++)
291 *cptr++ = (isprint(buf[count+count2])
292 ? buf[count+count2] :
'.');
306 return c==
'\n' || c==
'\r';
318 const char *idx1, *idx2;
319 static const char hex[] =
"0123456789ABCDEF";
323 out.setsize(strlen(in) + 1);
326 for (iptr = in, optr = out.
edit(); *iptr; iptr++)
328 if (*iptr ==
'+' && !no_space)
330 else if (*iptr ==
'%' && iptr[1] && iptr[2])
332 idx1 = strchr(hex, toupper((
unsigned char) iptr[1]));
333 idx2 = strchr(hex, toupper((
unsigned char) iptr[2]));
336 *optr++ = ((idx1 - hex) << 4) | (idx2 - hex);
356 for (i=0; i < str.len(); i++)
358 if (((!!unsafe && !strchr(unsafe, str[i])) ||
359 (!unsafe && (isalnum(str[i]) || strchr(
"_.!~*'()-", str[i])))) &&
362 retval.put(&str[i], 1);
367 sprintf(buf,
"%%%02X", str[i] & 0xff);
379 double diff = difftime(t1, t2);
382 if(diff > (60 * 60 * 24))
384 sprintf(out,
"%.1f day(s)", diff / (60 * 60 * 24));
385 else if(diff > (60 * 60))
386 sprintf(out,
"%.0f hour(s)", diff / (60 * 60));
388 sprintf(out,
"%.0f minute(s)", diff / 60);
390 sprintf(out,
"%.0f second(s)", diff);
403 struct tm *tmwhen = localtime(&when);
404 strftime(out.
edit(), 80,
"%a, %d %b %Y %H:%M:%S %z", tmwhen);
417 s2.setsize(s1.len() * 2 + 1);
420 char *p2 = s2.
edit();
437 while ((p=strchr(p, c)) != NULL && p++)
449 WvStringList::Iter i(fqdnlist);
452 for (i.rewind(); i.next(); )
453 dn.append(
"dc=%s,", *i);
463 char *optr, *optr_start;
467 nice.setsize(name.len() + 2);
470 optr = optr_start = nice.
edit();
471 if (!isascii(*iptr) || !isalnum(*(
const unsigned char *)iptr))
474 last_was_dash =
false;
475 for (; *iptr; iptr++)
480 if (*iptr ==
'-' || *iptr ==
'_')
484 last_was_dash =
true;
487 else if (isalnum(*(
const unsigned char *)iptr) || *iptr ==
'.')
490 last_was_dash =
false;
494 if (optr > optr_start && !isalnum(*(
const unsigned char *)(optr-1)))
509 char *cptr = strrchr(tmp.
edit(),
'/');
523 WvString getdirname(WvStringParm fullname)
526 char *cptr = strrchr(tmp.edit(),
'/');
533 return getdirname(tmp);
552 unsigned long long base;
560 {
"M", 1000ull * 1000ull },
561 {
"G", 1000ull * 1000ull * 1000ull },
562 {
"T", 1000ull * 1000ull * 1000ull * 1000ull },
563 {
"P", 1000ull * 1000ull * 1000ull * 1000ull * 1000ull},
564 {
"E", 1000ull * 1000ull * 1000ull * 1000ull * 1000ull * 1000ull},
575 {
"Mi", 1024ull * 1024ull},
576 {
"Gi", 1024ull * 1024ull * 1024ull },
577 {
"Ti", 1024ull * 1024ull * 1024ull * 1024ull },
578 {
"Pi", 1024ull * 1024ull * 1024ull * 1024ull * 1024ull},
579 {
"Ei", 1024ull * 1024ull * 1024ull * 1024ull * 1024ull * 1024ull},
587 static inline unsigned long long _sizetoa_rounder(RoundingMethod method,
588 unsigned long long size,
589 unsigned long long remainder,
590 unsigned long long base)
592 unsigned long long half = base / 2;
593 unsigned long long significant_digits = size / base;
600 if (remainder || (size % base))
601 ++significant_digits;
604 case ROUND_UP_AT_POINT_FIVE:
605 if ((size % base) >= half)
606 ++significant_digits;
609 case ROUND_DOWN_AT_POINT_FIVE:
610 unsigned long long r = size % base;
611 if ((r > half) || (remainder && (r == half)))
612 ++significant_digits;
615 return significant_digits;
627 static WvString _sizetoa(
unsigned long long size,
unsigned long blocksize,
628 RoundingMethod rounding_method,
629 const prefix_t *prefixes, WvStringParm unit)
645 const unsigned long long group_base = prefixes[0].base;
647 unsigned long prev_blocksize = 0;
648 while (blocksize >= group_base)
650 prev_blocksize = blocksize;
651 blocksize /= group_base;
657 if (prev_blocksize && prev_blocksize != group_base)
659 blocksize = prev_blocksize;
664 unsigned long long significant_digits = size * 10;
665 unsigned int remainder = 0;
666 if (significant_digits < size)
669 remainder = size % group_base;
673 while (size >= group_base)
676 significant_digits = _sizetoa_rounder(rounding_method,
680 if (significant_digits < (group_base * 10)
681 || !prefixes[p + shift + 1].name)
688 significant_digits *= blocksize;
689 while (significant_digits >= (group_base * 10)
690 && prefixes[p + shift + 1].name)
692 significant_digits = _sizetoa_rounder(rounding_method,
702 significant_digits / 10,
703 significant_digits % 10,
704 prefixes[p + shift].name,
709 RoundingMethod rounding_method)
711 unsigned long long bytes = blocks * blocksize;
714 if (bytes < 1000 && bytes >= blocks)
717 return _sizetoa(blocks, blocksize, rounding_method, si,
"B");
726 return sizetoa(kbytes, 1000, rounding_method);
730 RoundingMethod rounding_method)
732 unsigned long long bytes = blocks * blocksize;
735 if (bytes < 1024 && bytes >= blocks)
738 return _sizetoa(blocks, blocksize, rounding_method, iec,
"B");
747 return sizeitoa(kbytes, 1024, rounding_method);
754 unsigned int days = total_seconds / (3600*24);
755 total_seconds %= (3600*24);
756 unsigned int hours = total_seconds / 3600;
757 total_seconds %= 3600;
758 unsigned int mins = total_seconds / 60;
759 unsigned int secs = total_seconds % 60;
761 int num_elements = (days > 0) + (hours > 0) + (mins > 0);
766 result.append(days > 1 ?
" days" :
" day");
768 if (num_elements > 1)
770 else if (num_elements == 1)
771 result.append(
" and ");
775 result.append(hours);
776 result.append(hours > 1 ?
" hours" :
" hour");
778 if (num_elements > 1)
780 else if (num_elements == 1)
781 result.append(
" and ");
786 result.append(mins > 1 ?
" minutes" :
" minute");
788 if (days == 0 && hours == 0 && mins == 0)
791 result.append(secs != 1 ?
" seconds" :
" second");
800 const char *sptr = s, *eptr;
802 while ((eptr = strstr(sptr, a)) != NULL)
804 buf.put(sptr, eptr-sptr);
806 sptr = eptr + strlen(a);
809 buf.put(sptr, strlen(sptr));
820 for (
int i = 0; s[i] !=
'\0'; i++)
840 struct tm *tm = gmtime(&t);
844 strftime(s.
edit(), 128,
"%a, %d %b %Y %H:%M:%S GMT", tm);
850 int lookup(
const char *str,
const char *
const *table,
bool case_sensitive)
852 for (
int i = 0; table[i]; ++i)
856 if (strcmp(str, table[i]) != 0)
861 if (strcasecmp(str, table[i]) != 0)
876 char *name =
new char[maxlen];
877 int result = gethostname(name, maxlen);
885 assert(errno == WSAEFAULT);
887 assert(errno == EINVAL);
895 struct hostent *myhost;
899 return myhost->h_name;
901 return WvString::null;
911 char *name =
new char[maxlen];
912 char *res = getcwd(name, maxlen);
919 if (errno == EACCES || errno == ENOENT)
921 assert(errno == ERANGE);
942 res.setsize(digits + ((digits - 1) / 3) + ((j < 0) ? 1 : 0));
950 p += digits + ((digits - 1) / 3);
953 for (digit=0; digit<digits; digit++)
955 *p-- =
'0' + ( j%10 );
956 if (((digit+1) % 3) == 0 && digit < digits - 1)
968 return WvString::null;
970 const char *loc = strstr(line, a);
984 return WvString::null;
988 char *loc = strstr(ret.
edit(), a);
1000 const char *tmp = line.
cstr();
1001 if (pos > line.len()-1)
1006 char *tmp2 = ret.
edit();
1007 if (pos + len < line.len())
1020 static inline const char *cstr_escape_char(
char ch)
1022 static const char *xlat[256] =
1024 "\\0",
"\\x01",
"\\x02",
"\\x03",
"\\x04",
"\\x05",
"\\x06",
"\\a",
1025 "\\b",
"\\t",
"\\n",
"\\v",
"\\x0C",
"\\r",
"\\x0E",
"\\x0F",
1026 "\\x10",
"\\x11",
"\\x12",
"\\x13",
"\\x14",
"\\x15",
"\\x16",
"\\x17",
1027 "\\x18",
"\\x19",
"\\x1A",
"\\x1B",
"\\x1C",
"\\x1D",
"\\x1E",
"\\x1F",
1028 " ",
"!",
"\\\"",
"#",
"$",
"%",
"&",
"'",
1029 "(",
")",
"*",
"+",
",",
"-",
".",
"/",
1030 "0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
1031 "8",
"9",
":",
";",
"<",
"=",
">",
"?",
1032 "@",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
1033 "H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
1034 "P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
1035 "X",
"Y",
"Z",
"[",
"\\\\",
"]",
"^",
"_",
1036 "`",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
1037 "h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
1038 "p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
1039 "x",
"y",
"z",
"{",
"|",
"}",
"~",
"\\x7F",
1040 "\\x80",
"\\x81",
"\\x82",
"\\x83",
"\\x84",
"\\x85",
"\\x86",
"\\x87",
1041 "\\x88",
"\\x89",
"\\x8A",
"\\x8B",
"\\x8C",
"\\x8D",
"\\x8E",
"\\x8F",
1042 "\\x90",
"\\x91",
"\\x92",
"\\x93",
"\\x94",
"\\x95",
"\\x96",
"\\x97",
1043 "\\x98",
"\\x99",
"\\x9A",
"\\x9B",
"\\x9C",
"\\x9D",
"\\x9E",
"\\x9F",
1044 "\\xA0",
"\\xA1",
"\\xA2",
"\\xA3",
"\\xA4",
"\\xA5",
"\\xA6",
"\\xA7",
1045 "\\xA8",
"\\xA9",
"\\xAA",
"\\xAB",
"\\xAC",
"\\xAD",
"\\xAE",
"\\xAF",
1046 "\\xB0",
"\\xB1",
"\\xB2",
"\\xB3",
"\\xB4",
"\\xB5",
"\\xB6",
"\\xB7",
1047 "\\xB8",
"\\xB9",
"\\xBA",
"\\xBB",
"\\xBC",
"\\xBD",
"\\xBE",
"\\xBF",
1048 "\\xC0",
"\\xC1",
"\\xC2",
"\\xC3",
"\\xC4",
"\\xC5",
"\\xC6",
"\\xC7",
1049 "\\xC8",
"\\xC9",
"\\xCA",
"\\xCB",
"\\xCC",
"\\xCD",
"\\xCE",
"\\xCF",
1050 "\\xD0",
"\\xD1",
"\\xD2",
"\\xD3",
"\\xD4",
"\\xD5",
"\\xD6",
"\\xD7",
1051 "\\xD8",
"\\xD9",
"\\xDA",
"\\xDB",
"\\xDC",
"\\xDD",
"\\xDE",
"\\xDF",
1052 "\\xE0",
"\\xE1",
"\\xE2",
"\\xE3",
"\\xE4",
"\\xE5",
"\\xE6",
"\\xE7",
1053 "\\xE8",
"\\xE9",
"\\xEA",
"\\xEB",
"\\xEC",
"\\xED",
"\\xEE",
"\\xEF",
1054 "\\xF0",
"\\xF1",
"\\xF2",
"\\xF3",
"\\xF4",
"\\xF5",
"\\xF6",
"\\xF7",
1055 "\\xF8",
"\\xF9",
"\\xFA",
"\\xFB",
"\\xFC",
"\\xFD",
"\\xFE",
"\\xFF"
1057 return xlat[(
unsigned char)ch];
1060 static inline int hex_digit_val(
char ch)
1062 static int val[256] =
1064 -1, -1, -1, -1, -1, -1, -1, -1,
1065 -1, -1, -1, -1, -1, -1, -1, -1,
1066 -1, -1, -1, -1, -1, -1, -1, -1,
1067 -1, -1, -1, -1, -1, -1, -1, -1,
1068 -1, -1, -1, -1, -1, -1, -1, -1,
1069 -1, -1, -1, -1, -1, -1, -1, -1,
1070 0, 1, 2, 3, 4, 5, 6, 7,
1071 8, 9, -1, -1, -1, -1, -1, -1,
1072 -1, 10, 11, 12, 13, 14, 15, -1,
1073 -1, -1, -1, -1, -1, -1, -1, -1,
1074 -1, -1, -1, -1, -1, -1, -1, -1,
1075 -1, -1, -1, -1, -1, -1, -1, -1,
1076 -1, 10, 11, 12, 13, 14, 15, -1,
1077 -1, -1, -1, -1, -1, -1, -1, -1,
1078 -1, -1, -1, -1, -1, -1, -1, -1,
1079 -1, -1, -1, -1, -1, -1, -1, -1,
1080 -1, -1, -1, -1, -1, -1, -1, -1,
1081 -1, -1, -1, -1, -1, -1, -1, -1,
1082 -1, -1, -1, -1, -1, -1, -1, -1,
1083 -1, -1, -1, -1, -1, -1, -1, -1,
1084 -1, -1, -1, -1, -1, -1, -1, -1,
1085 -1, -1, -1, -1, -1, -1, -1, -1,
1086 -1, -1, -1, -1, -1, -1, -1, -1,
1087 -1, -1, -1, -1, -1, -1, -1, -1,
1088 -1, -1, -1, -1, -1, -1, -1, -1,
1089 -1, -1, -1, -1, -1, -1, -1, -1,
1090 -1, -1, -1, -1, -1, -1, -1, -1,
1091 -1, -1, -1, -1, -1, -1, -1, -1,
1092 -1, -1, -1, -1, -1, -1, -1, -1,
1093 -1, -1, -1, -1, -1, -1, -1, -1,
1094 -1, -1, -1, -1, -1, -1, -1, -1,
1095 -1, -1, -1, -1, -1, -1, -1, -1
1097 return val[(
unsigned char)ch];
1100 static inline bool cstr_unescape_char(
const char *&cstr,
char &ch)
1108 case '"': ch =
'"';
break;
1109 case 't': ch =
'\t';
break;
1110 case 'n': ch =
'\n';
break;
1111 case '\\': ch =
'\\';
break;
1112 case 'r': ch =
'\r';
break;
1113 case 'a': ch =
'\a';
break;
1114 case 'v': ch =
'\v';
break;
1115 case 'b': ch =
'\b';
break;
1116 case '0': ch =
'\0';
break;
1123 if ((vals[i] = hex_digit_val(*++cstr)) == -1)
1126 ch = (vals[0] << 4) | vals[1];
1129 default:
return false;
1146 if (!data)
return WvString::null;
1148 const char *cdata = (
const char *)data;
1151 result.setsize(4*size + 3);
1152 char *cstr = result.
edit();
1157 const char *esc = NULL;
1161 while (extra->ch && extra->esc)
1163 if (*cdata == extra->ch)
1172 if (!esc) esc = cstr_escape_char(*cdata);
1174 while (*esc) *cstr++ = *esc++;
1182 bool cstr_unescape(WvStringParm cstr,
void *data,
size_t max_size,
size_t &size,
1185 const char *q = cstr;
1186 char *cdata = (
char *)data;
1188 if (!q)
goto misformatted;
1193 while (isspace(*q)) q++;
1194 if (*q ==
'\0')
break;
1196 if (*q++ !=
'\"')
goto misformatted;
1197 while (*q && *q !=
'\"')
1204 while (extra->ch && extra->esc)
1206 size_t len = strlen(extra->esc);
1207 if (strncmp(extra->esc, q, len) == 0)
1218 if (!found && !cstr_unescape_char(q, unesc))
goto misformatted;
1219 if (size++ < max_size && cdata) *cdata++ = unesc;
1221 if (*q++ !=
'\"')
goto misformatted;
1224 return size <= max_size;
1240 struct tm *tmwhen = localtime(&when);
1241 strftime(out.
edit(), 80,
"%b %d %I:%M:%S %p", tmwhen);
1254 struct tm *tmwhen = localtime(&when);
1255 strftime(out.
edit(), 12,
"%H:%M:%S", tmwhen);
1268 struct tm *tmwhen = localtime(&when);
1269 strftime(out.
edit(), 16,
"%Y-%m-%d", tmwhen);
1282 struct tm *tmwhen = localtime(&when);
1283 strftime(out.
edit(), 24,
"%Y-%m-%d %H:%M:%S", tmwhen);
1296 struct tm *l = localtime(&t);
1298 time_t local = mktime(l);
1299 time_t gmt = mktime(gmtime(&t));
1309 char * edit = ret.
edit();
1310 int last = ret.len() - 1;
1311 if (edit[last] ==
'.' || edit[last] ==
'?' || edit[last] ==
'!')
1320 char buf[(
sizeof(ptr) * 2) + 3];
1323 rv = snprintf(buf,
sizeof(buf),
"%p", ptr);