SBlogOSUtils.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:16k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27. #ifdef WIN32
  28. #define WIN32_LEAN_AND_MEAN
  29. #include <windows.h>
  30. #else
  31. #include <time.h>                       // For CLK_TCK/CLOCKS_PER_SEC
  32. #include <sys/times.h>                  // For times( )
  33. #ifndef CLK_TCK
  34. #define CLK_TCK CLOCKS_PER_SEC
  35. #endif
  36. #endif
  37. #include <sys/timeb.h>                  // for ftime( )/_ftime( )
  38. #include <sys/stat.h>                   // for stat( )
  39. #include "SBlogOSUtils.h"
  40. #include "VXIclientUtils.h"
  41. #define BUFSIZE (4096 + 1024) // typical maxlen is 4096, want room over that
  42. // Convert wide to narrow characters
  43. #define w2c(w) (((w) & 0xff00)?'277':((unsigned char) ((w) & 0x00ff)))
  44. /*****************************
  45. // SBlogGetTime
  46. *****************************/
  47. extern "C" int SBlogGetTime(time_t *timestamp, 
  48.           VXIunsigned *timestampMsec)
  49. {
  50. #ifdef WIN32
  51.   struct _timeb tbuf;
  52.   _ftime(&tbuf);
  53.   *timestamp = tbuf.time;
  54.   *timestampMsec = (VXIunsigned) tbuf.millitm;
  55. #else
  56.   struct timeb tbuf;
  57.   ftime(&tbuf);
  58.   *timestamp = tbuf.time;
  59.   *timestampMsec = (VXIunsigned) tbuf.millitm;
  60. #endif
  61.   return 0;
  62. }
  63. /*****************************
  64. // SBlogGetTimeStampStr
  65. *****************************/
  66. extern "C" int SBlogGetTimeStampStr(time_t          timestamp,
  67.             VXIunsigned     timestampMsec,
  68.             char           *timestampStr)
  69. {
  70. #ifdef WIN32
  71.   char *timeStr = ctime(&timestamp);
  72. #else
  73.   char timeStr_r[64] = "";
  74.   char *timeStr = ctime_r(&timestamp, timeStr_r);
  75. #endif
  76.   if (timeStr) {
  77.     // Strip the weekday name from the front, year from the end,
  78.     // append hundredths of a second (the thousandths position is
  79.     // inaccurate, remains constant across entire runs of the process)
  80.     strncpy(timestampStr, &timeStr[4], 15);
  81.     sprintf(&timestampStr[15], ".%02u", timestampMsec / 10);
  82.   } else {
  83.     timestampStr[0] = '';
  84.     return -1;
  85.   }
  86.   return 0;
  87. }
  88. /*****************************
  89. // SBlogGetFileStats
  90. *****************************/
  91. extern "C" int SBlogGetFileStats(const char *path, 
  92.          SBlogFileStats *fileStats)
  93. {
  94.   int rc;
  95.   #ifdef WIN32
  96.   struct _stat stats;
  97.   #else
  98.   struct stat stats;
  99.   #endif
  100.   if ((! path) || (! fileStats))
  101.     return -1;
  102.   
  103.   #ifdef WIN32
  104.   rc = _stat(path, &stats);
  105.   #else
  106.   rc = stat(path, &stats);
  107.   #endif
  108.   
  109.   if (rc != 0) {
  110.     return -1;
  111.   }
  112.   
  113.   fileStats->st_size  = stats.st_size;
  114.   fileStats->st_mode  = stats.st_mode;
  115.   fileStats->st_atim = stats.st_atime;
  116.   fileStats->st_mtim = stats.st_mtime;
  117.   fileStats->st_ctim = stats.st_ctime;
  118.   
  119.   return 0;
  120. }
  121. /*****************************
  122. // SBlogGetCPUTimes
  123. *****************************/
  124. extern "C" int SBlogGetCPUTimes(long *userTime
  125.                                 /* ms spent in user mode */,
  126.                                 long *kernelTime
  127.                                 /* ms spent in kernel mode*/)
  128. {
  129. #ifdef WIN32
  130.   FILETIME dummy;
  131.   FILETIME k, u;
  132.   LARGE_INTEGER lk, lu;
  133.   if ((! userTime) || (! kernelTime))
  134.     return -1;
  135.   if (GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &k, &u) == FALSE)
  136.     return -1;
  137.   lk.LowPart  = k.dwLowDateTime;
  138.   lk.HighPart = k.dwHighDateTime;
  139.   *kernelTime = (long) (lk.QuadPart / 10000);
  140.   lu.LowPart  = u.dwLowDateTime;
  141.   lu.HighPart = u.dwHighDateTime;
  142.   *userTime   = (long) (lu.QuadPart / 10000);
  143. #else
  144.   struct tms timeBuf;
  145.   if ((! userTime) || (! kernelTime))
  146.     return -1;
  147.   times(&timeBuf);
  148.   *userTime = (long)timeBuf.tms_utime * 1000 / CLK_TCK;
  149.   *kernelTime = (long)timeBuf.tms_stime * 1000 / CLK_TCK;
  150. #endif
  151.   return 0;
  152. }
  153. /*****************************
  154. // format_wcs2str (internal-only)
  155. *****************************/
  156. static int format_wcs2str(const wchar_t *wformat, char *nformat)
  157. {
  158.   size_t len, i;
  159.   bool replacement = false;
  160.   
  161.   len = wcslen(wformat);
  162.   for (i = 0; i <= len; i++) {
  163.     nformat[i] = w2c(wformat[i]);
  164.     if (nformat[i] == '%') {
  165.       if (replacement)
  166.         replacement = false; // double %%
  167.       else
  168.         replacement = true;
  169.     } else if ((replacement == true) && 
  170.               (((nformat[i] >= 'a') && (nformat[i] <= 'z')) ||
  171.               ((nformat[i] >= 'A') && (nformat[i] <= 'Z')))) {
  172.       switch (nformat[i]) {
  173.         case 's':
  174.           // wide insert for wide format -> wide insert for narrow format
  175.           nformat[i] = 'S';
  176.           break;
  177.         case 'S':
  178.           // narrow insert for wide format -> narrow insert for narrow format
  179.           nformat[i] = 's';
  180.           break;
  181.         default:
  182.           break;
  183.       }
  184.       replacement = false;
  185.     }
  186.   }
  187.   nformat[i] = '';
  188.   
  189.   return len;
  190. }
  191. /*****************************
  192. // SBlogVswprintf
  193. *****************************/
  194. #ifndef WIN32
  195. #if ! (defined(__GNUC__) && (__GNUC__ <= 2))
  196. static wchar_t* ConvertFormatForWidePrintf(const wchar_t* format)
  197. {
  198.   int formatLen = wcslen(format);
  199.   // The maximum length of the new format string is 1 and 2/3 that
  200.   //    of the original.
  201.   wchar_t* newFormat = new wchar_t [2 * formatLen];
  202.   int nfIndex = 0;
  203.   for (int fIndex = 0; fIndex < formatLen; ++fIndex)
  204.   {
  205.     // We found %s in format.
  206.     if ((format[fIndex] == L'%') && (fIndex != (formatLen - 1)))
  207.     {
  208.       newFormat[nfIndex++] = L'%';
  209.       fIndex++;
  210.       while ((fIndex < formatLen - 1) &&
  211.             ((format[fIndex] >= L'0') && (format[fIndex] <= L'9')) ||
  212.             (format[fIndex] == L'+') || (format[fIndex] == L'-') ||
  213.             (format[fIndex] == L'.') || (format[fIndex] == L'*') ||
  214.             (format[fIndex] == L'#')) {
  215.         newFormat[nfIndex++] = format[fIndex++];
  216.       }
  217.       switch(format[fIndex]) {
  218.         case L's': {
  219.           newFormat[nfIndex++] = L'l';
  220.           newFormat[nfIndex++] = L's';
  221.           break;
  222.         }
  223.         case L'S': {
  224.           newFormat[nfIndex++] = L's';
  225.           break;
  226.         }
  227.         case L'c': {
  228.           newFormat[nfIndex++] = L'l';
  229.           newFormat[nfIndex++] = L'c';
  230.           break;
  231.         }
  232.         case L'C': {
  233.           newFormat[nfIndex++] = L'c';
  234.           break;
  235.         }
  236.         default: {
  237.           newFormat[nfIndex++] = format[fIndex];
  238.           break;
  239.         }
  240.       }
  241.     }
  242.     else
  243.     {
  244.       newFormat[nfIndex++] = format[fIndex];
  245.     }
  246.   }
  247.   newFormat[nfIndex] = 0;
  248.   return newFormat;
  249. }
  250. #endif /* ! defined(__GNUC__) && (__GNUC__ <= 2) */
  251. #endif /* ! WIN32 */
  252. extern "C" int SBlogVswprintf(wchar_t* wcs, size_t maxlen,
  253.             const wchar_t* format, va_list args)
  254. {
  255.   int rc;
  256.   if (maxlen < 1)
  257.     return -1;
  258.   *wcs = 0;
  259. #ifdef WIN32
  260.   /* Straight-forward Win32 implementation */
  261.   rc = _vsnwprintf(wcs, maxlen, format, args);
  262.   if ((size_t) rc >= maxlen - 1) /* overflow */
  263.     wcs[maxlen - 1] = L'';
  264. #else /* ! WIN32 */
  265. #if defined(__GNUC__) && (__GNUC__ <= 2)
  266.   /* Some versions of the GNU C library do not provide the required
  267.      vswprintf( ) function, so we emulate it by converting the format
  268.      string to narrow characters, do a narrow sprintf( ), then convert
  269.      back */
  270.   /* Use a temporary buffer for output to protect against relatively
  271.      small overruns */
  272.   char *buf, tmpbuf[BUFSIZE];
  273.   if (BUFSIZE < maxlen + 1024)
  274.     buf = new char[maxlen + 1024];
  275.   else
  276.     buf = tmpbuf;
  277.   if (!buf)
  278.     return -1;
  279.   /* convert format to narrow, a bit generous compared to the ANSI/ISO
  280.      C specifications for the printf( ) family format strings but we're
  281.      not trying to do full validation here anyway */
  282.   char *fmt, tmpfmt[BUFSIZE];
  283.   size_t fmtlen = wcslen(format);
  284.   if (BUFSIZE < fmtlen + 1)
  285.     fmt = new char[fmtlen + 1];
  286.   else
  287.     fmt = tmpfmt;
  288.   if (!fmt)
  289.     return -1;
  290.   format_wcs2str(format, fmt);
  291.   /* generate the final string based on the narrow format and arguments */ 
  292.   rc = vsprintf(buf, fmt, args);
  293.   /* copy back to wide characters */
  294.   size_t finallen = strlen(buf);
  295.   if (finallen >= maxlen)
  296.     finallen = maxlen - 1;
  297.   for (size_t i = 0; i < finallen; i++)
  298.     wcs[i] = buf[i];
  299.   wcs[finallen] = L'';
  300.   /* clean up */
  301.   if (buf != tmpbuf)
  302.     delete [] buf;
  303.   if (fmt != tmpfmt)
  304.     delete [] fmt;
  305. #else /* ! defined(__GNUC__) || (__GNUC__ > 2) */
  306.   wchar_t* newFormat = ConvertFormatForWidePrintf(format);
  307.   rc = vswprintf(wcs, maxlen, newFormat, args);
  308.   delete [] newFormat;
  309.   if ((size_t) rc >= maxlen - 1) /* overflow */
  310.     wcs[maxlen - 1] = L'';
  311. #endif /* defined(__GNUC__) && (__GNUC__ <= 2) */
  312. #endif /* WIN32 */
  313.   return rc;
  314. }
  315. /*****************************
  316. // SBlogMkDir
  317. *****************************/
  318. int SBlogMkDir(const char *path)
  319. {
  320. #ifdef WIN32
  321. #ifdef UNICODE
  322.   wchar_t wpath[1024];
  323.   char2wchar(wpath, path, strlen(path));
  324.   return (CreateDirectory (wpath, NULL) ? 1 : 0);  
  325. #else
  326.   return (CreateDirectory (path, NULL) ? 1 : 0);
  327. #endif  
  328. #else
  329.   return (mkdir (path, (mode_t)0755) == 0 ? 1 : 0);
  330. #endif
  331. }
  332. /*****************************
  333. // SBlogIsDir
  334. *****************************/
  335. int SBlogIsDir(const SBlogFileStats *statInfo)
  336. {
  337. #ifdef WIN32
  338. #ifdef _S_ISDIR
  339.   return (_S_ISDIR(statInfo->st_mode) ? 1 : 0);
  340. #else
  341.   return ((statInfo->st_mode & _S_IFDIR) ? 1 : 0);
  342. #endif
  343. #else   // ! WIN32
  344. #ifdef S_ISDIR
  345.   return (S_ISDIR(statInfo->st_mode) ? 1 : 0);
  346. #else
  347.   return ((statInfo->st_mode & S_IFDIR) ? 1 : 0);
  348. #endif
  349. #endif  // WIN32
  350. }
  351. /*****************************
  352. // SBlogWchar2Latin1
  353. *****************************/
  354. extern "C" VXIbool SBlogWchar2Latin1(const wchar_t * input, char * output,
  355.                                      VXIunsigned maxlen)
  356. {
  357.   const wchar_t * i;
  358.   char * j;
  359.   unsigned int idx = 0;
  360.   
  361.   if( output == NULL ) 
  362.     return FALSE;
  363.   if(input == NULL)
  364.   {
  365.     *output = '';
  366.   }
  367.   else
  368.   {  
  369.     for (i = input, j = output; *i && idx < maxlen; ++i, ++j, ++idx) 
  370.     {
  371.       char t = w2c(*i);
  372.       *j = t;
  373.     }
  374.     *j = '';
  375.   }
  376.   return TRUE;
  377. }
  378. /*****************************
  379. // SBlogWchar2UTF8
  380. *****************************/
  381. extern "C" VXIbool SBlogWchar2UTF8(const wchar_t * input, char * output,
  382.            VXIunsigned maxOutputBytes,
  383.            VXIunsigned * outputBytes)
  384. {
  385.   //  firstByteMark
  386.   //      A list of values to mask onto the first byte of an encoded sequence,
  387.   //      indexed by the number of bytes used to create the sequence.
  388.   static const char firstByteMark[7] =
  389.     {  char(0x00), char(0x00), char(0xC0), char(0xE0),
  390.        char(0xF0), char(0xF8), char(0xFC) };
  391.   //  Get pointers to our start and end points of the input buffer.
  392.   const wchar_t* srcPtr = input;
  393.   const wchar_t* srcEnd = srcPtr + wcslen(input);
  394.   *outputBytes = 0;
  395.   
  396.   while (srcPtr < srcEnd) {
  397.     wchar_t curVal = *srcPtr++;
  398.     // Watchout for surrogates, if found truncate
  399.     if ((curVal >= 0xD800) && (curVal <= 0xDBFF)) {
  400.       break;
  401.     }
  402.     // Figure out how many bytes we need
  403.     unsigned int encodedBytes;
  404.     if (curVal < 0x80)                encodedBytes = 1;
  405.     else if (curVal < 0x800)          encodedBytes = 2;
  406.     else if (curVal < 0x10000)        encodedBytes = 3;
  407.     else if (curVal < 0x200000)       encodedBytes = 4;
  408.     else if (curVal < 0x4000000)      encodedBytes = 5;
  409.     else if (curVal <= 0x7FFFFFFF)    encodedBytes = 6;
  410.     else {
  411.       // THIS SHOULD NOT HAPPEN!
  412.       output[*outputBytes] = '';
  413.       return FALSE;
  414.     }
  415.     //  If we don't have enough room in the buffer, truncate
  416.     if ( *outputBytes + encodedBytes >= maxOutputBytes ) {
  417.       break;
  418.     }
  419.     //  And spit out the bytes. We spit them out in reverse order
  420.     //  here, so bump up the output pointer and work down as we go.
  421.     char buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
  422.     
  423.     char * outPtr = buffer + encodedBytes;
  424.     switch(encodedBytes) {
  425.     case 6 : *--outPtr = char((curVal | 0x80) & 0xBF);
  426.       curVal >>= 6;
  427.     case 5 : *--outPtr = char((curVal | 0x80) & 0xBF);
  428.       curVal >>= 6;
  429.     case 4 : *--outPtr = char((curVal | 0x80) & 0xBF);
  430.       curVal >>= 6;
  431.     case 3 : *--outPtr = char((curVal | 0x80) & 0xBF);
  432.       curVal >>= 6;
  433.     case 2 : *--outPtr = char((curVal | 0x80) & 0xBF);
  434.       curVal >>= 6;
  435.     case 1 : *--outPtr = char(curVal | firstByteMark[encodedBytes]);
  436.     }
  437.     
  438.     for (int i = 0; buffer[i] != 0; i++) {
  439.       output[*outputBytes] = buffer[i];
  440.       (*outputBytes)++;
  441.     }
  442.   }
  443.   //  NULL terminate
  444.   output[*outputBytes] = '';
  445.   return TRUE;
  446. }
  447. /*****************************
  448. // Log errors to the console, only used for errors that occur prior
  449. // to initializing the log subsystem
  450. *****************************/
  451. VXIlogResult 
  452. SBlogLogErrorToConsole(const VXIchar *moduleName, VXIunsigned errorID,
  453.            const VXIchar *errorIDText)
  454. {
  455.   VXIlogResult rc = VXIlog_RESULT_SUCCESS;
  456.   const VXIchar *severity;
  457.   if (errorID < 200)
  458.     severity = L"CRITICAL";
  459.   else if (errorID < 300)
  460.     severity = L"SEVERE";
  461.   else
  462.     severity = L"WARNING";
  463. #ifdef WIN32
  464.   fwprintf(stderr, L"%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  465.      errorIDText);
  466. #else
  467.   fprintf(stderr, "%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  468.     errorIDText);
  469. #endif
  470.   return rc;
  471. }
  472. VXIlogResult 
  473. SBlogVLogErrorToConsole(const VXIchar *moduleName, VXIunsigned errorID,
  474.       const VXIchar *errorIDText, const VXIchar *format,
  475.       va_list arguments)
  476. {
  477.   int argCount;
  478.   VXIlogResult rc = VXIlog_RESULT_SUCCESS;
  479.   const VXIchar *in;
  480.   VXIchar *out, tempFormat[256];
  481.   /* Get the severity */
  482.   const VXIchar *severity;
  483.   if (errorID < 200)
  484.     severity = L"CRITICAL";
  485.   else if (errorID < 300)
  486.     severity = L"SEVERE";
  487.   else
  488.     severity = L"WARNING";
  489.   /* Properly delimit the format arguments for human consumption */
  490.   argCount = 0;
  491.   if (format) {
  492.     for (in = format, out = tempFormat; *in != L''; in++, out++) {
  493.       if (*in == L'%') {
  494.   argCount++;
  495.   *out = (argCount % 2 == 0 ? L'=' : L'|');
  496.   out++;
  497.       }
  498.       *out = *in;
  499.     }
  500.     *out = L'n';
  501.     out++;
  502.     *out = L'';
  503.     
  504. #ifdef WIN32
  505.     fwprintf(stderr, L"%ls: %ls|%u|%ls", severity, moduleName, errorID,
  506.        errorIDText);
  507.     vfwprintf(stderr, tempFormat, arguments);
  508. #else
  509.     /* SBlogVswprintf( ) handles the format conversion if necessary
  510.        from Microsoft Visual C++ run-time library/GNU gcc 2.x C
  511.        library notation to GNU gcc 3.x C library (and most other UNIX
  512.        C library) notation: %s -> %ls, %S -> %s. Unfortunately there
  513.        is no single format string representation that can be used
  514.        universally. */
  515.     VXIchar tempBuf[4096];
  516.     SBlogVswprintf(tempBuf, 4096, tempFormat, arguments);
  517.     fprintf(stderr, "%ls: %ls|%u|%ls%lsn", severity, moduleName, errorID,
  518.       errorIDText, tempBuf);
  519. #endif
  520.   } else {
  521. #ifdef WIN32
  522.     fwprintf(stderr, L"%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  523.        errorIDText);
  524. #else
  525.     fprintf(stderr, "%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  526.       errorIDText);
  527. #endif
  528.   }
  529.   
  530.   return rc;
  531. }