cs.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:15k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cs.c,v $
  4.  * PRODUCTION Revision 1000.1  2003/11/17 22:20:08  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [ORIGINAL] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
  10.  * Copyright (C) 1998-1999  Brian Bruns
  11.  *
  12.  * This library is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Library General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Library General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Library General Public
  23.  * License along with this library; if not, write to the
  24.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25.  * Boston, MA 02111-1307, USA.
  26.  */
  27. #include <tds_config.h>
  28. #include <cspublic.h>
  29. #include <tdsconvert.h>
  30. #include <time.h>
  31. static char  software_version[]   = "$Id: cs.c,v 1000.1 2003/11/17 22:20:08 gouriano Exp $";
  32. static void *no_unused_var_warn[] = {software_version,
  33.                                      no_unused_var_warn};
  34. CS_RETCODE cs_ctx_alloc(CS_INT version, CS_CONTEXT **ctx)
  35. {
  36. TDSCONTEXT *tds_ctx;
  37. *ctx = (CS_CONTEXT *) malloc(sizeof(CS_CONTEXT));
  38. memset(*ctx,'',sizeof(CS_CONTEXT));
  39. tds_ctx = tds_alloc_context();
  40. tds_ctx_set_parent(tds_ctx, *ctx);
  41. (*ctx)->tds_ctx = tds_ctx;
  42. if( tds_ctx->locale && !tds_ctx->locale->date_fmt ) {
  43. /* set default in case there's no locale file */
  44. tds_ctx->locale->date_fmt = strdup("%b %e %Y %l:%M%p"); 
  45. }
  46. return CS_SUCCEED;
  47. }
  48. CS_RETCODE cs_ctx_drop(CS_CONTEXT *ctx)
  49. {
  50. if (ctx) {
  51. if (ctx->tds_ctx) 
  52. tds_free_context(ctx->tds_ctx);
  53. free(ctx);
  54. }
  55. return CS_SUCCEED;
  56. }
  57. CS_RETCODE cs_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  58. {
  59. return CS_SUCCEED;
  60. }
  61. CS_RETCODE cs_convert(CS_CONTEXT *ctx, CS_DATAFMT *srcfmt, CS_VOID *srcdata, 
  62.                       CS_DATAFMT *destfmt, CS_VOID *destdata, CS_INT *resultlen)
  63. {
  64. int src_type, src_len, desttype, destlen, len, i = 0;
  65. CONV_RESULT cres;
  66. unsigned char *dest;
  67. CS_RETCODE ret;
  68.     tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert()n");
  69.     src_type = _ct_get_server_type(srcfmt->datatype);
  70.     src_len  =  srcfmt ? srcfmt->maxlength : 0;
  71.     desttype = _ct_get_server_type(destfmt->datatype);
  72.     destlen  =  destfmt ? destfmt->maxlength : 0;
  73.     tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() srctype = %d (%d) desttype = %d (%d)n",
  74.                 src_type, src_len, desttype, destlen);
  75.     if (destlen <= 0)
  76.        return CS_SUCCEED;
  77.     dest = (unsigned char *)destdata;
  78.     /* If source is indicated to be NULL, set dest to low values */
  79.     if (srcdata == NULL) {
  80.        tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() srcdata is nulln");
  81.        memset(dest,'', destlen);
  82.        if (resultlen != (CS_INT *)NULL ) *resultlen = 0;
  83.        return CS_SUCCEED;
  84.     }
  85.        
  86.     /* many times we are asked to convert a data type to itself */
  87.     if (src_type == desttype) {
  88.        tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() srctype = desttypen");
  89.        switch (desttype) {
  90.           case SYBBINARY:
  91.           case SYBIMAGE:
  92.                if (src_len > destlen) {
  93.                   ret = CS_FAIL;
  94.                }
  95.                else {
  96.                   switch (destfmt->format) {
  97.                       case CS_FMT_PADNULL:
  98.                           memcpy(dest, srcdata, src_len);
  99.                           for ( i = src_len; i < destlen; i++)
  100.                               dest[i] = '';
  101.                           if (resultlen != (CS_INT *)NULL ) *resultlen = destlen;
  102.                           ret = CS_SUCCEED;
  103.                           break;
  104.                       case CS_FMT_UNUSED:
  105.                           memcpy(dest, srcdata, src_len);
  106.                           if (resultlen != (CS_INT *)NULL ) *resultlen = src_len;
  107.                           ret = CS_SUCCEED;
  108.                           break;
  109.                       default:
  110.                           ret = CS_FAIL;
  111.                           break;
  112.                           
  113.                   }
  114.                }
  115.                break;
  116.           case SYBCHAR:
  117.           case SYBVARCHAR:
  118.           case SYBTEXT:
  119.                tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() desttype = charactern");
  120.                if (src_len > destlen ) {
  121.                   ret = CS_FAIL;
  122.                }
  123.                else {
  124.                   switch (destfmt->format) {
  125.       
  126.                       case CS_FMT_NULLTERM:
  127.                           if (src_len == destlen ) { 
  128.                              ret = CS_FAIL;    /* not enough room for data + a null terminator - error */
  129.                           }
  130.                           else {
  131.                              memcpy(dest, srcdata, src_len);
  132.                              dest[src_len] = '';
  133.                              if (resultlen != (CS_INT *)NULL ) *resultlen = src_len+1;
  134.                              ret = CS_SUCCEED;
  135.                           }
  136.                           break;
  137.                              
  138.                       case CS_FMT_PADBLANK:
  139.                           memcpy(dest, srcdata, src_len);
  140.                           for ( i = src_len; i < destlen; i++)
  141.                               dest[i] = ' ';
  142.                           if (resultlen != (CS_INT *)NULL ) *resultlen = destlen;
  143.                           ret = CS_SUCCEED;
  144.                           break;
  145.                       case CS_FMT_PADNULL:
  146.                           memcpy(dest, srcdata, src_len);
  147.                           for ( i = src_len; i < destlen; i++)
  148.                               dest[i] = '';
  149.                           if (resultlen != (CS_INT *)NULL ) *resultlen = destlen;
  150.                           ret = CS_SUCCEED;
  151.                           break;
  152.                       case CS_FMT_UNUSED:
  153.                           memcpy(dest, srcdata, src_len);
  154.                           if (resultlen != (CS_INT *)NULL ) *resultlen = src_len;
  155.                           ret = CS_SUCCEED;
  156.                           break;
  157.                       default:
  158.                           ret = CS_FAIL;
  159.                           break;
  160.                   }
  161.                }
  162.                break;
  163.           case SYBINT1:
  164.           case SYBINT2:
  165.           case SYBINT4:
  166.           case SYBFLT8:
  167.           case SYBREAL:
  168.           case SYBBIT:
  169.           case SYBBITN:
  170.           case SYBMONEY:
  171.           case SYBMONEY4:
  172.           case SYBDATETIME:
  173.           case SYBDATETIME4:
  174.                if (src_len > destlen) {
  175.                   ret = CS_FAIL;
  176.                }
  177.                else {
  178.                   memcpy (dest, srcdata, src_len);
  179.                   if (resultlen != (CS_INT *)NULL ) *resultlen = src_len;
  180.                   ret = CS_SUCCEED;
  181.                } 
  182.                break;
  183.           case SYBNUMERIC:
  184.           case SYBDECIMAL:
  185.                if (src_len > destlen ) {
  186.                   ret = CS_FAIL;
  187.                }
  188.                else {
  189.                   memcpy (dest, srcdata, src_len);
  190.                   if (resultlen != (CS_INT *)NULL ) *resultlen = src_len;
  191.                   ret = CS_SUCCEED;
  192.                } 
  193.                break;
  194.  
  195.           default:
  196.                ret = CS_FAIL;
  197.                break;
  198.        }
  199.       
  200.        return ret;
  201.     }  /* src type == dest type */
  202. /* set the output precision/scale for conversions to numeric type */
  203. if (is_numeric_type(desttype)) {
  204. cres.n.precision = destfmt->precision;
  205. cres.n.scale     = destfmt->scale;
  206. if (destfmt->precision == CS_SRC_VALUE)
  207. cres.n.precision = srcfmt->precision;
  208. if (destfmt->scale == CS_SRC_VALUE)
  209. cres.n.scale = srcfmt->scale;
  210. }
  211.     
  212.     tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() calling tds_convertn");
  213.     len = tds_convert(ctx->tds_ctx, src_type, srcdata, src_len, desttype, &cres);
  214.     if (len == TDS_FAIL)
  215.        return CS_FAIL;
  216.     tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() tds_convert returned %dn", len);
  217.     switch (desttype) {
  218.         case SYBBINARY:
  219.         case SYBIMAGE:
  220.              if (len > destlen) {
  221.                 free(cres.ib);
  222.                 fprintf(stderr,"error_handler: Data-conversion resulted in overflow.n");
  223.                 ret = CS_FAIL;
  224.              }
  225.              else {
  226.                 memcpy(dest, cres.ib, len);
  227.                 free(cres.ib);
  228.                 for ( i = len ; i < destlen; i++ )
  229.                     dest[i] = '';
  230.                 if (resultlen != (CS_INT *)NULL ) *resultlen = destlen;
  231.                 ret = CS_SUCCEED;
  232.              }
  233.              break;
  234.         case SYBBIT:
  235.         case SYBBITN:
  236.      /* fall trough, act same way of TINYINT */
  237.         case SYBINT1:
  238.              memcpy(dest,&(cres.ti),1);
  239.              if (resultlen != (CS_INT *)NULL ) *resultlen = 1;
  240.              ret = CS_SUCCEED;
  241.              break;
  242.         case SYBINT2:
  243.              memcpy(dest,&(cres.si),2);
  244.              if (resultlen != (CS_INT *)NULL ) *resultlen = 2;
  245.              ret = CS_SUCCEED;
  246.              break;
  247.         case SYBINT4:
  248.              memcpy(dest,&(cres.i),4);
  249.              if (resultlen != (CS_INT *)NULL ) *resultlen = 4;
  250.              ret = CS_SUCCEED;
  251.              break;
  252.         case SYBFLT8:
  253.              memcpy(dest,&(cres.f),8);
  254.              if (resultlen != (CS_INT *)NULL ) *resultlen = 8;
  255.              ret = CS_SUCCEED;
  256.              break;
  257.         case SYBREAL:
  258.              memcpy(dest,&(cres.r),4);
  259.              if (resultlen != (CS_INT *)NULL ) *resultlen = 4;
  260.              ret = CS_SUCCEED;
  261.              break;
  262.         case SYBMONEY:
  263.              
  264.              tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() copying %d bytes to srcn", sizeof(TDS_MONEY));
  265.              memcpy(dest,&(cres.m),sizeof(TDS_MONEY));
  266.              if (resultlen != (CS_INT *)NULL ) *resultlen = sizeof(TDS_MONEY);
  267.              ret = CS_SUCCEED;
  268.              break;
  269.         case SYBMONEY4:
  270.              memcpy(dest,&(cres.m4),sizeof(TDS_MONEY4));
  271.              if (resultlen != (CS_INT *)NULL ) *resultlen = sizeof(TDS_MONEY4);
  272.              ret = CS_SUCCEED;
  273.              break;
  274.         case SYBDATETIME:
  275.              memcpy(dest,&(cres.dt),sizeof(TDS_DATETIME));
  276.              if (resultlen != (CS_INT *)NULL ) *resultlen = sizeof(TDS_DATETIME);
  277.              ret = CS_SUCCEED;
  278.              break;
  279.         case SYBDATETIME4:
  280.              memcpy(dest,&(cres.dt4),sizeof(TDS_DATETIME4));
  281.              if (resultlen != (CS_INT *)NULL ) *resultlen = sizeof(TDS_DATETIME4);
  282.              ret = CS_SUCCEED;
  283.              break;
  284.         case SYBNUMERIC:
  285.         case SYBDECIMAL:
  286.              memcpy(dest,&(cres.n), sizeof(TDS_NUMERIC));
  287.              if (resultlen != (CS_INT *)NULL ) *resultlen = sizeof(TDS_NUMERIC);
  288.              ret = CS_SUCCEED;
  289.              break;
  290.         case SYBCHAR:
  291.         case SYBVARCHAR:
  292.         case SYBTEXT:
  293.              if (len > destlen) {
  294.                 fprintf(stderr,"error_handler: Data-conversion resulted in overflow.n");
  295.                 ret = CS_FAIL;
  296.              }
  297.              else {
  298.                 switch (destfmt->format) {
  299.     
  300.                     case CS_FMT_NULLTERM:
  301.                         tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() FMT_NULLTERMn");
  302.                         if (len == destlen ) { 
  303.                            tdsdump_log(TDS_DBG_FUNC, "%L not enough room for data + a null terminator - errorn");
  304.                            ret = CS_FAIL;    /* not enough room for data + a null terminator - error */
  305.                         }
  306.                         else {
  307.                            memcpy(dest, cres.c, len);
  308.    dest[len] = 0;
  309.                            if (resultlen != (CS_INT *)NULL ) *resultlen = len+1;
  310.                            ret = CS_SUCCEED;
  311.                         }
  312.                         break;
  313.                            
  314.                     case CS_FMT_PADBLANK:
  315.                         tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() FMT_PADBLANKn");
  316. /* strcpy here can lead to a small buffer overflow */
  317.                         memcpy(dest, cres.c, len);
  318.                         for ( i = len; i < destlen; i++)
  319.                             dest[i] = ' ';
  320.                         if (resultlen != (CS_INT *)NULL ) *resultlen = destlen;
  321.                         ret = CS_SUCCEED;
  322.                         break;
  323.                     case CS_FMT_PADNULL:
  324.                         tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() FMT_PADNULLn");
  325. /* strcpy here can lead to a small buffer overflow */
  326.                         memcpy(dest, cres.c, len);
  327.                         for ( i = len; i < destlen; i++)
  328.                             dest[i] = '';
  329.                         if (resultlen != (CS_INT *)NULL ) *resultlen = destlen;
  330.                         ret = CS_SUCCEED;
  331.                         break;
  332.                     case CS_FMT_UNUSED:
  333.                         tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() FMT_UNUSEDn");
  334.                         memcpy(dest, cres.c, len);
  335.                         if (resultlen != (CS_INT *)NULL ) *resultlen = len;
  336.                         ret = CS_SUCCEED;
  337.                         break;
  338.                     default:
  339.                         ret = CS_FAIL;
  340.                         break;
  341.                 }
  342.              }
  343.              free(cres.c);
  344.              break;
  345.     }
  346.     tdsdump_log(TDS_DBG_FUNC, "%L inside cs_convert() returning  %dn", ret);
  347.     return (ret);
  348. }
  349. CS_RETCODE cs_dt_crack(CS_CONTEXT *ctx, CS_INT datetype, CS_VOID *dateval, CS_DATEREC *daterec)
  350. {
  351. CS_DATETIME *dt;
  352. CS_DATETIME4 *dt4;
  353. time_t tmp_secs_from_epoch;
  354. struct tm *t;
  355. TDSDATEREC dr;
  356. if (datetype == CS_DATETIME_TYPE) {
  357. dt = (TDS_DATETIME *)dateval;
  358. tds_datecrack(SYBDATETIME, dt, &dr);
  359. } else if (datetype == CS_DATETIME4_TYPE) {
  360. dt4 = (TDS_DATETIME4 *)dateval;
  361. tds_datecrack(SYBDATETIME4, dt4, &dr);
  362. } else {
  363. return CS_FAIL;
  364. }
  365.     t = (struct tm *) gmtime(&tmp_secs_from_epoch);
  366. daterec->dateyear   = dr.year;
  367. daterec->datemonth  = dr.month;
  368. daterec->datedmonth = dr.day;
  369. daterec->datedyear  = dr.dayofyear;
  370. daterec->datedweek  = dr.weekday;
  371. daterec->datehour   = dr.hour;
  372. daterec->dateminute = dr.minute;
  373. daterec->datesecond = dr.second;
  374. daterec->datetzone   = 0; 
  375. return CS_SUCCEED;
  376. }
  377. CS_RETCODE cs_loc_alloc(CS_CONTEXT *ctx, CS_LOCALE **locptr)
  378. return CS_SUCCEED;
  379. }
  380. CS_RETCODE cs_loc_drop(CS_CONTEXT *ctx, CS_LOCALE *locale)
  381. return CS_SUCCEED;
  382. }
  383. CS_RETCODE cs_locale(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  384. return CS_SUCCEED;
  385. }
  386. CS_RETCODE cs_dt_info(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_INT item, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  387. {
  388. if (action==CS_SET) {
  389. switch(type) {
  390. case CS_DT_CONVFMT:
  391. break;
  392. }
  393. }
  394. return CS_SUCCEED;
  395. }