home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / odbc_hlp.zip / odbctran.zip / TRANSLAT.C < prev   
C/C++ Source or Header  |  1995-12-05  |  12KB  |  429 lines

  1. /*--------------------------------------------------------------+
  2. |  Purpose:                            |
  3. |    Translate text strings between OEM and ANSI.        |
  4. |    Convert to OEM for text passed to the database.        |
  5. |    Convert to ANSI for text returned from the database.    |
  6. |                                                               |
  7. |  Author: John Hobson            Date: April 1994    |
  8. |                                                               |
  9. |  Copyright: 1992-1995 INTERSOLV Inc.                |
  10. |                                                               |
  11. |       This software contains confidential and proprietary     |
  12. |       information of INTERSOLV Inc.                |
  13. +--------------------------------------------------------------*/
  14.  
  15. /*----------------+
  16. |  Include files  |
  17. +----------------*/
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include <malloc.h>
  23.  
  24. #if defined(__unix) || defined(QE_MAC) || defined(QE_MAC_PPC)
  25. #if !defined (__STDC__) && !defined (__cplusplus)
  26. #define const
  27. #define signed
  28. #endif
  29.  
  30. #include <qeodbc.h>
  31. #define DLLOVSPROC
  32. #define    BOOL    int
  33. #define HWND    int
  34. #define    DWORD    unsigned long
  35. #define FAR
  36. #define far
  37. #define lstrlen strlen
  38. #define    lstrcpyn strncpy
  39. typedef    int (* FARPROC)();
  40. #if defined(__aix) || defined(__unix)
  41. #define TYPEPARAM1(x) ((char *) (x))
  42. #define TYPEPARAM2(x) ((char *) (x))
  43. #ifdef __cplusplus
  44. #define    NULL    0
  45. #endif
  46. #else
  47. #define TYPEPARAM1(x) (x)
  48. #define TYPEPARAM2(x) (x)
  49. #endif
  50. #endif
  51.  
  52. #if defined (QE_MSDOS)
  53. #include "windows.h"
  54. #if defined (QE_WIN32)
  55. #define DLLOVSPROC __stdcall
  56. #define TYPEPARAM1(x) ((const char *)x)
  57. #define TYPEPARAM2(x) ((char *)x)
  58. #else
  59. #define DLLOVSPROC __loadds __export PASCAL FAR
  60. #define TYPEPARAM1(x) (x)
  61. #define TYPEPARAM2(x) (x)
  62. #endif
  63. #endif
  64.  
  65. #if defined (QE_OS2)
  66. #include <os2.h>
  67. #include <ivodbc.h>
  68. #define TYPEPARAM1(x) ((const char *) (x))
  69. #define TYPEPARAM2(x) ((char *) (x))
  70. #define DLLOVSPROC _Export _System
  71. #define    DWORD    unsigned long
  72. #define lstrlen strlen
  73. #define    lstrcpyn strncpy
  74. #endif
  75.  
  76. /*  Include the ODBC header files */
  77. #ifdef __cplusplus
  78. extern "C" {
  79. #endif
  80. #include "sql.h"
  81. #include "sqlext.h"
  82. #ifdef __cplusplus
  83. /* prototypes required if compiling with C++ */
  84. BOOL DLLOVSPROC
  85.         ConfigTranslator (HWND hwndParent, DWORD FAR * pvOption);
  86. BOOL DLLOVSPROC SQLDataSourceToDriver (
  87.         UDWORD          fOption,
  88.         SWORD           fSqlType,
  89.         PTR             rgbValueIn,
  90.         SDWORD          cbValueIn,
  91.         PTR             rgbValueOut,
  92.         SDWORD          cbValueOutMax,
  93.         SDWORD  FAR *   pcbValueOut,
  94.         UCHAR   FAR *   szErrorMsg,
  95.         SWORD           cbErrorMsgMax,
  96.         SWORD   FAR *   pcbErrorMsg
  97. );
  98. BOOL DLLOVSPROC SQLDriverToDataSource (
  99.         UDWORD          fOption,
  100.         SWORD           fSqlType,
  101.         PTR             rgbValueIn,
  102.         SDWORD          cbValueIn,
  103.         PTR             rgbValueOut,
  104.         SDWORD          cbValueOutMax,
  105.         SDWORD  FAR *   pcbValueOut,
  106.         UCHAR   FAR *   szErrorMsg,
  107.         SWORD           cbErrorMsgMax,
  108.         SWORD   FAR *   pcbErrorMsg
  109. );
  110. /* end of extern C prototypes, now do C++ prototypes */
  111. }
  112. #endif
  113.  
  114. #if defined (QE_WIN32)
  115. WINUSERAPI BOOL WINAPI AnsiToOem (const char * temp, char * out);
  116. WINUSERAPI BOOL WINAPI OemToAnsi (const char * temp, char * out);
  117. #else
  118. #ifndef QE_MSDOS
  119. void AnsiToOem (const char * temp, char * out);
  120. void OemToAnsi (const char * temp, char * out);
  121. #endif
  122. #endif
  123.  
  124. /*----------------------------------------------------------------------+
  125. | ConfigTranslator                            |
  126. | Purpose:    Provide data source to driver conversions.        |
  127. |        See Chapter 29 of the ODBC Programmer's reference V2.0    |
  128. +----------------------------------------------------------------------*/
  129.  
  130. extern BOOL DLLOVSPROC
  131. ConfigTranslator (
  132.     HWND        hwndParent,    /* Parent window, for dialog    */
  133.     DWORD FAR  *    pvOption)    /* Translation option        */
  134. {
  135.  
  136. /* We don't have any options, so return zero.    */
  137.  
  138.     *pvOption = 0;
  139.     return TRUE;
  140. }
  141.  
  142. void writeString (
  143.     UCHAR    FAR *    szErrorMsg,    /* Pointer to error message storage  */
  144.     SWORD        cbErrorMsgMax,    /* Space available for error message */
  145.     SWORD    FAR *    pcbErrorMsg,    /* Length of error message           */
  146.     UCHAR    FAR *    string)        /* String to add                     */
  147. {
  148.     short    currLen;
  149.     short len = lstrlen ((const char *) string);
  150.  
  151.  
  152. /* If we don't have an error msg string, return        */
  153.  
  154.     if (szErrorMsg == NULL) return;
  155.  
  156. /* Determine current length of error msg        */
  157.  
  158.     currLen = (pcbErrorMsg != NULL) ? *pcbErrorMsg :
  159.                 lstrlen ((const char *) szErrorMsg);
  160.  
  161. /* Add new string onto the end                */
  162.  
  163.     lstrcpyn ((char *) (szErrorMsg + currLen), (const char *) string,
  164.         (size_t) (cbErrorMsgMax - currLen));
  165.  
  166. /* Update error message length                */
  167.  
  168.     if (pcbErrorMsg != NULL)
  169.         if (len > (cbErrorMsgMax - currLen))
  170.             *pcbErrorMsg = cbErrorMsgMax;
  171.         else
  172.             *pcbErrorMsg += len;
  173.     return;
  174. }
  175.  
  176. /*----------------------------------------------------------------------+
  177. | SQLDataSourceToDriver                            |
  178. | Purpose:    Provide data source to driver conversions.        |
  179. |        See Chapter 29 of the ODBC Programmer's reference V2.    |
  180. | Parameters:                                |
  181. |        fOption        - Option value                |
  182. |        fSqlType    - SQL data type                |
  183. |        rgbValueIn    - Value to translate            |
  184. |        cbValueIn    - Length of value to translate        |
  185. |        rgbValueOut    - Translated value            |
  186. |        cbValueOutMax    - Space available for translated value    |
  187. |        pcbValueOut    - Length of translated value        |
  188. |        szErrorMsg    - Pointer to error message storage    |
  189. |        cbErrorMsgMax    - Space available for error message    |
  190. |        pcbErrorMsg    - Length of error message        |
  191. +----------------------------------------------------------------------*/
  192.  
  193. extern BOOL DLLOVSPROC
  194. SQLDataSourceToDriver (
  195.     UDWORD        fOption,
  196.         SWORD        fSqlType,
  197.         PTR        rgbValueIn,
  198.     SDWORD        cbValueIn,
  199.     PTR        rgbValueOut,
  200.     SDWORD        cbValueOutMax,
  201.     SDWORD    FAR *    pcbValueOut,
  202.     UCHAR    FAR *    szErrorMsg,
  203.     SWORD        cbErrorMsgMax,
  204.     SWORD    FAR *    pcbErrorMsg)
  205. {
  206.     UCHAR    FAR *    temp;
  207.     FILE    FAR *    file;
  208.  
  209. /* Initialize error message and length                */
  210.  
  211.     if (pcbErrorMsg != NULL) *pcbErrorMsg = 0;
  212.     if (szErrorMsg  != NULL)  *szErrorMsg = 0;
  213.  
  214. /* See if value is too large to translate            */
  215.  
  216.     if ((cbValueIn > cbValueOutMax) || (cbValueIn >= 0xffff)) {
  217.         writeString (szErrorMsg, cbErrorMsgMax, pcbErrorMsg,
  218.             (UCHAR *) "Input data too large to translate");
  219.         return FALSE;
  220.     }
  221.  
  222.     if ((fSqlType == SQL_CHAR) || (fSqlType == SQL_VARCHAR) ||
  223.         (fSqlType == SQL_LONGVARCHAR)) {
  224.  
  225. /* We are only converting character data            */
  226.  
  227.         temp = (UCHAR FAR *) malloc ((unsigned int) (cbValueIn + 1));
  228.         if (temp == NULL) {
  229. nomem:            writeString (szErrorMsg, cbErrorMsgMax, pcbErrorMsg,
  230.                 (UCHAR *) "Unable to allocate memory");
  231.             return FALSE;
  232.         }
  233.  
  234. /* Copy and null-terminate input                */
  235.  
  236.         memcpy (temp, rgbValueIn, (unsigned int) cbValueIn);
  237.         temp[cbValueIn] = 0;
  238.  
  239.         if (cbValueIn == cbValueOutMax) {
  240.             char *    out = (char *)malloc (
  241.                 (unsigned int) (cbValueIn+1));
  242.  
  243.             unsigned short    len;
  244.  
  245. /* Not enough room into output buffer for null-terminator;    */
  246. /* use a temporary                        */
  247.  
  248.             if (out == NULL) goto nomem;
  249.             OemToAnsi (TYPEPARAM1 (temp), TYPEPARAM2 (out));
  250.             len = lstrlen (out);
  251.             if (pcbValueOut != NULL) *pcbValueOut = len;
  252.  
  253. /* If there's room for the null-terminator, include it        */
  254.  
  255.             if (len < ((unsigned int) cbValueOutMax)) len++;
  256.             memcpy (rgbValueOut, out, len);
  257.             free (out);
  258.         } else {
  259.             OemToAnsi (TYPEPARAM1 (temp),
  260.                 TYPEPARAM2 (rgbValueOut));
  261.             if (pcbValueOut != NULL)
  262.                 *pcbValueOut =
  263.                     lstrlen (TYPEPARAM1 (rgbValueOut));
  264.         }
  265.  
  266.         if (fOption == 210) {
  267.  
  268. /* As debugging aide, if the fOption is 210, copy before    */
  269. /* and after data values to a file.                */
  270.  
  271. #if defined(__unix)
  272.             file = fopen ("/tmp/interslv.txt", "a");
  273. #else
  274.             file = fopen ("c:\\interslv.txt", "a");
  275. #endif
  276.             if (file != NULL) {
  277.                 fprintf (file, "Input : %s\n", temp);
  278.                 fprintf (file, "Output: %s\n", rgbValueOut);
  279.                 fclose (file);
  280.             }
  281.         }
  282.  
  283.         free (temp);
  284.     } else {
  285.  
  286. /* Copy input data to output                    */
  287.  
  288.         memcpy (rgbValueOut, rgbValueIn, (unsigned int) cbValueIn);
  289.  
  290. /* Set the return length                    */
  291.  
  292.         if (pcbValueOut != NULL) *pcbValueOut = cbValueIn;
  293.     }
  294.  
  295. /* return success                        */
  296.  
  297.     return (TRUE);
  298. }
  299.  
  300.  
  301. /*----------------------------------------------------------------------+
  302. |  SQLDriverToDataSource                        |
  303. |  Purpose:    Provide driver to data source conversions.        |
  304. |         See Chapter 29 of the ODBC Programmer's reference V2.0    |
  305. +----------------------------------------------------------------------*/
  306.  
  307. extern BOOL DLLOVSPROC
  308. SQLDriverToDataSource (
  309.     UDWORD        fOption,
  310.         SWORD        fSqlType,
  311.         PTR        rgbValueIn,
  312.     SDWORD        cbValueIn,
  313.     PTR        rgbValueOut,
  314.     SDWORD        cbValueOutMax,
  315.     SDWORD    FAR *    pcbValueOut,
  316.     UCHAR    FAR *    szErrorMsg,
  317.     SWORD        cbErrorMsgMax,
  318.     SWORD    FAR *    pcbErrorMsg)
  319. {
  320.     UCHAR    FAR *    temp;
  321.     FILE    FAR *    file;
  322.  
  323. /* Initialize error message and length                */
  324.  
  325.     if (pcbErrorMsg != NULL) *pcbErrorMsg = 0;
  326.     if (szErrorMsg  != NULL)  *szErrorMsg = 0;
  327.  
  328. /* See if value is too large to translate            */
  329.  
  330.     if ((cbValueIn > cbValueOutMax) || (cbValueIn >= 0xffff)) {
  331.         writeString (szErrorMsg, cbErrorMsgMax, pcbErrorMsg,
  332.             (UCHAR *) "Input data too large to translate");
  333.         return FALSE;
  334.     }
  335.  
  336.     if ((fSqlType == SQL_CHAR) || (fSqlType == SQL_VARCHAR) ||
  337.         (fSqlType == SQL_LONGVARCHAR)) {
  338.  
  339. /* We are only converting character data            */
  340.  
  341.         temp = (UCHAR FAR *) malloc ((unsigned int) (cbValueIn + 1));
  342.         if (temp == NULL) {
  343. nomem:            writeString (szErrorMsg, cbErrorMsgMax, pcbErrorMsg,
  344.                 (UCHAR *) "Unable to allocate memory");
  345.             return FALSE;
  346.         }
  347.  
  348. /* Copy and null-terminate input                */
  349.  
  350.         memcpy (temp, rgbValueIn, (unsigned int) cbValueIn);
  351.         temp[cbValueIn] = 0;
  352.  
  353.         if (cbValueIn == cbValueOutMax) {
  354.             UCHAR FAR *    out = (UCHAR FAR *)malloc (
  355.                 (unsigned int) (cbValueIn + 1));
  356.             unsigned short    len;
  357.  
  358. /* Not enough room into output buffer for null-terminator;    */
  359. /* use a temporary                        */
  360.  
  361.             if (out == NULL) goto nomem;
  362.             AnsiToOem (TYPEPARAM1 (temp), TYPEPARAM2 (out));
  363.             len = lstrlen ((const char *) out);
  364.             if (pcbValueOut != NULL) *pcbValueOut = len;
  365.  
  366. /* If there's room for the null-terminator, include it        */
  367.  
  368.             if (len < ((unsigned int) cbValueOutMax)) len++;
  369.             memcpy (rgbValueOut, out, len);
  370.             free (out);
  371.         } else {
  372.             AnsiToOem (TYPEPARAM1 (temp),
  373.                 TYPEPARAM2 (rgbValueOut));
  374.             if (pcbValueOut != NULL)
  375.                 *pcbValueOut =
  376.                     lstrlen (TYPEPARAM1 (rgbValueOut));
  377.         }
  378.  
  379.         if (fOption == 210) {
  380.  
  381. /* As debugging aide, if the fOption is 210, copy before    */
  382. /* and after data values to a file.                */
  383.  
  384. #if defined(__unix)
  385.             file = fopen ("/tmp/interslv.txt", "a");
  386. #else
  387.             file = fopen ("c:\\interslv.txt", "a");
  388. #endif
  389.             if (file != NULL) {
  390.                 fprintf (file, "Input : %s\n", temp);
  391.                 fprintf (file, "Output: %s\n", rgbValueOut);
  392.                 fclose (file);
  393.             }
  394.         }
  395.  
  396.         free (temp);
  397.     } else {
  398.  
  399. /* Copy input data to output                    */
  400.  
  401.         memcpy (rgbValueOut, rgbValueIn, (unsigned int) cbValueIn);
  402.  
  403. /* Set the return length                    */
  404.  
  405.         if (pcbValueOut != NULL) *pcbValueOut = cbValueIn;
  406.     }
  407.  
  408. /* return success                        */
  409.  
  410.     return (TRUE);
  411. }
  412.  
  413. #if defined (QE_OS2) || defined (__unix) || defined(QE_MAC) || defined (QE_MAC_PPC)
  414. /*    dummy these out since they're not meaningful for os2.    */
  415. void AnsiToOem (const char * temp, char * out)
  416. {
  417.     strcpy(out, temp);
  418. }
  419.  
  420. void OemToAnsi (const char * temp, char * out)
  421. {
  422.     strcpy(out, temp);
  423. }
  424.  
  425. #endif
  426.  
  427.  
  428.  
  429.