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. #define BUFSIZE (4096 + 1024) // typical maxlen is 4096, want room over that
  41. // Convert wide to narrow characters
  42. #define w2c(w) (((w) & 0xff00)?'277':((unsigned char) ((w) & 0x00ff)))
  43. /*****************************
  44. // SBlogGetTime
  45. *****************************/
  46. extern "C" int SBlogGetTime(time_t *timestamp, 
  47.     VXIunsigned *timestampMsec)
  48. {
  49. #ifdef WIN32
  50.   struct _timeb tbuf;
  51.   _ftime(&tbuf);
  52.   *timestamp = tbuf.time;
  53.   *timestampMsec = (VXIunsigned) tbuf.millitm;
  54. #else
  55.   struct timeb tbuf;
  56.   ftime(&tbuf);
  57.   *timestamp = tbuf.time;
  58.   *timestampMsec = (VXIunsigned) tbuf.millitm;
  59. #endif
  60.   return 0;
  61. }
  62. /*****************************
  63. // SBlogGetTimeStampStr
  64. *****************************/
  65. extern "C" int SBlogGetTimeStampStr(time_t          timestamp,
  66.     VXIunsigned     timestampMsec,
  67.     char           *timestampStr)
  68. {
  69. #ifdef WIN32
  70.   char *timeStr = ctime(&timestamp);
  71. #else
  72.   char timeStr_r[64] = "";
  73.   char *timeStr = ctime_r(&timestamp, timeStr_r);
  74. #endif
  75.   if (timeStr) {
  76.     // Strip the weekday name from the front, year from the end,
  77.     // append hundredths of a second (the thousandths position is
  78.     // inaccurate, remains constant across entire runs of the process)
  79.     strncpy(timestampStr, &timeStr[4], 15);
  80.     sprintf(&timestampStr[15], ".%02u", timestampMsec / 10);
  81.   } else {
  82.     timestampStr[0] = '';
  83.     return -1;
  84.   }
  85.   return 0;
  86. }
  87. /*****************************
  88. // SBlogGetFileStats
  89. *****************************/
  90. extern "C" int SBlogGetFileStats(const char *path, 
  91.  SBlogFileStats *fileStats)
  92. {
  93.   int rc;
  94.   #ifdef WIN32
  95.   struct _stat stats;
  96.   #else
  97.   struct stat stats;
  98.   #endif
  99.   if ((! path) || (! fileStats))
  100.     return -1;
  101.   
  102.   #ifdef WIN32
  103.   rc = _stat(path, &stats);
  104.   #else
  105.   rc = stat(path, &stats);
  106.   #endif
  107.   
  108.   if (rc != 0) {
  109.     return -1;
  110.   }
  111.   
  112.   fileStats->st_size  = stats.st_size;
  113.   fileStats->st_mode  = stats.st_mode;
  114.   fileStats->st_atim = stats.st_atime;
  115.   fileStats->st_mtim = stats.st_mtime;
  116.   fileStats->st_ctim = stats.st_ctime;
  117.   
  118.   return 0;
  119. }
  120. /*****************************
  121. // SBlogGetCPUTimes
  122. *****************************/
  123. extern "C" int SBlogGetCPUTimes(long *userTime
  124. /* ms spent in user mode */,
  125. long *kernelTime
  126. /* ms spent in kernel mode*/
  127. )
  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.   int bufsz = 0;
  273.   char *buf, tmpbuf[BUFSIZE];
  274.   if (BUFSIZE < maxlen + 1024){
  275.     bufsz = maxlen + 1024;
  276.     buf = new char[bufsz];
  277.   }
  278.   else {
  279.     bufsz = sizeof(tmpbuf);
  280.     buf = tmpbuf;
  281.   }
  282.   if (!buf)
  283.     return -1;
  284.   /* convert format to narrow, a bit generous compared to the ANSI/ISO
  285.      C specifications for the printf( ) family format strings but we're
  286.      not trying to do full validation here anyway */
  287.   char *fmt, tmpfmt[BUFSIZE];
  288.   size_t fmtlen = wcslen(format);
  289.   if (BUFSIZE < fmtlen + 1)
  290.     fmt = new char[fmtlen + 1];
  291.   else
  292.     fmt = tmpfmt;
  293.   if (!fmt)
  294.     return -1;
  295.   format_wcs2str(format, fmt);
  296.   /* generate the final string based on the narrow format and arguments */ 
  297.   rc = vsnprintf(buf, bufsz, fmt, args);
  298.   /* copy back to wide characters */
  299.   size_t finallen = strlen(buf);
  300.   if (finallen >= maxlen)
  301.     finallen = maxlen - 1;
  302.   for (size_t i = 0; i < finallen; i++)
  303.     wcs[i] = buf[i];
  304.   wcs[finallen] = L'';
  305.   /* clean up */
  306.   if (buf != tmpbuf)
  307.     delete [] buf;
  308.   if (fmt != tmpfmt)
  309.     delete [] fmt;
  310. #else /* ! defined(__GNUC__) || (__GNUC__ > 2) */
  311.   wchar_t* newFormat = ConvertFormatForWidePrintf(format);
  312.   rc = vswprintf(wcs, maxlen, newFormat, args);
  313.   delete [] newFormat;
  314.   if ((size_t) rc >= maxlen - 1) /* overflow */
  315.     wcs[maxlen - 1] = L'';
  316. #endif /* defined(__GNUC__) && (__GNUC__ <= 2) */
  317. #endif /* WIN32 */
  318.   return rc;
  319. }
  320. /*****************************
  321. // SBlogMkDir
  322. *****************************/
  323. int SBlogMkDir(const char *path)
  324. {
  325. #ifdef WIN32
  326.   return (CreateDirectory (path, NULL) ? 1 : 0);
  327. #else
  328.   return (mkdir (path, (mode_t)0755) == 0 ? 1 : 0);
  329. #endif
  330. }
  331. /*****************************
  332. // SBlogIsDir
  333. *****************************/
  334. int SBlogIsDir(const SBlogFileStats *statInfo)
  335. {
  336. #ifdef WIN32
  337. #ifdef _S_ISDIR
  338.   return (_S_ISDIR(statInfo->st_mode) ? 1 : 0);
  339. #else
  340.   return ((statInfo->st_mode & _S_IFDIR) ? 1 : 0);
  341. #endif
  342. #else   // ! WIN32
  343. #ifdef S_ISDIR
  344.   return (S_ISDIR(statInfo->st_mode) ? 1 : 0);
  345. #else
  346.   return ((statInfo->st_mode & S_IFDIR) ? 1 : 0);
  347. #endif
  348. #endif  // WIN32
  349. }
  350. /*****************************
  351. // SBlogWchar2Latin1
  352. *****************************/
  353. extern "C" VXIbool SBlogWchar2Latin1(const wchar_t * input, char * output,
  354.      VXIunsigned maxlen)
  355. {
  356.   const wchar_t * i;
  357.   char * j;
  358.   unsigned int idx = 0;
  359.   
  360.   if( output == NULL ) 
  361.     return FALSE;
  362.   if(input == NULL)
  363.   {
  364.     *output = '';
  365.   }
  366.   else
  367.   {  
  368.     for (i = input, j = output; *i && idx < maxlen; ++i, ++j, ++idx) 
  369.     {
  370.       char t = w2c(*i);
  371.       *j = t;
  372.     }
  373.     *j = '';
  374.   }
  375.   return TRUE;
  376. }
  377. /*****************************
  378. // SBlogWchar2UTF8
  379. *****************************/
  380. extern "C" VXIbool SBlogWchar2UTF8(const wchar_t * input, char * output,
  381.    VXIunsigned maxOutputBytes,
  382.    VXIunsigned * outputBytes)
  383. {
  384.   //  firstByteMark
  385.   //      A list of values to mask onto the first byte of an encoded sequence,
  386.   //      indexed by the number of bytes used to create the sequence.
  387.   static const char firstByteMark[7] =
  388.     {  char(0x00), char(0x00), char(0xC0), char(0xE0),
  389.        char(0xF0), char(0xF8), char(0xFC) };
  390.   //  Get pointers to our start and end points of the input buffer.
  391.   const wchar_t* srcPtr = input;
  392.   const wchar_t* srcEnd = srcPtr + wcslen(input);
  393.   *outputBytes = 0;
  394.   
  395.   while (srcPtr < srcEnd) {
  396.     wchar_t curVal = *srcPtr++;
  397.     // Watchout for surrogates, if found truncate
  398.     if ((curVal >= 0xD800) && (curVal <= 0xDBFF)) {
  399.       break;
  400.     }
  401.     // Figure out how many bytes we need
  402.     unsigned int encodedBytes;
  403.     if (curVal < 0x80)                encodedBytes = 1;
  404.     else if (curVal < 0x800)          encodedBytes = 2;
  405.     else if (curVal < 0x10000)        encodedBytes = 3;
  406.     else if (curVal < 0x200000)       encodedBytes = 4;
  407.     else if (curVal < 0x4000000)      encodedBytes = 5;
  408.     else if (curVal <= 0x7FFFFFFF)    encodedBytes = 6;
  409.     else {
  410.       // THIS SHOULD NOT HAPPEN!
  411.       output[*outputBytes] = '';
  412.       return FALSE;
  413.     }
  414.     //  If we don't have enough room in the buffer, truncate
  415.     if ( *outputBytes + encodedBytes >= maxOutputBytes ) {
  416.       break;
  417.     }
  418.     //  And spit out the bytes. We spit them out in reverse order
  419.     //  here, so bump up the output pointer and work down as we go.
  420.     char buffer[7] = { 0, 0, 0, 0, 0, 0, 0 };
  421.     
  422.     char * outPtr = buffer + encodedBytes;
  423.     switch(encodedBytes) {
  424.     case 6 : *--outPtr = char((curVal | 0x80) & 0xBF);
  425.       curVal >>= 6;
  426.     case 5 : *--outPtr = char((curVal | 0x80) & 0xBF);
  427.       curVal >>= 6;
  428.     case 4 : *--outPtr = char((curVal | 0x80) & 0xBF);
  429.       curVal >>= 6;
  430.     case 3 : *--outPtr = char((curVal | 0x80) & 0xBF);
  431.       curVal >>= 6;
  432.     case 2 : *--outPtr = char((curVal | 0x80) & 0xBF);
  433.       curVal >>= 6;
  434.     case 1 : *--outPtr = char(curVal | firstByteMark[encodedBytes]);
  435.     }
  436.     
  437.     for (int i = 0; buffer[i] != 0; i++) {
  438.       output[*outputBytes] = buffer[i];
  439.       (*outputBytes)++;
  440.     }
  441.   }
  442.   //  NULL terminate
  443.   output[*outputBytes] = '';
  444.   return TRUE;
  445. }
  446. /*****************************
  447. // Log errors to the console, only used for errors that occur prior
  448. // to initializing the log subsystem
  449. *****************************/
  450. VXIlogResult 
  451. SBlogLogErrorToConsole(const VXIchar *moduleName, VXIunsigned errorID,
  452.        const VXIchar *errorIDText)
  453. {
  454.   VXIlogResult rc = VXIlog_RESULT_SUCCESS;
  455.   const VXIchar *severity;
  456.   if (errorID < 200)
  457.     severity = L"CRITICAL";
  458.   else if (errorID < 300)
  459.     severity = L"SEVERE";
  460.   else
  461.     severity = L"WARNING";
  462. #ifdef WIN32
  463.   fwprintf(stderr, L"%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  464.    errorIDText);
  465. #else
  466.   fprintf(stderr, "%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  467.   errorIDText);
  468. #endif
  469.   return rc;
  470. }
  471. VXIlogResult 
  472. SBlogVLogErrorToConsole(const VXIchar *moduleName, VXIunsigned errorID,
  473. const VXIchar *errorIDText, const VXIchar *format,
  474. va_list arguments)
  475. {
  476.   int argCount;
  477.   VXIlogResult rc = VXIlog_RESULT_SUCCESS;
  478.   const VXIchar *in;
  479.   VXIchar *out, tempFormat[256];
  480.   /* Get the severity */
  481.   const VXIchar *severity;
  482.   if (errorID < 200)
  483.     severity = L"CRITICAL";
  484.   else if (errorID < 300)
  485.     severity = L"SEVERE";
  486.   else
  487.     severity = L"WARNING";
  488.   /* Properly delimit the format arguments for human consumption */
  489.   argCount = 0;
  490.   if (format) {
  491.     for (in = format, out = tempFormat; *in != L''; in++, out++) {
  492.       if (*in == L'%') {
  493. argCount++;
  494. *out = (argCount % 2 == 0 ? L'=' : L'|');
  495. out++;
  496.       }
  497.       *out = *in;
  498.     }
  499.     *out = L'n';
  500.     out++;
  501.     *out = L'';
  502.     
  503. #ifdef WIN32
  504.     fwprintf(stderr, L"%ls: %ls|%u|%ls", severity, moduleName, errorID,
  505.      errorIDText);
  506.     vfwprintf(stderr, tempFormat, arguments);
  507. #else
  508.     /* SBlogVswprintf( ) handles the format conversion if necessary
  509.        from Microsoft Visual C++ run-time library/GNU gcc 2.x C
  510.        library notation to GNU gcc 3.x C library (and most other UNIX
  511.        C library) notation: %s -> %ls, %S -> %s. Unfortunately there
  512.        is no single format string representation that can be used
  513.        universally. */
  514.     VXIchar tempBuf[4096];
  515.     SBlogVswprintf(tempBuf, 4096, tempFormat, arguments);
  516.     fprintf(stderr, "%ls: %ls|%u|%ls%lsn", severity, moduleName, errorID,
  517.     errorIDText, tempBuf);
  518. #endif
  519.   } else {
  520. #ifdef WIN32
  521.     fwprintf(stderr, L"%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  522.      errorIDText);
  523. #else
  524.     fprintf(stderr, "%ls: %ls|%u|%lsn", severity, moduleName, errorID,
  525.     errorIDText);
  526. #endif
  527.   }
  528.   
  529.   return rc;
  530. }