OSDN Git Service

use boost_1_56_0 and build by VS2013
[yamy/yamy.git] / stringtool.cpp
index 5837626..5357d90 100644 (file)
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// stringtool.cpp
-
-
-#include "stringtool.h"
-#include "array.h"
-#include <locale>
-#include <malloc.h>
-#include <mbstring.h>
-
-
-/* ************************************************************************** *
-   
-STRLCPY(3)                OpenBSD Programmer's Manual               STRLCPY(3)
-
-NAME
-     strlcpy, strlcat - size-bounded string copying and concatenation
-
-
-
-SYNOPSIS
-     #include <string.h>
-
-     size_t
-     strlcpy(char *dst, const char *src, size_t size);
-
-     size_t
-     strlcat(char *dst, const char *src, size_t size);
-
-DESCRIPTION
-     The strlcpy() and strlcat() functions copy and concatenate strings re-
-     spectively.  They are designed to be safer, more consistent, and less er-
-     ror prone replacements for strncpy(3) and strncat(3).  Unlike those func-
-     tions, strlcpy() and strlcat() take the full size of the buffer (not just
-     the length) and guarantee to NUL-terminate the result (as long as size is
-     larger than 0).  Note that you should include a byte for the NUL in size.
-
-     The strlcpy() function copies up to size - 1 characters from the NUL-ter-
-     minated string src to dst, NUL-terminating the result.
-
-     The strlcat() function appends the NUL-terminated string src to the end
-     of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
-     nating the result.
-
-RETURN VALUES
-     The strlcpy() and strlcat() functions return the total length of the
-     string they tried to create.  For strlcpy() that means the length of src.
-     For strlcat() that means the initial length of dst plus the length of
-     src. While this may seem somewhat confusing it was done to make trunca-
-     tion detection simple.
-
-EXAMPLES
-     The following code fragment illustrates the simple case:
-
-           char *s, *p, buf[BUFSIZ];
-
-           ...
-
-           (void)strlcpy(buf, s, sizeof(buf));
-           (void)strlcat(buf, p, sizeof(buf));
-
-     To detect truncation, perhaps while building a pathname, something like
-     the following might be used:
-
-           char *dir, *file, pname[MAXPATHNAMELEN];
-
-           ...
-
-           if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
-                   goto toolong;
-           if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
-                   goto toolong;
-
-     Since we know how many characters we copied the first time, we can speed
-     things up a bit by using a copy instead on an append:
-
-           char *dir, *file, pname[MAXPATHNAMELEN];
-           size_t n;
-
-           ...
-
-           n = strlcpy(pname, dir, sizeof(pname));
-           if (n >= sizeof(pname))
-                   goto toolong;
-           if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname)-n)
-                   goto toolong;
-
-     However, one may question the validity of such optimizations, as they de-
-     feat the whole purpose of strlcpy() and strlcat().  As a matter of fact,
-     the first version of this manual page got it wrong.
-
-SEE ALSO
-     snprintf(3),  strncat(3),  strncpy(3)
-
-OpenBSD 2.6                      June 22, 1998                               2
-
-
--------------------------------------------------------------------------------
-
-Source: OpenBSD 2.6 man pages. Copyright: Portions are copyrighted by BERKELEY
-SOFTWARE DESIGN, INC., The Regents of the University of California,
-Massachusetts Institute of Technology, Free Software Foundation, FreeBSD Inc.,
-and others.
-
-* ************************************************************************** */
-
-
-// copy
-template <class T>
-static inline size_t xstrlcpy(T *o_dest, const T *i_src, size_t i_destSize)
-{
-  T *d = o_dest;
-  const T *s = i_src;
-  size_t n = i_destSize;
-
-  ASSERT( o_dest != NULL );
-  ASSERT( i_src != NULL );
-
-  // Copy as many bytes as will fit
-  if (n != 0 && --n != 0)
-  {
-    do
-    {
-      if ((*d++ = *s++) == 0)
-       break;
-    } while (--n != 0);
-  }
-
-  // Not enough room in o_dest, add NUL and traverse rest of i_src
-  if (n == 0)
-  {
-    if (i_destSize != 0)
-      *d = T();                                        // NUL-terminate o_dest
-    while (*s++)
-      ;
-  }
-
-  return (s - i_src - 1);                      // count does not include NUL
-}
-
-
-// copy
-size_t strlcpy(char *o_dest, const char *i_src, size_t i_destSize)
-{
-  return xstrlcpy(o_dest, i_src, i_destSize);
-}
-
-
-// copy
-size_t wcslcpy(wchar_t *o_dest, const wchar_t *i_src, size_t i_destSize)
-{
-  return xstrlcpy(o_dest, i_src, i_destSize);
-}
-
-
-// copy 
-size_t mbslcpy(unsigned char *o_dest, const unsigned char *i_src,
-              size_t i_destSize)
-{
-  unsigned char *d = o_dest;
-  const unsigned char *s = i_src;
-  size_t n = i_destSize;
-
-  ASSERT( o_dest != NULL );
-  ASSERT( i_src != NULL );
-
-  if (n == 0)
-    return strlen(reinterpret_cast<const char *>(i_src));
-  
-  // Copy as many bytes as will fit
-  for (-- n; *s && 0 < n; -- n)
-  {
-    if (_ismbblead(*s))
-    {
-      if (!(s[1] && 2 <= n))
-       break;
-      *d++ = *s++;
-      -- n;
-    }
-    *d++ = *s++;
-  }
-  *d = '\0';
-
-  for (; *s; ++ s)
-    ;
-  
-  return s - i_src;
-}
-
-
-/// stream output
-tostream &operator<<(tostream &i_ost, const tstringq &i_data)
-{
-  i_ost << _T("\"");
-  for (const _TCHAR *s = i_data.c_str(); *s; ++ s)
-  {
-    switch (*s)
-    {
-      case _T('\a'): i_ost << _T("\\a"); break;
-      case _T('\f'): i_ost << _T("\\f"); break;
-      case _T('\n'): i_ost << _T("\\n"); break;
-      case _T('\r'): i_ost << _T("\\r"); break;
-      case _T('\t'): i_ost << _T("\\t"); break;
-      case _T('\v'): i_ost << _T("\\v"); break;
-      case _T('"'): i_ost << _T("\\\""); break;
-      default:
-       if (_istlead(*s))
-       {
-         _TCHAR buf[3] = { s[0], s[1], 0 };
-         i_ost << buf;
-         ++ s;
-       }
-       else if (_istprint(*s))
-       {
-         _TCHAR buf[2] = { *s, 0 };
-         i_ost << buf;
-       }
-       else
-       {
-         i_ost << _T("\\x");
-         _TCHAR buf[5];
-#ifdef _UNICODE
-         _sntprintf(buf, NUMBER_OF(buf), _T("%04x"), *s);
-#else
-         _sntprintf(buf, NUMBER_OF(buf), _T("%02x"), *s);
-#endif
-         i_ost << buf;
-       }
-       break;
-    }
-  }
-  i_ost << _T("\"");
-  return i_ost;
-}
-
-
-// interpret meta characters such as \n
-tstring interpretMetaCharacters(const _TCHAR *i_str, size_t i_len,
-                               const _TCHAR *i_quote,
-                               bool i_doesUseRegexpBackReference)
-{
-  // interpreted string is always less than i_len
-  Array<_TCHAR> result(i_len + 1);
-  // destination
-  _TCHAR *d = result.get();
-  // end pointer
-  const _TCHAR *end = i_str + i_len;
-  
-  while (i_str < end && *i_str)
-  {
-    if (*i_str != _T('\\'))
-    {
-      if (_istlead(*i_str) && *(i_str + 1) && i_str + 1 < end)
-       *d++ = *i_str++;
-      *d++ = *i_str++;
-    }
-    else if (*(i_str + 1) != _T('\0'))
-    {
-      i_str ++;
-      if (i_quote && _tcschr(i_quote, *i_str))
-       *d++ = *i_str++;
-      else
-       switch (*i_str)
-       {
-         case _T('a'): *d++ = _T('\x07'); i_str ++; break;
-           //case _T('b'): *d++ = _T('\b'); i_str ++; break;
-         case _T('e'): *d++ = _T('\x1b'); i_str ++; break;
-         case _T('f'): *d++ = _T('\f'); i_str ++; break;
-         case _T('n'): *d++ = _T('\n'); i_str ++; break;
-         case _T('r'): *d++ = _T('\r'); i_str ++; break;
-         case _T('t'): *d++ = _T('\t'); i_str ++; break;
-         case _T('v'): *d++ = _T('\v'); i_str ++; break;
-           //case _T('?'): *d++ = _T('\x7f'); i_str ++; break;
-           //case _T('_'): *d++ = _T(' '); i_str ++; break;
-           //case _T('\\'): *d++ = _T('\\'); i_str ++; break;
-         case _T('\''): *d++ = _T('\''); i_str ++; break;
-         case _T('"'): *d++ = _T('"'); i_str ++; break;
-         case _T('\\'): *d++ = _T('\\'); i_str ++; break;
-         case _T('c'): // control code, for example '\c[' is escape: '\x1b'
-           i_str ++;
-           if (i_str < end && *i_str)
-           {
-             static const _TCHAR *ctrlchar =
-               _T("@ABCDEFGHIJKLMNO")
-               _T("PQRSTUVWXYZ[\\]^_")
-               _T("@abcdefghijklmno")
-               _T("pqrstuvwxyz@@@@?");
-             static const _TCHAR *ctrlcode =
-               _T("\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17")
-               _T("\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37")
-               _T("\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17")
-               _T("\20\21\22\23\24\25\26\27\30\31\32\00\00\00\00\177");
-             if (const _TCHAR *c = _tcschr(ctrlchar, *i_str))
-               *d++ = ctrlcode[c - ctrlchar], i_str ++;
-           }
-           break;
-         case _T('x'): case _T('X'):
-         {
-           i_str ++;
-           static const _TCHAR *hexchar = _T("0123456789ABCDEFabcdef");
-           static int hexvalue[] = { 0, 1, 2, 3, 4, 5 ,6, 7, 8, 9,
-                                     10, 11, 12, 13, 14, 15,
-                                     10, 11, 12, 13, 14, 15, };
-           bool brace = false;
-           if (i_str < end && *i_str == _T('{'))
-           {
-             i_str ++;
-             brace = true;
-           }
-           int n = 0;
-           for (; i_str < end && *i_str; i_str ++)
-             if (const _TCHAR *c = _tcschr(hexchar, *i_str))
-               n = n * 16 + hexvalue[c - hexchar];
-             else
-               break;
-           if (i_str < end && *i_str == _T('}') && brace)
-             i_str ++;
-           if (0 < n)
-             *d++ = static_cast<_TCHAR>(n);
-           break;
-         }
-         case _T('1'): case _T('2'): case _T('3'):
-         case _T('4'): case _T('5'): case _T('6'): case _T('7'):
-           if (i_doesUseRegexpBackReference)
-             goto case_default;
-           // fall through
-         case _T('0'):
-         {
-           static const _TCHAR *octalchar = _T("01234567");
-           static int octalvalue[] = { 0, 1, 2, 3, 4, 5 ,6, 7, };
-           int n = 0;
-           for (; i_str < end && *i_str; i_str ++)
-             if (const _TCHAR *c = _tcschr(octalchar, *i_str))
-               n = n * 8 + octalvalue[c - octalchar];
-             else
-               break;
-           if (0 < n)
-             *d++ = static_cast<_TCHAR>(n);
-           break;
-         }
-         default:
-         case_default:
-           *d++ = _T('\\');
-           if (_istlead(*i_str) && *(i_str + 1) && i_str + 1 < end)
-             *d++ = *i_str++;
-           *d++ = *i_str++;
-           break;
-       }
-    }
-  }
-  *d =_T('\0');
-  return result.get();
-}
-
-
-// add session id to i_str
-tstring addSessionId(const _TCHAR *i_str)
-{
-    DWORD sessionId;
-    tstring s(i_str);
-    if (ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) {
-       _TCHAR buf[20];
-       _sntprintf(buf, NUMBER_OF(buf), _T("%u"), sessionId);
-       s += buf;
-    }
-    return s;
-}
-
-
-#ifdef _MBCS
-// escape regexp special characters in MBCS trail bytes
-std::string guardRegexpFromMbcs(const char *i_str)
-{
-  size_t len = strlen(i_str);
-  Array<char> buf(len * 2 + 1);
-  char *p = buf.get();
-  while (*i_str)
-  {
-    if (_ismbblead(static_cast<u_char>(*i_str)) && i_str[1])
-    {
-      *p ++ = *i_str ++;
-      if (strchr(".*?+(){}[]^$", *i_str))
-       *p ++ = '\\';
-    }
-    *p ++ = *i_str ++;
-  }
-  return std::string(buf.get(), p);
-}
-#endif // !_MBCS
-
-
-// converter
-std::wstring to_wstring(const std::string &i_str)
-{
-  size_t size = mbstowcs(NULL, i_str.c_str(), i_str.size() + 1);
-  if (size == (size_t)-1)
-    return std::wstring();
-  Array<wchar_t> result(size + 1);
-  mbstowcs(result.get(), i_str.c_str(), i_str.size() + 1);
-  return std::wstring(result.get());
-}
-
-
-// converter
-std::string to_string(const std::wstring &i_str)
-{
-  size_t size = wcstombs(NULL, i_str.c_str(), i_str.size() + 1);
-  if (size == (size_t)-1)
-    return std::string();
-  Array<char> result(size + 1);
-  wcstombs(result.get(), i_str.c_str(), i_str.size() + 1);
-  return std::string(result.get());
-}
-
-
-/// stream output
-tostream &operator<<(tostream &i_ost, const tregex &i_data)
-{
-  return i_ost << i_data.str();
-}
-
-
-/// get lower string
-tstring toLower(const tstring &i_str)
-{
-  tstring str(i_str);
-  for (size_t i = 0; i < str.size(); ++ i)
-  {
-    if (_ismbblead(str[i]))
-      ++ i;
-    else
-      str[i] = tolower(str[i]);
-  }
-  return str;
-}
-
-
-// convert wstring to UTF-8
-std::string to_UTF_8(const std::wstring &i_str)
-{
-  // 0xxxxxxx: 00-7F
-  // 110xxxxx 10xxxxxx: 0080-07FF
-  // 1110xxxx 10xxxxxx 10xxxxxx: 0800 - FFFF
-
-  int size = 0;
-  
-  // count needed buffer size
-  for (std::wstring::const_iterator i = i_str.begin(); i != i_str.end(); ++ i)
-  {
-    if (0x0000 <= *i && *i <= 0x007f)
-      size += 1;
-    else if (0x0080 <= *i && *i <= 0x07ff)
-      size += 2;
-    else if (0x0800 <= *i && *i <= 0xffff)
-      size += 3;
-  }
-
-  Array<char> result(size);
-  int ri = 0;
-  
-  // make UTF-8
-  for (std::wstring::const_iterator i = i_str.begin(); i != i_str.end(); ++ i)
-  {
-    if (0x0000 <= *i && *i <= 0x007f)
-      result[ri ++] = static_cast<char>(*i);
-    else if (0x0080 <= *i && *i <= 0x07ff)
-    {
-      result[ri ++] = static_cast<char>(((*i & 0x0fc0) >>  6) | 0xc0);
-      result[ri ++] = static_cast<char>(( *i & 0x003f       ) | 0x80);
-    }
-    else if (0x0800 <= *i && *i <= 0xffff)
-    {
-      result[ri ++] = static_cast<char>(((*i & 0xf000) >> 12) | 0xe0);
-      result[ri ++] = static_cast<char>(((*i & 0x0fc0) >>  6) | 0x80);
-      result[ri ++] = static_cast<char>(( *i & 0x003f       ) | 0x80);
-    }
-  }
-
-  return std::string(result.begin(), result.end());
-}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// stringtool.cpp\r
+\r
+\r
+#include "stringtool.h"\r
+#include "array.h"\r
+#include <locale>\r
+#include <malloc.h>\r
+#include <mbstring.h>\r
+\r
+\r
+/* ************************************************************************** *\r
+\r
+STRLCPY(3)                OpenBSD Programmer's Manual               STRLCPY(3)\r
+\r
+NAME\r
+     strlcpy, strlcat - size-bounded string copying and concatenation\r
+\r
+\r
+\r
+SYNOPSIS\r
+     #include <string.h>\r
+\r
+     size_t\r
+     strlcpy(char *dst, const char *src, size_t size);\r
+\r
+     size_t\r
+     strlcat(char *dst, const char *src, size_t size);\r
+\r
+DESCRIPTION\r
+     The strlcpy() and strlcat() functions copy and concatenate strings re-\r
+     spectively.  They are designed to be safer, more consistent, and less er-\r
+     ror prone replacements for strncpy(3) and strncat(3).  Unlike those func-\r
+     tions, strlcpy() and strlcat() take the full size of the buffer (not just\r
+     the length) and guarantee to NUL-terminate the result (as long as size is\r
+     larger than 0).  Note that you should include a byte for the NUL in size.\r
+\r
+     The strlcpy() function copies up to size - 1 characters from the NUL-ter-\r
+     minated string src to dst, NUL-terminating the result.\r
+\r
+     The strlcat() function appends the NUL-terminated string src to the end\r
+     of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-\r
+     nating the result.\r
+\r
+RETURN VALUES\r
+     The strlcpy() and strlcat() functions return the total length of the\r
+     string they tried to create.  For strlcpy() that means the length of src.\r
+     For strlcat() that means the initial length of dst plus the length of\r
+     src. While this may seem somewhat confusing it was done to make trunca-\r
+     tion detection simple.\r
+\r
+EXAMPLES\r
+     The following code fragment illustrates the simple case:\r
+\r
+           char *s, *p, buf[BUFSIZ];\r
+\r
+           ...\r
+\r
+           (void)strlcpy(buf, s, sizeof(buf));\r
+           (void)strlcat(buf, p, sizeof(buf));\r
+\r
+     To detect truncation, perhaps while building a pathname, something like\r
+     the following might be used:\r
+\r
+           char *dir, *file, pname[MAXPATHNAMELEN];\r
+\r
+           ...\r
+\r
+           if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))\r
+                   goto toolong;\r
+           if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))\r
+                   goto toolong;\r
+\r
+     Since we know how many characters we copied the first time, we can speed\r
+     things up a bit by using a copy instead on an append:\r
+\r
+           char *dir, *file, pname[MAXPATHNAMELEN];\r
+           size_t n;\r
+\r
+           ...\r
+\r
+           n = strlcpy(pname, dir, sizeof(pname));\r
+           if (n >= sizeof(pname))\r
+                   goto toolong;\r
+           if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname)-n)\r
+                   goto toolong;\r
+\r
+     However, one may question the validity of such optimizations, as they de-\r
+     feat the whole purpose of strlcpy() and strlcat().  As a matter of fact,\r
+     the first version of this manual page got it wrong.\r
+\r
+SEE ALSO\r
+     snprintf(3),  strncat(3),  strncpy(3)\r
+\r
+OpenBSD 2.6                      June 22, 1998                               2\r
+\r
+\r
+-------------------------------------------------------------------------------\r
+\r
+Source: OpenBSD 2.6 man pages. Copyright: Portions are copyrighted by BERKELEY\r
+SOFTWARE DESIGN, INC., The Regents of the University of California,\r
+Massachusetts Institute of Technology, Free Software Foundation, FreeBSD Inc.,\r
+and others.\r
+\r
+* ************************************************************************** */\r
+\r
+\r
+// copy\r
+template <class T>\r
+static inline size_t xstrlcpy(T *o_dest, const T *i_src, size_t i_destSize)\r
+{\r
+       T *d = o_dest;\r
+       const T *s = i_src;\r
+       size_t n = i_destSize;\r
+\r
+       ASSERT( o_dest != NULL );\r
+       ASSERT( i_src != NULL );\r
+\r
+       // Copy as many bytes as will fit\r
+       if (n != 0 && --n != 0) {\r
+               do {\r
+                       if ((*d++ = *s++) == 0)\r
+                               break;\r
+               } while (--n != 0);\r
+       }\r
+\r
+       // Not enough room in o_dest, add NUL and traverse rest of i_src\r
+       if (n == 0) {\r
+               if (i_destSize != 0)\r
+                       *d = T();                                       // NUL-terminate o_dest\r
+               while (*s++)\r
+                       ;\r
+       }\r
+\r
+       return (s - i_src - 1);                 // count does not include NUL\r
+}\r
+\r
+\r
+// copy\r
+size_t strlcpy(char *o_dest, const char *i_src, size_t i_destSize)\r
+{\r
+       return xstrlcpy(o_dest, i_src, i_destSize);\r
+}\r
+\r
+\r
+// copy\r
+size_t wcslcpy(wchar_t *o_dest, const wchar_t *i_src, size_t i_destSize)\r
+{\r
+       return xstrlcpy(o_dest, i_src, i_destSize);\r
+}\r
+\r
+\r
+// copy\r
+size_t mbslcpy(unsigned char *o_dest, const unsigned char *i_src,\r
+                          size_t i_destSize)\r
+{\r
+       unsigned char *d = o_dest;\r
+       const unsigned char *s = i_src;\r
+       size_t n = i_destSize;\r
+\r
+       ASSERT( o_dest != NULL );\r
+       ASSERT( i_src != NULL );\r
+\r
+       if (n == 0)\r
+               return strlen(reinterpret_cast<const char *>(i_src));\r
+\r
+       // Copy as many bytes as will fit\r
+       for (-- n; *s && 0 < n; -- n) {\r
+               if (_ismbblead(*s)) {\r
+                       if (!(s[1] && 2 <= n))\r
+                               break;\r
+                       *d++ = *s++;\r
+                       -- n;\r
+               }\r
+               *d++ = *s++;\r
+       }\r
+       *d = '\0';\r
+\r
+       for (; *s; ++ s)\r
+               ;\r
+\r
+       return s - i_src;\r
+}\r
+\r
+\r
+/// stream output\r
+tostream &operator<<(tostream &i_ost, const tstringq &i_data)\r
+{\r
+       i_ost << _T("\"");\r
+       for (const _TCHAR *s = i_data.c_str(); *s; ++ s) {\r
+               switch (*s) {\r
+               case _T('\a'):\r
+                       i_ost << _T("\\a");\r
+                       break;\r
+               case _T('\f'):\r
+                       i_ost << _T("\\f");\r
+                       break;\r
+               case _T('\n'):\r
+                       i_ost << _T("\\n");\r
+                       break;\r
+               case _T('\r'):\r
+                       i_ost << _T("\\r");\r
+                       break;\r
+               case _T('\t'):\r
+                       i_ost << _T("\\t");\r
+                       break;\r
+               case _T('\v'):\r
+                       i_ost << _T("\\v");\r
+                       break;\r
+               case _T('"'):\r
+                       i_ost << _T("\\\"");\r
+                       break;\r
+               default:\r
+                       if (_istlead(*s)) {\r
+                               _TCHAR buf[3] = { s[0], s[1], 0 };\r
+                               i_ost << buf;\r
+                               ++ s;\r
+                       } else if (_istprint(*s)) {\r
+                               _TCHAR buf[2] = { *s, 0 };\r
+                               i_ost << buf;\r
+                       } else {\r
+                               i_ost << _T("\\x");\r
+                               _TCHAR buf[5];\r
+#ifdef _UNICODE\r
+                               _sntprintf(buf, NUMBER_OF(buf), _T("%04x"), *s);\r
+#else\r
+                               _sntprintf(buf, NUMBER_OF(buf), _T("%02x"), *s);\r
+#endif\r
+                               i_ost << buf;\r
+                       }\r
+                       break;\r
+               }\r
+       }\r
+       i_ost << _T("\"");\r
+       return i_ost;\r
+}\r
+\r
+\r
+// interpret meta characters such as \n\r
+tstring interpretMetaCharacters(const _TCHAR *i_str, size_t i_len,\r
+                                                               const _TCHAR *i_quote,\r
+                                                               bool i_doesUseRegexpBackReference)\r
+{\r
+       // interpreted string is always less than i_len\r
+       Array<_TCHAR> result(i_len + 1);\r
+       // destination\r
+       _TCHAR *d = result.get();\r
+       // end pointer\r
+       const _TCHAR *end = i_str + i_len;\r
+\r
+       while (i_str < end && *i_str) {\r
+               if (*i_str != _T('\\')) {\r
+                       if (_istlead(*i_str) && *(i_str + 1) && i_str + 1 < end)\r
+                               *d++ = *i_str++;\r
+                       *d++ = *i_str++;\r
+               } else if (*(i_str + 1) != _T('\0')) {\r
+                       i_str ++;\r
+                       if (i_quote && _tcschr(i_quote, *i_str))\r
+                               *d++ = *i_str++;\r
+                       else\r
+                               switch (*i_str) {\r
+                               case _T('a'):\r
+                                       *d++ = _T('\x07');\r
+                                       i_str ++;\r
+                                       break;\r
+                                       //case _T('b'): *d++ = _T('\b'); i_str ++; break;\r
+                               case _T('e'):\r
+                                       *d++ = _T('\x1b');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('f'):\r
+                                       *d++ = _T('\f');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('n'):\r
+                                       *d++ = _T('\n');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('r'):\r
+                                       *d++ = _T('\r');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('t'):\r
+                                       *d++ = _T('\t');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('v'):\r
+                                       *d++ = _T('\v');\r
+                                       i_str ++;\r
+                                       break;\r
+                                       //case _T('?'): *d++ = _T('\x7f'); i_str ++; break;\r
+                                       //case _T('_'): *d++ = _T(' '); i_str ++; break;\r
+                                       //case _T('\\'): *d++ = _T('\\'); i_str ++; break;\r
+                               case _T('\''):\r
+                                       *d++ = _T('\'');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('"'):\r
+                                       *d++ = _T('"');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('\\'):\r
+                                       *d++ = _T('\\');\r
+                                       i_str ++;\r
+                                       break;\r
+                               case _T('c'): // control code, for example '\c[' is escape: '\x1b'\r
+                                       i_str ++;\r
+                                       if (i_str < end && *i_str) {\r
+                                               static const _TCHAR *ctrlchar =\r
+                                                       _T("@ABCDEFGHIJKLMNO")\r
+                                                       _T("PQRSTUVWXYZ[\\]^_")\r
+                                                       _T("@abcdefghijklmno")\r
+                                                       _T("pqrstuvwxyz@@@@?");\r
+                                               static const _TCHAR *ctrlcode =\r
+                                                       _T("\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17")\r
+                                                       _T("\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37")\r
+                                                       _T("\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17")\r
+                                                       _T("\20\21\22\23\24\25\26\27\30\31\32\00\00\00\00\177");\r
+                                               if (const _TCHAR *c = _tcschr(ctrlchar, *i_str))\r
+                                                       *d++ = ctrlcode[c - ctrlchar], i_str ++;\r
+                                       }\r
+                                       break;\r
+                               case _T('x'):\r
+                               case _T('X'): {\r
+                                       i_str ++;\r
+                                       static const _TCHAR *hexchar = _T("0123456789ABCDEFabcdef");\r
+                                       static int hexvalue[] = { 0, 1, 2, 3, 4, 5 ,6, 7, 8, 9,\r
+                                                                                         10, 11, 12, 13, 14, 15,\r
+                                                                                         10, 11, 12, 13, 14, 15,\r
+                                                                                       };\r
+                                       bool brace = false;\r
+                                       if (i_str < end && *i_str == _T('{')) {\r
+                                               i_str ++;\r
+                                               brace = true;\r
+                                       }\r
+                                       int n = 0;\r
+                                       for (; i_str < end && *i_str; i_str ++)\r
+                                               if (const _TCHAR *c = _tcschr(hexchar, *i_str))\r
+                                                       n = n * 16 + hexvalue[c - hexchar];\r
+                                               else\r
+                                                       break;\r
+                                       if (i_str < end && *i_str == _T('}') && brace)\r
+                                               i_str ++;\r
+                                       if (0 < n)\r
+                                               *d++ = static_cast<_TCHAR>(n);\r
+                                       break;\r
+                               }\r
+                               case _T('1'):\r
+                               case _T('2'):\r
+                               case _T('3'):\r
+                               case _T('4'):\r
+                               case _T('5'):\r
+                               case _T('6'):\r
+                               case _T('7'):\r
+                                       if (i_doesUseRegexpBackReference)\r
+                                               goto case_default;\r
+                                       // fall through\r
+                               case _T('0'): {\r
+                                       static const _TCHAR *octalchar = _T("01234567");\r
+                                       static int octalvalue[] = { 0, 1, 2, 3, 4, 5 ,6, 7, };\r
+                                       int n = 0;\r
+                                       for (; i_str < end && *i_str; i_str ++)\r
+                                               if (const _TCHAR *c = _tcschr(octalchar, *i_str))\r
+                                                       n = n * 8 + octalvalue[c - octalchar];\r
+                                               else\r
+                                                       break;\r
+                                       if (0 < n)\r
+                                               *d++ = static_cast<_TCHAR>(n);\r
+                                       break;\r
+                               }\r
+                               default:\r
+case_default:\r
+                                       *d++ = _T('\\');\r
+                                       if (_istlead(*i_str) && *(i_str + 1) && i_str + 1 < end)\r
+                                               *d++ = *i_str++;\r
+                                       *d++ = *i_str++;\r
+                                       break;\r
+                               }\r
+               }\r
+       }\r
+       *d =_T('\0');\r
+       return result.get();\r
+}\r
+\r
+\r
+// add session id to i_str\r
+tstring addSessionId(const _TCHAR *i_str)\r
+{\r
+       DWORD sessionId;\r
+       tstring s(i_str);\r
+       if (ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) {\r
+               _TCHAR buf[20];\r
+               _sntprintf(buf, NUMBER_OF(buf), _T("%u"), sessionId);\r
+               s += buf;\r
+       }\r
+       return s;\r
+}\r
+\r
+\r
+#ifdef _MBCS\r
+// escape regexp special characters in MBCS trail bytes\r
+std::string guardRegexpFromMbcs(const char *i_str)\r
+{\r
+       size_t len = strlen(i_str);\r
+       Array<char> buf(len * 2 + 1);\r
+       char *p = buf.get();\r
+       while (*i_str) {\r
+               if (_ismbblead(static_cast<u_char>(*i_str)) && i_str[1]) {\r
+                       *p ++ = *i_str ++;\r
+                       if (strchr(".*?+(){}[]^$", *i_str))\r
+                               *p ++ = '\\';\r
+               }\r
+               *p ++ = *i_str ++;\r
+       }\r
+       return std::string(buf.get(), p);\r
+}\r
+#endif // !_MBCS\r
+\r
+\r
+// converter\r
+std::wstring to_wstring(const std::string &i_str)\r
+{\r
+       size_t size = mbstowcs(NULL, i_str.c_str(), i_str.size() + 1);\r
+       if (size == (size_t)-1)\r
+               return std::wstring();\r
+       Array<wchar_t> result(size + 1);\r
+       mbstowcs(result.get(), i_str.c_str(), i_str.size() + 1);\r
+       return std::wstring(result.get());\r
+}\r
+\r
+\r
+// converter\r
+std::string to_string(const std::wstring &i_str)\r
+{\r
+       size_t size = wcstombs(NULL, i_str.c_str(), i_str.size() + 1);\r
+       if (size == (size_t)-1)\r
+               return std::string();\r
+       Array<char> result(size + 1);\r
+       wcstombs(result.get(), i_str.c_str(), i_str.size() + 1);\r
+       return std::string(result.get());\r
+}\r
+\r
+\r
+/// stream output\r
+tostream &operator<<(tostream &i_ost, const tregex &i_data)\r
+{\r
+       return i_ost << i_data.str();\r
+}\r
+\r
+\r
+/// get lower string\r
+tstring toLower(const tstring &i_str)\r
+{\r
+       tstring str(i_str);\r
+       for (size_t i = 0; i < str.size(); ++ i) {\r
+               if (_ismbblead(str[i]))\r
+                       ++ i;\r
+               else\r
+                       str[i] = tolower(str[i]);\r
+       }\r
+       return str;\r
+}\r
+\r
+\r
+// convert wstring to UTF-8\r
+std::string to_UTF_8(const std::wstring &i_str)\r
+{\r
+       // 0xxxxxxx: 00-7F\r
+       // 110xxxxx 10xxxxxx: 0080-07FF\r
+       // 1110xxxx 10xxxxxx 10xxxxxx: 0800 - FFFF\r
+\r
+       int size = 0;\r
+\r
+       // count needed buffer size\r
+       for (std::wstring::const_iterator i = i_str.begin(); i != i_str.end(); ++ i) {\r
+               if (0x0000 <= *i && *i <= 0x007f)\r
+                       size += 1;\r
+               else if (0x0080 <= *i && *i <= 0x07ff)\r
+                       size += 2;\r
+               else if (0x0800 <= *i && *i <= 0xffff)\r
+                       size += 3;\r
+       }\r
+\r
+       Array<char> result(size);\r
+       int ri = 0;\r
+\r
+       // make UTF-8\r
+       for (std::wstring::const_iterator i = i_str.begin(); i != i_str.end(); ++ i) {\r
+               if (0x0000 <= *i && *i <= 0x007f)\r
+                       result[ri ++] = static_cast<char>(*i);\r
+               else if (0x0080 <= *i && *i <= 0x07ff) {\r
+                       result[ri ++] = static_cast<char>(((*i & 0x0fc0) >>  6) | 0xc0);\r
+                       result[ri ++] = static_cast<char>(( *i & 0x003f       ) | 0x80);\r
+               } else if (0x0800 <= *i && *i <= 0xffff) {\r
+                       result[ri ++] = static_cast<char>(((*i & 0xf000) >> 12) | 0xe0);\r
+                       result[ri ++] = static_cast<char>(((*i & 0x0fc0) >>  6) | 0x80);\r
+                       result[ri ++] = static_cast<char>(( *i & 0x003f       ) | 0x80);\r
+               }\r
+       }\r
+\r
+       return std::string(result.begin(), result.end());\r
+}\r