1 #include "util_string.h"
2 #include "util_const.h"
3 #include "util_random.h"
4 #include "util_splitter.h"
11 #include <boost/regex.hpp>
12 #include <boost/regex/pattern_except.hpp>
13 #include <boost/algorithm/string.hpp>
23 UIConv::UIConv (const char* in, const char* out) {
24 cd = iconv_open (in, out);
25 if (cd == ICONV_ERR) {
26 throw (ustring (in).append (CharConst (", ")).append (ustring (out)).append (CharConst (": unknown encoding.")));
30 ustring UIConv::cv (const ustring& text) {
33 if (cd != ICONV_ERR) {
34 char* buf = new char[4096];
37 size_t isize, osize, rsize;
39 ibuf = text.begin ().base ();
45 rsize = ::iconv (cd, (char**)&ibuf, &isize, &obuf, &osize);
47 rsize = ::iconv (cd, &ibuf, &isize, &obuf, &osize);
50 if (errno == EILSEQ) {
53 ans.append (CharConst ("_"));
54 } else if (errno == EINVAL) {
55 } else if (errno == E2BIG) {
61 ans.append (buf, obuf - buf);
68 ustring c3 (const ustring& str) {
70 static uregex re ("^[0-9]+");
76 if (str[0] == '-' || str[0] == '+') {
80 if (usearch (b, e, m, re)) {
81 int n = m[0].second - m[0].first;
82 int l = str.size () + n / 3;
87 ans.append (1, str[0]);
89 for (; b != m[0].second; b ++) {
91 if (n > 1 && n % 3 == 1) {
92 ans.append (CharConst (","));
96 for (; b != e; b ++) {
105 ustring to_ustring (double val) {
107 return ustring (b, snprintf (b, 32, "%.*g", DBL_DIG, val));
110 static int hex (char c) {
111 if ('0' <= c && c <= '9') {
113 } else if ('a' <= c && c <= 'f') {
114 return (c - 'a' + 10);
115 } else if ('A' <= c && c <= 'F') {
116 return (c - 'A' + 10);
122 static int hex (char c1, char c2) {
123 return (hex (c1) * 16 + hex (c2));
126 static char hexchar (int c) {
127 if (0 <= c && c <= 9)
129 else if (10 <= c <= 15)
135 static char hexchar_c (int c) {
136 if (0 <= c && c <= 9)
138 else if (10 <= c <= 15)
144 static ustring percentHex (int c) {
145 ustring ans (3, '%');
147 ans[1] = hexchar ((c >> 4) & 0x0f);
148 ans[2] = hexchar (c & 0x0f);
152 static ustring percentHEX (int c) {
153 ustring ans (3, '%');
155 ans[1] = hexchar_c ((c >> 4) & 0x0f);
156 ans[2] = hexchar_c (c & 0x0f);
160 ustring urldecode_nonul (const ustring& str) {
162 static uregex re ("(\\+)|%([0-9a-fA-F][0-9a-fA-F])|\\x00");
166 ans.reserve (str.size ());
169 while (usearch (b, e, m, re)) {
170 if (b != m[0].first) {
171 ans.append (b, m[0].first);
175 } else if (m[2].matched) {
176 int v = hex (*(m[2].first), *(m[2].first + 1));
190 static ustring omitPattern (const ustring& text, uregex& re) {
191 Splitter sp (text, re);
196 ans.reserve (text.length ());
197 if (sp.begin () != sp.end ())
198 ans.append (sp.begin (), sp.end ());
200 if (sp.begin () != sp.end ())
201 ans.append (sp.begin (), sp.end ());
212 ustring omitCtrl (const ustring& str) {
213 static uregex re ("[\\x00-\\x1f\\x7f]+");
214 return omitPattern (str, re);
217 ustring omitCtrlX (const ustring& str) {
218 static uregex re ("[^\\x09\\x0a\\x20-\\x7e\\x80-\\xff]+");
219 return omitPattern (str, re);
222 ustring omitNul (const ustring& str) {
223 static uregex re ("[\\x00]+");
224 return omitPattern (str, re);
227 ustring omitNL (const ustring& str) {
228 return omitPattern (str, re_nl);
231 ustring omitNonAscii (const ustring& str) {
232 static uregex re ("[^ -\\x7e]+");
233 return omitPattern (str, re);
236 ustring omitNonAsciiWord (const ustring& str) {
237 static uregex re ("[^\\x21-\\x7e]+");
238 return omitPattern (str, re);
241 bool to_bool (const ustring& v) {
242 if (v.length () == 0 || (v.length () == 1 && v[0] == '0')) {
250 static ustring percentEncode (const ustring& text, uregex& re) {
260 if (b != e && usearch (b, e, m, re)) {
261 if (b != m[0].first) {
262 ans.append (ustring (b, m[0].first));
265 ans.append (uUScore);
266 } else if (m[2].matched) {
267 ans.append (percentHex (*m[2].first));
272 while (b != e && usearch (b, e, m, re)) {
273 if (b != m[0].first) {
274 ans.append (ustring (b, m[0].first));
277 ans.append (uUScore);
278 } else if (m[2].matched) {
279 ans.append (percentHex (*m[2].first));
286 ans.append (ustring (b, e));
295 static ustring percentEncode (uiterator b, uiterator e, const uregex& re) {
301 while (b < e && usearch (b, e, m, re)) {
303 ans.append (b, m[0].first);
305 ans.append (uUScore);
306 } else if (m[2].matched) {
307 ans.append (percentHEX (*m[2].first));
320 ustring urlencode (const ustring& url) {
321 static uregex re ("(\\x00)|([^a-zA-Z0-9_.,/\x80-\xff-])");
323 return percentEncode (url, re);
327 ustring percentEncode (uiterator b, uiterator e) {
328 static uregex re ("(\\x00)|([^A-Za-z0-9_.~-])");
330 return percentEncode (b, e, re);
333 ustring percentEncode (const ustring& str) {
334 return percentEncode (str.begin (), str.end ());
337 ustring percentEncode_path (uiterator b, uiterator e) {
341 for (i = b; i < e; i ++) {
344 ans.append (percentEncode (b, i));
345 ans.append (CharConst ("/"));
350 ans.append (percentEncode (b, e));
355 ustring percentEncode_path (const ustring& str) {
356 return percentEncode_path (str.begin (), str.end ());
359 ustring percentDecode (const ustring& str) {
361 static uregex re ("%([0-9a-fA-F][0-9a-fA-F])|\\x00");
367 while (usearch (b, e, m, re)) {
368 if (b != m[0].first) {
369 ans.append (b, m[0].first);
372 int v = hex (*(m[1].first), *(m[1].first + 1));
383 return fixUTF8 (ans);
386 ustring cookieencode (const ustring& text) {
387 static uregex re ("([\\x00-\\x1f\\x7f])|([ ,;%\\x80-\\xff])");
389 return percentEncode (text.begin (), text.end (), re);
392 ustring cookiedecode (const ustring& text) {
397 static uregex re ("%([0-9a-fA-F])([0-9a-fA-F])");
401 while (usearch (b, e, m, re)) {
403 ans.append (ustring (b, m[0].first));
404 a = hex (*m[1].first, *m[2].first);
409 ans.append (ustring (b, e));
414 ustring clipColon (const ustring& text) {
418 for (i = 0; i < ans.size (); i ++) {
425 ustring dirPart (char* path) {
426 char* e = rindex (path, '/');
428 if (e && e != path) {
429 return ustring (path, e - path);
435 ustring dirPart (const ustring& path) {
436 ustring::size_type s = path.rfind ('/', path.size ());
438 if (s == ustring::npos) {
441 return ustring (path.begin (), path.begin () + s);
445 ustring filePart_osSafe (const ustring& path) {
447 static uregex re ("[^\\\\/]+$");
449 if (usearch (path, m, re)) {
450 return ustring (m[0].first, m[0].second);
456 void split (uiterator b, uiterator e, uregex& re, std::vector<ustring>& ans) {
457 Splitter sp (b, e, re);
460 ans.push_back (sp.cur ());
464 void splitE (uiterator b, uiterator e, uregex& re, std::vector<ustring>& ans) {
465 Splitter sp (b, e, re);
468 while (sp.nextSep ()) {
469 ans.push_back (sp.cur ());
471 ans.push_back (ustring (sp.begin (), sp.eol ()));
475 bool splitChar (uiterator b, uiterator e, uiterator::value_type ch, uiterator& m1) {
476 for (; b < e; b ++) {
486 ustring escape_re (const ustring& text) {
487 ustring::const_iterator b, e;
492 static uregex re ("[^\\x01- !\"#%',/0-9:;<=>@A-Z_`a-z~\\x7f-\\xff-]");
496 ans.reserve (text.size () + 16);
499 while (b != e && usearch (b, e, m, re)) {
501 ans.append (b, m[0].first);
503 buf[2] = hexchar ((c >> 4) & 0x0f);
504 buf[3] = hexchar (c & 0x0f);
513 ustring slashEncode (const ustring& text) {
514 ustring::const_iterator b, e;
519 static uregex re ("([\\x00-\\x1f\\x7f])|(\\\\)|(\")");
525 while (b != e && usearch (b, e, m, re)) {
527 ans.append (b, m[0].first);
532 ans.append (CharConst ("\\t"));
535 ans.append (CharConst ("\\r"));
538 ans.append (CharConst ("\\n"));
541 buf[2] = hexchar ((c >> 4) & 0x0f);
542 buf[3] = hexchar (c & 0x0f);
545 } else if (m[2].matched) {
546 ans.append (CharConst ("\\\\"));
547 } else if (m[3].matched) {
548 ans.append (CharConst ("\\\""));
559 ustring slashDecode (const ustring& text) {
560 ustring::const_iterator b, e;
564 static uregex re ("\\\\([0-7][0-7][0-7]|[\\x00-\\x7f])");
568 while (b != e && usearch (b, e, m, re)) {
570 ans.append (b, m[0].first);
575 ans.append (CharConst ("\t"));
578 ans.append (CharConst ("\r"));
581 ans.append (CharConst ("\n"));
584 if (m[0].second - m[0].first == 4) {
590 if (0 < c && c < 0x20)
603 unsigned long strtoul (const ustring& str) {
604 return strtoul (str.c_str (), NULL, 10);
607 unsigned long strtoul (const uiterator& b) {
608 return strtoul (&*b, NULL, 10);
611 long strtol (const ustring& str) {
612 return strtol (str.c_str (), NULL, 10);
615 double strtod (const ustring& str) {
616 return strtod (str.c_str (), NULL);
619 bool passMatch (const ustring& pass, const ustring& cpass) {
620 if (pass.length () == 0 || cpass.length () == 0)
622 return (strcmp (crypt (pass.c_str (), cpass.c_str ()), cpass.c_str ()) == 0);
625 ustring passCrypt (const ustring& pass) {
626 ustring salt = makeSalt ();
627 return ustring (crypt (pass.c_str (), salt.c_str ()));
630 size_t strLength (const ustring& src) {
642 void substring (const ustring& src, size_t idx, size_t len, int flen, ustring& ans) {
648 for (i = 0; i < idx && b < e; i ++)
652 for (i = 0; i < len && t < e; i ++)
660 static bool jssafe[] = {
661 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0--15
662 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 16--31
663 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1, // 32--47
664 1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0, // 48--63
665 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 64--79
666 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // 80--95
667 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 96--111
668 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // 112--127
671 ustring jsEncode (const ustring& str) {
678 ans.reserve (u.size () * 3);
681 for (i = 0; i < u.size (); i += 2) {
684 if (c == 0 && 0 < d && d < 127 && jssafe[d]) {
687 b[2] = hexchar ((c >> 4) & 0x0f);
688 b[3] = hexchar (c & 0x0f);
689 b[4] = hexchar ((d >> 4) & 0x0f);
690 b[5] = hexchar (d & 0x0f);
697 ustring filenameEncode (const ustring& text) {
698 static uregex re ("([\\x00-\\x1f\\x7f])|([^a-zA-Z0-9._-])|(^\\.+)");
699 Splitter sp (text, re);
703 if (text.length () == 0) {
704 throw (ustring (text).append (uErrorBadName));
706 ans.reserve (text.length () + 16);
708 if (sp.begin () < sp.end ())
709 ans.append (sp.begin (), sp.end ());
711 } else if (sp.match (2)) {
712 c = *sp.matchBegin (2);
714 ans.append (1, hexchar ((c >> 4) & 0x0f));
715 ans.append (1, hexchar (c & 0x0f));
716 } else if (sp.match (3)) {
717 for (c = sp.matchEnd (3) - sp.matchBegin (3); c > 0; c --) {
718 ans.append (CharConst (":2e"));
722 if (ans.length () > 250)
727 ustring filenameDecode (const ustring& text) {
728 static uregex re (":([0-9a-fA-F][0-9a-fA-F])");
729 Splitter sp (text, re);
733 ans.reserve (text.length ());
735 if (sp.begin () < sp.end ())
736 ans.append (sp.begin (), sp.end ());
738 c = hex (*(sp.matchBegin (1))) * 16 + hex (*(sp.matchBegin (1) + 1));
739 if (32 <= c && c < 256)
746 bool matchSkip (uiterator& b, uiterator e, const char* t, size_t s) {
747 if (e - b >= s && memcmp (t, &b[0], s) == 0) {
755 bool matchHead (uiterator& b, uiterator e, const char* t, size_t s) {
756 if (e - b >= s && memcmp (t, &b[0], s) == 0) {
763 bool matchHead (const ustring& str, const char* t, size_t s) {
764 if (str.length () >= s && memcmp (t, &*str.begin (), s) == 0) {
771 bool matchHead (const ustring& str, const ustring& head) {
772 if (str.length () >= head.length () && memcmp (&*str.begin (), &*head.begin (), head.length ()) == 0) {
779 bool match (uiterator b, uiterator e, const char* t, size_t s) {
780 if (e - b == s && memcmp (t, &b[0], s) == 0) {
787 bool match (const ustring& str, const char* t, size_t s) {
788 if (str.length () == s && memcmp (t, str.data (), s) == 0) {
795 bool match (uiterator b, uiterator e, const ustring& str) {
796 if (e - b == str.length () && memcmp (str.data (), &b[0], str.length ()) == 0) {
803 bool match (const ustring& str, const char* t, size_t s, const char* t2, size_t s2) {
804 if (match (str, t, s) || match (str, t2, s2)) {
811 ustring clipWhite (uiterator b, uiterator e) {
819 if (isblank (*(e - 1))) {
824 return ustring (b, e);
826 ustring clipWhite (const ustring& str) {
827 return clipWhite (str.begin (), str.end ());
830 ustring getenvString (const char* key) {
831 char* e = getenv (key);
839 ustring zeroPad (int n, const ustring& src) {
842 n = std::min (32, n);
843 m = n - src.length ();
855 bool wsearch (const ustring& text, boost::wsmatch& m, const ustring& reg, boost::wregex::flag_type reg_flags, boost::match_flag_type search_flags) {
857 std::wstring wtext = utow (text);
858 std::wstring wreg = utow (reg);
859 boost::wregex wre (wreg, reg_flags);
860 return regex_search (wtext, m, wre, search_flags);
861 } catch (boost::regex_error& err) {
862 throw (uErrorRegexp);
866 bool wsearch_env (MlEnv* mlenv, const ustring& text, const ustring& reg, boost::wregex::flag_type reg_flags, boost::match_flag_type search_flags) {
868 mlenv->regtext = utow (text);
869 std::wstring wreg = utow (reg);
870 boost::wregex wre (wreg, reg_flags);
871 return regex_search (mlenv->regtext, mlenv->regmatch, wre, search_flags);
872 } catch (boost::regex_error& err) {
873 throw (uErrorRegexp);
877 ustring wreplace (const ustring& text, const ustring& reg, const ustring& fmt, boost::wregex::flag_type reg_flags, boost::match_flag_type match_flags) {
879 std::wstring wtext = utow (text);
880 std::wstring wreg = utow (reg);
881 std::wstring wfmt = utow (fmt);
882 boost::wregex wre (wreg, reg_flags);
883 std::wstring ans = regex_replace (wtext, wre, wfmt, match_flags);
885 } catch (boost::regex_error& err) {
886 throw (uErrorRegexp);
890 ustring padEmpty (const ustring& name) {
892 return ustring (CharConst ("(null)"));
897 uint32_t hextoul (uiterator b, uiterator e) {
901 for (n = 0; n < 8 && b != e; n ++, b ++) {
902 ans = (ans << 4) + hex (*b);
907 ustring toCRLF (const ustring& str) {
908 uiterator b = str.begin ();
909 uiterator e = str.end ();
913 while (usearch (b, e, m, re_lf)) {
914 ans.append (b, m[0].first).append (uCRLF);
921 void skipSpace (uiterator& b, uiterator e) {
922 while (b < e && *b == ' ') {
927 static ustring::value_type toLower_ustring_value (ustring::value_type v) {
928 if ('A' <= v && v <= 'Z') {
929 return v - 'A' + 'a';
936 void toLower (ustring::iterator* b, ustring::iterator* e) {
937 transform (*b, *e, *b, toLower_ustring_value);
941 ustring toLower (uiterator b, uiterator e) {
946 for (; b < e; b ++, i++) {
947 *i = toLower_ustring_value (*b);
952 static void format_hex (ustring& ans, MNode* a, std::vector<ustring>& par, bool fcap) {
959 if (par.size () > 0) {
960 int p = strtol (par[0]);
966 ans.append (buf, snprintf (buf, 32, "%.*X", p, v));
968 ans.append (buf, snprintf (buf, 32, "%.*x", p, v));
971 ans.append (buf, snprintf (buf, 32, "%X", v));
973 ans.append (buf, snprintf (buf, 32, "%x", v));
977 static void format_hex (ustring& ans, MNode* a, std::vector<ustring>& par) {
978 format_hex (ans, a, par, false);
981 static void format_HEX (ustring& ans, MNode* a, std::vector<ustring>& par) {
982 format_hex (ans, a, par, true);
985 static void format_int_sub (ustring& ans, MNode* a, std::vector<ustring>& par, bool pad0 = false) {
993 if (par.size () > 0) {
997 if (match (par[0], CharConst ("comma")) || match (par[0], CharConst ("c"))) {
998 ans.append (c3 (to_ustring (v)));
1000 int p = strtol (par[0]);
1005 for (int i = 1; i < par.size (); i ++) {
1006 if (match (par[i], CharConst ("clip"))) {
1008 } else if (match (par[i], CharConst ("0"))) {
1010 } else if (match (par[i], CharConst ("comma")) || match (par[i], CharConst ("c"))) {
1013 throw (par[i] + uErrorBadParam);
1017 s = snprintf (buf, 32, "%.*d", p, v);
1019 s = snprintf (buf, 32, "%*d", p, v);
1021 ans.append (buf + s - p, p);
1022 else if (! fclip && fc3)
1023 ans.append (c3 (ustring (buf, s)));
1025 ans.append (buf, s);
1028 ans.append (to_ustring (v));
1032 static void format_int (ustring& ans, MNode* a, std::vector<ustring>& par) {
1033 format_int_sub (ans, a, par);
1036 static void format_int0 (ustring& ans, MNode* a, std::vector<ustring>& par) {
1037 format_int_sub (ans, a, par, true);
1040 static void format_int (ustring& ans, MNode* a, int c, bool pad0 = false) {
1052 s = snprintf (buf, 32, "%.*d", c, v);
1054 s = snprintf (buf, 32, "%*d", c, v);
1056 ans.append (buf + s - c, c);
1058 ans.append (buf, s);
1060 ans.append (to_ustring (v));
1064 static void format_float (ustring& ans, MNode* a, std::vector<ustring>& par) {
1069 if (par.size () > 0)
1070 p1 = strtol (par[0]);
1071 if (par.size () > 1)
1072 p2 = strtol (par[1]);
1081 ans.append (buf, snprintf (buf, 32, "%*.*lf", p1, p2, to_double (a)));
1084 static void format_string (ustring& ans, MNode* a, std::vector<ustring>& par) {
1086 bool fright = false;
1087 ustring u = to_string (a);
1089 if (par.size () > 0)
1090 p = strtol (par[0]);
1093 if (par.size () > 1) {
1094 if (match (par[1], CharConst ("right")) || match (par[1], CharConst ("r")))
1097 throw (par[1] + uErrorBadParam);
1101 ans.append (p - u.size (), ' ').append (u);
1106 ans.append (u).append (p - u.size (), ' ');
1112 static void format_literal (ustring& ans, MNode* a, const char* list[], int offset, size_t size) {
1116 v = to_int (a) - offset;
1117 if (0 <= v && v < size)
1118 ans.append (list[v]);
1122 static const char* mstr_a[] = {
1123 "Jan", "Feb", "Mar", "Apr",
1124 "May", "Jun", "Jul", "Aug",
1125 "Sep", "Oct", "Nov", "Dec"
1127 static const char* mstr[] = {
1128 "January", "February", "March", "April",
1129 "May", "June", "July", "August",
1130 "September", "October", "November", "December"
1132 static void format_month (ustring& ans, MNode* a, std::vector<ustring>& par) {
1133 format_literal (ans, a, mstr_a, 1, 12);
1136 static void format_Month (ustring& ans, MNode* a, std::vector<ustring>& par) {
1137 format_literal (ans, a, mstr, 1, 12);
1140 static const char* WStr_a[] = {
1141 "Sun", "Mon", "Tue", "Wed",
1145 static const char* WStr[] = {
1146 "Sunday", "Monday", "Tuesday", "Wednesday",
1147 "Thursday", "Friday", "Saturday"
1150 static void format_week (ustring& ans, MNode* a, std::vector<ustring>& par) {
1151 format_literal (ans, a, WStr_a, 0, 7);
1154 static void format_Week (ustring& ans, MNode* a, std::vector<ustring>& par) {
1155 format_literal (ans, a, WStr, 0, 7);
1158 ustring formatString (const ustring& format, boost::ptr_vector<MNodePtr>& par) {
1164 static uregex re ("\\$\\{([1-9][0-9]*)(:([a-zA-Z][a-zA-Z0-9]*)(:([0-9a-z.:]+))?)?\\}");
1168 void (*fn)(ustring& ans, MNode* a, std::vector<ustring>& par);
1170 {CharConst ("hex"), format_hex},
1171 {CharConst ("HEX"), format_HEX},
1172 {CharConst ("int"), format_int},
1173 {CharConst ("int0"), format_int0},
1174 {CharConst ("float"), format_float},
1175 {CharConst ("string"), format_string},
1176 {CharConst ("month"), format_month},
1177 {CharConst ("Month"), format_Month},
1178 {CharConst ("week"), format_week},
1179 {CharConst ("Week"), format_Week},
1183 b = format.begin ();
1185 while (usearch (b, e, m, re)) {
1186 ans.append (b, m[0].first);
1188 i = strtoul (ustring (m[1].first, m[1].second)) - 1;
1189 if (i < par.size ()) {
1194 if (! m[2].matched) {
1196 ans.append (to_string (a));
1198 std::vector<ustring> fpar;
1201 split (m[5].first, m[5].second, re_colon, fpar);
1202 for (i = 0; formatFunc[i].name; i ++) {
1203 if (match (m[3].first, m[3].second, formatFunc[i].name, formatFunc[i].namelen)) {
1204 (*formatFunc[i].fn) (ans, a, fpar);
1208 ans.append (m[0].first, m[0].second);
1217 static ustring colpad0 (int n, const ustring& src) {
1221 n = std::min (32, n);
1222 m = n - src.length ();
1226 ans.append (m, '0');
1229 } else if (m == 0) {
1232 return ustring (src.end () - n, src.end ());
1241 ${M:2}, ${M}, ${M:name}, ${M:ab}
1249 //ustring formatDateString (const ustring& format, time_t tm) {
1250 ustring formatDateString (const ustring& format, struct tm& v) {
1256 // static uregex re ("\\$\\{([YMDhmsWw])(:([0-9]))?\\}");
1257 static uregex re ("\\$\\{(([YMDhmsWwo])(:([0-9]))?|M:((name)|(ab)|(abname)))\\}");
1258 std::vector<ustring> fpar;
1260 // localtime_r (&tm, &v);
1261 b = format.begin ();
1263 while (usearch (b, e, m, re)) {
1264 ans.append (b, m[0].first);
1267 if (m[6].matched) { // name
1268 ans.append (mstr[v.tm_mon]);
1269 } else if (m[7].matched || m[8].matched) { // abname
1270 ans.append (mstr_a[v.tm_mon]);
1273 // if (m[2].matched) {
1275 // pc = strtol (ustring (m[3].first, m[3].second));
1276 pc = strtol (ustring (m[4].first, m[4].second));
1280 // switch (*m[1].first) {
1281 switch (*m[2].first) {
1283 ans.append (colpad0 (pc, to_ustring (v.tm_year + 1900)));
1286 ans.append (colpad0 (pc, to_ustring (v.tm_mon + 1)));
1289 ans.append (colpad0 (pc, to_ustring (v.tm_mday)));
1292 ans.append (colpad0 (pc, to_ustring (v.tm_hour)));
1295 ans.append (colpad0 (pc, to_ustring (v.tm_min)));
1298 ans.append (colpad0 (pc, to_ustring (v.tm_sec)));
1301 ans.append (WStr [v.tm_wday]);
1304 ans.append (WStr_a [v.tm_wday]);
1309 if (v.tm_gmtoff < 0) {
1310 h = - v.tm_gmtoff / 60;
1313 ans.append (CharConst ("-")).append (colpad0 (4, to_ustring (h * 100 + m)));
1315 h = v.tm_gmtoff / 60;
1318 ans.append (CharConst ("+")).append (colpad0 (4, to_ustring (h * 100 + m)));
1330 ustring toLower (const ustring& str) {
1331 return boost::to_lower_copy (str);
1334 ustring toUpper (const ustring& str) {
1335 return boost::to_upper_copy (str);
1338 ustring hexEncode (const ustring& data) {
1342 ans.reserve (data.length () * 2);
1345 for (; b < e; b ++) {
1346 ans.append (1, hexchar ((*b >> 4) & 0x0f));
1347 ans.append (1, hexchar (*b & 0x0f));