SWIprintf.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 <stddef.h>
  26. #include <string.h>
  27. #include <stdarg.h>
  28. #include <ctype.h>
  29. #include <malloc.h>
  30. #include "SWIprintf.h"
  31. #include "misc_string.h"
  32. static const char BAD_FORMAT_TEXT[] = " [bad format!]";
  33. static const wchar_t BAD_FORMAT_TEXT_W[] = L" [bad format!]";
  34. static const size_t BAD_FORMAT_TEXT_LEN = 14;
  35. // Convert wide to narrow characters
  36. #define w2c(w) (((w) & 0xff00)?'277':((unsigned char) ((w) & 0x00ff)))
  37. #if !defined(_win32_)
  38. static wchar_t* ConvertFormatForWidePrintf(const wchar_t* format)
  39. {
  40.   int formatLen = wcslen(format);
  41.   // The maximum length of the new format string is 1 and 2/3 that
  42.   //    of the original.
  43.   wchar_t* newFormat = new wchar_t [2 * formatLen];
  44.   int nfIndex = 0;
  45.   for (int fIndex = 0; fIndex < formatLen; ++fIndex)
  46.   {
  47.     // We found %s in format.
  48.     if ((format[fIndex] == L'%') && (fIndex != (formatLen - 1)))
  49.     {
  50.       newFormat[nfIndex++] = L'%';
  51.       fIndex++;
  52.       while((SWIchar_iswdigit(format[fIndex]) || (format[fIndex] == L'+') ||
  53.             (format[fIndex] == L'-') || (format[fIndex] == L'.') ||
  54.             (format[fIndex] == L'*') || (format[fIndex] == L'#')) &&
  55.             (fIndex < formatLen - 1)) {
  56.         newFormat[nfIndex++] = format[fIndex++];
  57.       }
  58.       switch(format[fIndex]) {
  59.         case L's': {
  60.           newFormat[nfIndex++] = L'l';
  61.           newFormat[nfIndex++] = L's';
  62.           break;
  63.         }
  64.         case L'S': {
  65.           newFormat[nfIndex++] = L's';
  66.           break;
  67.         }
  68.         case L'c': {
  69.           newFormat[nfIndex++] = L'l';
  70.           newFormat[nfIndex++] = L'c';
  71.           break;
  72.         }
  73.         case L'C': {
  74.           newFormat[nfIndex++] = L'c';
  75.           break;
  76.         }
  77.         default: {
  78.           newFormat[nfIndex++] = format[fIndex];
  79.           break;
  80.         }
  81.       }
  82.     }
  83.     else
  84.     {
  85.       newFormat[nfIndex++] = format[fIndex];
  86.     }
  87.   }
  88.   newFormat[nfIndex] = 0;
  89.   return newFormat;
  90. }
  91. static char* ConvertFormatForNarrowPrintf(const char* format)
  92. {
  93.   int formatLen = strlen(format);
  94.   // The maximum length of the new format string is 1 and 2/3 that
  95.   //    of the original.
  96.   char* newFormat = new char [2 * formatLen];
  97.   int nfIndex = 0;
  98.   for (int fIndex = 0; fIndex < formatLen; ++fIndex)
  99.   {
  100.     // We found %s in format.
  101.     if ((format[fIndex] == '%') && (fIndex != (formatLen - 1)))
  102.     {
  103.       newFormat[nfIndex++] = '%';
  104.       fIndex++;
  105.       while((SWIchar_isdigit(format[fIndex]) || (format[fIndex] == L'+') ||
  106.             (format[fIndex] == L'-') || (format[fIndex] == L'.') ||
  107.             (format[fIndex] == L'*') || (format[fIndex] == L'#')) &&
  108.             (fIndex < formatLen - 1)) {
  109.         newFormat[nfIndex++] = format[fIndex++];
  110.       }
  111.       if (format[fIndex] == 'S')
  112.       {
  113.         newFormat[nfIndex++] = 'l';
  114.         newFormat[nfIndex++] = 's';
  115.       }
  116.       else if (format[fIndex] == 'C')
  117.       {
  118.         newFormat[nfIndex++] = 'l';
  119.         newFormat[nfIndex++] = 'c';
  120.       }
  121.       else
  122.       {
  123.         newFormat[nfIndex++] = format[fIndex];
  124.       }
  125.     }
  126.     else
  127.     {
  128.       newFormat[nfIndex++] = format[fIndex];
  129.     }
  130.   }
  131.   newFormat[nfIndex] = 0;
  132.   return newFormat;
  133. }
  134. static char* ConvertWideFormatForNarrowPrintf(const wchar_t* format)
  135. {
  136.   int formatLen = wcslen(format);
  137.   // The maximum length of the new format string is 1 and 2/3 that
  138.   //    of the original.
  139.   char* newFormat = new char [2 * formatLen];
  140.   int nfIndex = 0;
  141.   for (int fIndex = 0; fIndex < formatLen; ++fIndex)
  142.   {
  143.     // We found %s in format.
  144.     if ((format[fIndex] == L'%') && (fIndex != (formatLen - 1)))
  145.     {
  146.       newFormat[nfIndex++] = '%';
  147.       fIndex++;
  148.       while((SWIchar_iswdigit(format[fIndex]) || (format[fIndex] == L'+') ||
  149.             (format[fIndex] == L'-') || (format[fIndex] == L'.') ||
  150.             (format[fIndex] == L'*') || (format[fIndex] == L'#')) &&
  151.             (fIndex < formatLen - 1)) {
  152.         newFormat[nfIndex++] = w2c(format[fIndex++]);
  153.       }
  154.       switch(format[fIndex]) {
  155.         case L's': {
  156.           newFormat[nfIndex++] = 'l';
  157.           newFormat[nfIndex++] = 's';
  158.           break;
  159.         }
  160.         case L'S': {
  161.           newFormat[nfIndex++] = 's';
  162.           break;
  163.         }
  164.         case L'c': {
  165.           newFormat[nfIndex++] = 'l';
  166.           newFormat[nfIndex++] = 'c';
  167.           break;
  168.         }
  169.         case L'C': {
  170.           newFormat[nfIndex++] = 'c';
  171.           break;
  172.         }
  173.         default: {
  174.           newFormat[nfIndex++] = w2c(format[fIndex]);
  175.           break;
  176.         }
  177.       }
  178.     }
  179.     else
  180.     {
  181.       newFormat[nfIndex++] = w2c(format[fIndex]);
  182.     }
  183.   }
  184.   newFormat[nfIndex] = 0;
  185.   return newFormat;
  186. }
  187. #endif
  188. /*
  189.  *  Common functions for all OSes
  190.  */
  191. SWIPRINTF_API int SWIfprintf(FILE* file, const char* format, ...)
  192. {
  193.   va_list ap;
  194.   int rc;
  195.   va_start(ap, format);
  196. #if 0
  197.   try {
  198. #endif
  199. #if !defined(_win32_)
  200.     char* newFormat = ConvertFormatForNarrowPrintf(format);
  201.     rc = vfprintf(file, newFormat, ap);
  202.     delete []newFormat;
  203. #else
  204.     rc = vfprintf(file, format, ap);
  205. #endif
  206. #if 0
  207.   } catch(...) {
  208.     rc = fputs(format, file);
  209.   }
  210. #endif
  211.   va_end(ap);
  212.   return rc;
  213. }
  214. SWIPRINTF_API int SWIfwprintf(FILE* file, const wchar_t* format, ...)
  215. {
  216.   va_list ap;
  217.   int rc;
  218.   va_start(ap, format);
  219. #if !defined(_win32_)
  220.   char* newFormat = ConvertWideFormatForNarrowPrintf(format);
  221.   rc = vfprintf(file, newFormat, ap);
  222.   delete [] newFormat;
  223. #else
  224.   rc = vfwprintf(file, format, ap);
  225. #endif
  226.   va_end(ap);
  227.   return rc;
  228. }
  229. SWIPRINTF_API int SWIsprintf(char* str, size_t maxlen, const char* format, ...)
  230. {
  231.   va_list ap;
  232.   int rc;
  233.   va_start(ap, format);
  234.   rc = SWIvsprintf(str, maxlen, format, ap);
  235.   va_end(ap);
  236.   return rc;
  237. }
  238.   // if maxlen == 0, wcs is untouched, returns -1
  239.   // if there is overflow, returns -1 and maxlen-1 # of chars are written
  240. SWIPRINTF_API int SWIswprintf (wchar_t* wcs, size_t maxlen,
  241.        const wchar_t* format, ...)
  242. {
  243.   va_list ap;
  244.   int rc;
  245.   wchar_t strbuf[200]; // try to avoid malloc
  246.   wchar_t *tstr;
  247.   if (maxlen < 1)
  248.     return -1;
  249.   if ( maxlen >= 200 ) {
  250.     tstr = (wchar_t *)malloc( (maxlen+1)*sizeof(wchar_t) );
  251.     if (tstr == NULL) {
  252.       //FIXME-- can't log, how can we notify user?
  253.       return -1;
  254.     }
  255.   } else {
  256.     tstr = strbuf;
  257.   }
  258.   va_start(ap, format);
  259.   rc = SWIvswprintf(tstr, maxlen, format, ap);
  260.   va_end(ap);
  261.   wcscpy( wcs,tstr );
  262.   if ( tstr != strbuf ) free(tstr);
  263.   return rc;
  264. }
  265. /*
  266.  *  OS specific functions below, UNIX variants start first
  267.  */
  268. #ifndef _win32_
  269. static int wcs2str(const wchar_t *wcs, char *str)
  270. {
  271.   int len, i;
  272.   len = wcslen(wcs);
  273.   for (i = 0; i < len; i++)
  274.     str[i] = w2c(wcs[i]);
  275.   str[i] = '';
  276.   return len;
  277. }
  278. static int str2wcs(const char *str, wchar_t *wcs)
  279. {
  280.   int len, i;
  281.   len = strlen(str);
  282.   for (i = 0; i < len; i++)
  283.     wcs[i] = (wchar_t)str[i];
  284.   wcs[i] = L'';
  285.   return len;
  286. }
  287. /* convert str to wcs */
  288. static int buf_str2wcs(const char *str, wchar_t *wcs, int len)
  289. {
  290.   int i;
  291.   for (i = 0; i < len; i++)
  292.     wcs[i] = (wchar_t)str[i];
  293.   return len;
  294. }
  295. static int buf_wcs2str(const wchar_t *wcs, char *str, int len)
  296. {
  297.   int i;
  298.   for (i = 0; i < len; i++)
  299.     str[i] = w2c(wcs[i]);
  300.   return len;
  301. }
  302. static int format_wcs2str(const wchar_t *wformat, char *nformat)
  303. {
  304.   size_t len, i;
  305.   bool replacement = false;
  306.   len = wcslen(wformat);
  307.   for (i = 0; i <= len; i++) {
  308.     nformat[i] = w2c(wformat[i]);
  309.     if (nformat[i] == '%') {
  310.       if (replacement)
  311. replacement = false; // double %%
  312.       else
  313. replacement = true;
  314.     }
  315.     else if ((replacement == true) && (SWIchar_isalpha(nformat[i]))) {
  316.       switch (nformat[i]) {
  317.       case 'c':
  318. // wide insert for wide format -> wide insert for narrow format
  319. nformat[i] = 'C';
  320. break;
  321.       case 's':
  322. // wide insert for wide format -> wide insert for narrow format
  323. nformat[i] = 'S';
  324. break;
  325.       case 'C':
  326. // narrow insert for wide format -> narrow insert for narrow format
  327. nformat[i] = 'c';
  328. break;
  329.       case 'S':
  330. // narrow insert for wide format -> narrow insert for narrow format
  331. nformat[i] = 's';
  332. break;
  333.       default:
  334. break;
  335.       }
  336.       replacement = false;
  337.     }
  338.   }
  339.   nformat[i] = '';
  340.   return len;
  341. }
  342. SWIPRINTF_API int SWIvsprintf(char* str, size_t maxlen,
  343.       const char* format, va_list args)
  344. {
  345.   char tmpbuf[BUFSIZE];
  346.   char *buf;
  347.   int rc;
  348.   if (maxlen < 1)
  349.     return -1;
  350.   str[0] = '';
  351.   /* allocate buffer, allow for overrun */
  352.   buf = BUFMALLOC(tmpbuf, maxlen + 1024);
  353.   if (!buf)
  354.     return -1;
  355. #if 0
  356.   try {
  357. #endif
  358.     char* newFormat = ConvertFormatForNarrowPrintf(format);
  359.     rc = vsnprintf(buf, maxlen, newFormat, args);
  360.     delete []newFormat;
  361. #if 0
  362.   } catch(...) {
  363.     if (strlen(format) < maxlen) {
  364.       strcpy(buf, format);
  365.       rc = strlen(buf);
  366.       if (rc + BAD_FORMAT_TEXT_LEN < maxlen) {
  367. strcat(buf, BAD_FORMAT_TEXT);
  368. rc += BAD_FORMAT_TEXT_LEN;
  369.       }
  370.     }
  371.   }
  372. #endif
  373.   /* copy buffer back */
  374.   if (rc >= 0) {
  375.     size_t len = strlen(buf);
  376.     if (len < maxlen) {
  377.       strcpy(str, buf);
  378.     } else {
  379.       strncpy(str, buf, maxlen - 1);
  380.       str[maxlen - 1] = '';
  381.     }
  382.   }
  383.   BUFFREE(tmpbuf, buf);
  384.   return rc;
  385. }
  386. SWIPRINTF_API int SWIvswprintf(wchar_t* wcs, size_t maxlen,
  387.        const wchar_t* format, va_list args)
  388. {
  389.   int rc;
  390.   if (maxlen < 1)
  391.     return -1;
  392.   wcs[0] = '';
  393. #if defined(__GNUC__) && (__GNUC__ <= 2)
  394.   /* Some versions of the GNU C library do not provide the required
  395.      vswprintf( ) function, so we emulate it by converting the format
  396.      string to narrow characters, do a narrow sprintf( ), then convert
  397.      back */
  398.   /* Use a temporary buffer for output to protect against relatively
  399.      small overruns */
  400.   char *buf, tmpbuf[BUFSIZE];
  401.   if (BUFSIZE < maxlen + 1024)
  402.     buf = new char[maxlen + 1024];
  403.   else
  404.     buf = tmpbuf;
  405.   if (!buf)
  406.     return -1;
  407.   /* convert format to narrow, a bit generous compared to the ANSI/ISO
  408.      C specifications for the printf( ) family format strings but we're
  409.      not trying to do full validation here anyway */
  410.   char *fmt, tmpfmt[BUFSIZE];
  411.   size_t fmtlen = wcslen(format);
  412.   if (BUFSIZE < fmtlen + 1)
  413.     fmt = new char[fmtlen + 1];
  414.   else
  415.     fmt = tmpfmt;
  416.   if (!fmt)
  417.     return -1;
  418.   format_wcs2str(format, fmt);
  419.   /* generate the final string based on the narrow format and arguments */
  420.   rc = vsnprintf(buf, maxlen, fmt, args);
  421.   /* copy back to wide characters */
  422.   size_t finallen = strlen(buf);
  423.   if (finallen >= maxlen)
  424.     finallen = maxlen - 1;
  425.   for (size_t i = 0; i < finallen; i++)
  426.     wcs[i] = buf[i];
  427.   wcs[finallen] = L'';
  428.   /* clean up */
  429.   if (buf != tmpbuf)
  430.     delete [] buf;
  431.   if (fmt != tmpfmt)
  432.     delete [] fmt;
  433. #else /* ! defined(__GNUC__) || (__GNUC__ > 2) */
  434.   wchar_t* newFormat = ConvertFormatForWidePrintf(format);
  435.   rc = vswprintf(wcs, maxlen, newFormat, args);
  436.   delete [] newFormat;
  437.   // vswprintf() returns a -1 on overflow but does not terminate
  438.   //   the string with a NULL character.
  439.   // Terminate the string with a NULL character in either of
  440.   //   these cases.
  441.   if ((size_t) rc >= maxlen - 1 || (size_t) rc == -1) /* overflow */
  442.     wcs[maxlen - 1] = L'';
  443. #endif /* defined(__GNUC__) && (__GNUC__ <= 2) */
  444.   return rc;
  445. }
  446. SWIPRINTF_API wchar_t *SWIfgetws(wchar_t *ws, int n, FILE *stream)
  447. {
  448.   char tmpbuf[BUFSIZE];
  449.   char *buf;
  450.   char *rs;
  451.   /* allocate local buffer */
  452.   buf = BUFMALLOC(tmpbuf, n);
  453.   if (!buf) {
  454.     return NULL;
  455.   }
  456.   rs = fgets(buf, n, stream);
  457.   if (rs == NULL) {
  458.     BUFFREE(tmpbuf, buf);
  459.     return NULL;
  460.   }
  461.   str2wcs(buf, ws);
  462.   BUFFREE(tmpbuf, buf);
  463.   return ws;
  464. }
  465. /* Only for linux: Solaris has a swscanf but doesn't have vsscanf!! */
  466. #if defined(_linux_)
  467. SWIPRINTF_API int SWIswscanf(const wchar_t *s, const wchar_t *format, ... )
  468. {
  469.   char tmpbuf[BUFSIZE];
  470.   char *buf;
  471.   char tmpfmt[BUFSIZE];
  472.   char *fmt;
  473.   va_list ap;
  474.   int rc;
  475.   buf = BUFMALLOC(tmpbuf, wcslen(s) + 1);
  476.   if (!buf) {
  477.     return 0;
  478.   }
  479.   fmt = BUFMALLOC(tmpfmt, wcslen(format) + 1);
  480.   if (!fmt) {
  481.     BUFFREE(tmpbuf, buf);
  482.     return 0;
  483.   }
  484.   /* convert buffers */
  485.   wcs2str(s, buf);
  486.   format_wcs2str(format, fmt);
  487.   va_start(ap, format);
  488.   rc = vsscanf(buf, fmt, ap);
  489.   va_end(ap);
  490.   /* we do not need to convert anything back */
  491.   BUFFREE(tmpbuf, buf);
  492.   BUFFREE(tmpfmt, fmt);
  493.   return rc;
  494. }
  495. #endif
  496. #elif defined(_win32_)
  497. SWIPRINTF_API int SWIvsprintf(char* str, size_t maxlen,
  498.       const char* format, va_list args)
  499. {
  500.   int rc;
  501.   if (maxlen < 1)
  502.     return -1;
  503.   str[0] = '';
  504. #if 0
  505.   try {
  506. #endif
  507.     rc = _vsnprintf(str, maxlen, format, args);
  508.     // vsnprintf() returns a -1 on overflow but does not terminate
  509.     //   the string with a NULL character.
  510.     // Terminate the string with a NULL character in either of
  511.     //   these cases.
  512.     if ((size_t) rc >= maxlen - 1 || (size_t) rc == -1) /* overflow */
  513.       str[maxlen - 1] = '';
  514. #if 0
  515.   } catch(...) {
  516.     if (strlen(format) < maxlen) {
  517.       strcpy(str, format);
  518.       rc = strlen(str);
  519.       if (rc + BAD_FORMAT_TEXT_LEN < maxlen) {
  520. strcat(str, BAD_FORMAT_TEXT);
  521. rc += BAD_FORMAT_TEXT_LEN;
  522.       }
  523.     }
  524.   }
  525. #endif
  526.   return rc;
  527. }
  528. SWIPRINTF_API int SWIvswprintf(wchar_t* wcs, size_t maxlen,
  529.        const wchar_t* format, va_list args)
  530. {
  531.   int rc;
  532.   if (maxlen < 1)
  533.     return -1;
  534.   wcs[0] = '';
  535. #if 0
  536.   try {
  537. #endif
  538.     rc = _vsnwprintf(wcs, maxlen, format, args);
  539.     // vsnwprintf() returns a -1 on overflow but does not terminate
  540.     //   the string with a NULL character.
  541.     // Terminate the string with a NULL character in either of
  542.     //   these cases.
  543.     if ((size_t) rc >= maxlen - 1 || (size_t) rc == -1) /* overflow */
  544.       wcs[maxlen - 1] = L'';
  545. #if 0
  546.   } catch(...) {
  547.     if (wcslen(format) < maxlen) {
  548.       wcscpy(wcs, format);
  549.       rc = wcslen(wcs);
  550.       if (rc + BAD_FORMAT_TEXT_LEN < maxlen) {
  551. wcscat(wcs, BAD_FORMAT_TEXT_W);
  552. rc += BAD_FORMAT_TEXT_LEN;
  553.       }
  554.     }
  555.   }
  556. #endif
  557.   return rc;
  558. }
  559. SWIPRINTF_API wchar_t *SWIfgetws(wchar_t *ws, int n, FILE *stream)
  560. {
  561.   return fgetws(ws, n, stream);
  562. }
  563. /* SWSCANF on Win32 is just a #define to the real version */
  564. #elif
  565. #error
  566. #endif