.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VPA04TC$
.tt 2 $$$
.TT 3 $BurkhardD$CONVERSION TO DATABASE$2000-08-24$
***********************************************************
.nf

.nf

.nf

    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo


.fo


.fo
Module  :
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
Define  :
#ifndef DEBUG
#line 21 "vpa04tc" 
#endif
.CM *-END-* define --------------------------------------
Use     :
.CM *-END-* use -----------------------------------------
Synonym :
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : BurkhardD
.sp
.cp 3
Created : 08-31-1993
.sp
.cp 3
Version : 1994-04-25
.sp
.cp 3
Release :      Date : 2000-08-24
.sp
Release :      Date : 2000-08-24
Specification:
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.CM -lll-
Code    :
#ifndef DEBUG
#line 67 "vpa04tc" 
#endif
#define PRINT_ULONG "%lu"
#define PRINT_USHORT "%u"

#define SAPDB_MIN_INT4 (SAPDB_MAX_INT4-1L)

#include <stdlib.h>
#include <time.h>
#include <ctype.h>

#include "vpa00global.h"
#include "hpa05num.h"
#include "hsp78_0.h"

VOID apdexp(UCHAR FAR *string_ptr, SWORD FAR *exponent_ptr);

/* Prototypes */
void FAR PCALL s41pbyte (char*, tsp00_Int4, int*, const char*, 
                         tsp00_Int4, int, char*);
void FAR PCALL s40gbyte (const char *, tsp00_Int4, int, char*, 
                         tsp00_Int4, int, char*);

extern const tsp77encoding *pa04gGetEncodingType(SWORD format);

BOOLEAN pa04t_NumericNotNull( SQL_NUMERIC_STRUCT  *numeric );


/* apthx2by() - convert hexadecimalstring to a binarystring    */
API_RETCODE apthx2by(UCHAR  *in_string_ptr,
                     UDWORD  in_length,
                     SWORD   in_format,
                     UCHAR  *out_string_ptr,
                     UDWORD  out_length,
                     SWORD   out_format )
{
    API_RETCODE  api_retcode;
    UDWORD       len_in;
    SWORD        invalid = 0;
    int   localLen;              /* PTS 1113731 */

    API_TRACE(API_TR_ENTRY, "apthx2by", 0);
    API_TRACE(API_TR_PTR, "in_string_ptr", &in_string_ptr);
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE(API_TR_UWORD, "in_format", &in_format);
    API_TRACE(API_TR_PTR, "out_string_ptr", &out_string_ptr);
    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE(API_TR_SWORD, "out_format", &out_format);  

    api_retcode = API_OK;

    if (in_length == SQL_NTS) {
        in_length = (SQLUINTEGER) API_STRLEN(in_string_ptr);
    }
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE_LEN(API_TR_ODBC_STRING, "in_string_ptr", in_string_ptr, in_length);
    if (in_length < out_length)  
        {
            len_in  = in_length;
        }
    else {
        len_in  = out_length / 2;
        api_retcode = API_TRUNCATE;
    }
    s41pbyte ( (char*) out_string_ptr, 1, &localLen,
               (char*) in_string_ptr, 1,
               (int) len_in, (char *)&invalid );
    out_length = localLen;

    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE_BUF(out_string_ptr, 1, out_length);
    API_TRACE(API_TR_SWORD, "invalid", &invalid);
    if (invalid) {
        api_retcode = API_NOT_NUMBER;
    }
    API_TRACE(API_TR_EXIT,"apthx2by",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* apthx2by */

/* aptnm2wch () - convert numericstring to a wide string    */
API_RETCODE aptnm2chw (UCHAR  *in_string_ptr,
                       UWORD   in_format,
                       UCHAR  *out_string_ptr,
                       UDWORD  out_length,
                       UWORD   out_scale,
                       UWORD   out_format,
                       UDWORD *used)
{
  API_RETCODE  api_retcode = API_OK;
  UCHAR *outPtr;
  UCHAR localString[API_CHAR_LENGTH_CHAR+1];
  int  allocFlag = 0;
  tsp78ConversionResult convRes;
  tsp00_Uint4 destBytesWritten, srcBytesParsed;

  if (out_length >= sizeof (localString)) {
    allocFlag = 1;
    outPtr = apdallo (out_length);
    if (outPtr == NULL) {
      api_retcode = API_NOT_OK;
      goto exit;
    }
  }
  else
    outPtr = localString;

  api_retcode =
    aptnm2ch( in_string_ptr, in_format,
              outPtr,        out_length,
              out_scale,     SQL_VARCHAR,  used);

  /* preserve space for terminator */
  out_length -= sp77encodingUCS2Native->fixedCharacterSize;

  convRes = sp78convertBuffer (sp77encodingUCS2Native, 
                               out_string_ptr, out_length,
                               &destBytesWritten,
                               sp77encodingAscii,
                               outPtr, *used,
                               &srcBytesParsed);

  /* append terminator */
  API_MEMCPY (((CHAR*)out_string_ptr)+destBytesWritten,
              sp77encodingUCS2Native->charTable->terminator.bytes,
              sp77encodingUCS2Native->charTable->terminator.byteCount);

  *used = destBytesWritten;

  if (convRes != sp78_Ok && convRes != sp78_TargetExhausted)
    api_retcode = API_NOT_OK;
  else
    if (convRes == sp78_TargetExhausted)
      api_retcode = API_TRUNCATE;

  if (allocFlag != 0)
    apdfree (outPtr);

 exit:
  return (api_retcode);

}

/* aptnm2ch () - convert numericstring to a string    */
API_RETCODE aptnm2ch ( UCHAR  *in_string_ptr,
                       UWORD   in_format,
                       UCHAR  *out_string_ptr,
                       UDWORD  out_length,
                       UWORD   out_scale,
                       UWORD   out_format,
                       UDWORD *used)
{
    SWORD        right_digits;
    SWORD        left_digits;
    SWORD        sign_digits;
    SWORD        sign_indicator;
    SWORD        exponent;
    SWORD        len;
    SWORD        e_len;
    UDWORD       in_length;
    UCHAR       *ptr;
    UCHAR       *e_pos;
    API_RETCODE  api_retcode;

    API_TRACE(API_TR_ENTRY,"aptnm2ch",0);
    API_TRACE(API_TR_PTR,"in_string_ptr",&in_string_ptr);
    API_TRACE(API_TR_UWORD,"in_format",&in_format);
    API_TRACE(API_TR_PTR,"&out_string_ptr",&out_string_ptr);
    API_TRACE(API_TR_UDWORD,"out_length",&out_length);
    API_TRACE(API_TR_UWORD,"out_scale",&out_scale);
    API_TRACE(API_TR_UWORD,"out_format",&out_format);  
    API_TRACE(API_TR_PTR, "&used", &used);  

    api_retcode = API_OK;

    right_digits   = 0;
    left_digits    = 0;
    sign_digits    = 0;
    sign_indicator = 0;
    e_len          = 0;
    len            = 0;
    ptr            = in_string_ptr;
    
    /* skip leading spaces */
    while (*ptr == ' ') {
        ptr++;
    };
    in_length = (SQLUINTEGER) API_STRLEN(ptr);
    API_TRACE(API_TR_UDWORD,"in_length",&in_length);
    if (in_length == 0) {
        api_retcode = API_NOT_NUMBER;
    }
    if (api_retcode == API_OK) {
        /* scan input string */
        aptanly( ptr,
                 (UWORD*) &right_digits, (UWORD*) &left_digits,
                 (UWORD*) &sign_digits, (UWORD*) &sign_indicator,
                 (SWORD*) &exponent );
        if (exponent != 0) {
            /* get exponent string */
            if ((e_pos = (UCHAR*) API_STRCHR(ptr, 'E')) == NULL)
                e_pos = (UCHAR*) API_STRCHR(ptr, 'e');
            e_len = (SWORD)API_STRLEN(e_pos);
        }
        if (left_digits > 0) {
            if ((SWORD)out_scale < left_digits) {
                api_retcode = API_TRUNCATE;
                if (out_scale > 0) {
                    len = (SWORD) (out_scale + 1);
                }	    
            } 
            else {
                len = (SWORD) (left_digits + 1);
            }
        }
        API_TRACE(API_TR_SWORD, "len",&len);
      
        if (out_length < 1
            || (UDWORD)(right_digits + len + e_len) > out_length -1 ) {
            api_retcode = API_DATA_LOSS;
        }
        else {
            API_MEMCPY(out_string_ptr, ptr, (int) sign_digits);
            *used = sign_digits;
            API_TRACE_LEN(API_TR_ODBC_STRING,
                          "out_string_ptr", out_string_ptr, *used);
            ptr += sign_digits;
            if (len > 0) {
                API_MEMCPY(out_string_ptr+*used, ptr, len);
                *used += len;
                ptr += len;
                API_TRACE_LEN(API_TR_ODBC_STRING,
                              "out_string_ptr", out_string_ptr, *used);
            }
            else
                if (len == 0 && (right_digits-sign_indicator) == 0) {
                    *out_string_ptr = '0';
                    *used = 1;
                }
            if (e_len > 0) {
                API_MEMCPY(out_string_ptr+*used, ptr, e_len);
                *used += e_len;
                API_TRACE_LEN(API_TR_ODBC_STRING,
                              "out_string_ptr", out_string_ptr, *used);
            }
            if (out_format == SQL_CHAR ) {
                if (out_length > *used + 1) {
                    API_MEMSET(out_string_ptr+*used, ' ',
                               (SWORD)(out_length-*used-1));
                    *used = out_length-1;
                }
            }
            *(out_string_ptr+*used) = 0;
            if (api_retcode == API_TRUNCATE)
                *used += (left_digits - out_scale);
        }
    }

    API_TRACE(API_TR_EXIT,"aptnm2ch",0);
    API_TRACE(API_TR_STRING,"out_string_ptr",out_string_ptr);
    API_TRACE(API_TR_UDWORD,"*used", used);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* aptnm2ch */


/* function to check whether the input string is a number */
/*   and to convert E-notation format to a decimal format */
API_RETCODE aptchst( UCHAR  *string_ptr)
{
    UCHAR       *last_ptr;    /* MUST be static near for DLL */
    SDOUBLE      local_double;
    UCHAR        local_string [API_CHAR_LENGTH_CHAR];
    UWORD        string_len = 0;
    UWORD        right_digits = 0;
    UWORD        left_digits = 0;
    UWORD        sign_digits = 0;
    UWORD        sign_indicator = 0;
    SWORD        exponent = 0;
    UCHAR       *e_pos_ptr;
    API_RETCODE  api_retcode;

    API_TRACE(API_TR_ENTRY,"aptchst", 0);
    API_TRACE(API_TR_PTR,"string_ptr", &string_ptr);
    API_TRACE(API_TR_STRING,"string_ptr", string_ptr);

    api_retcode = API_OK;
    /* check for string not eq."" */
    if (string_ptr [0] == '\0') {
        api_retcode = API_NOT_NUMBER;
    }
 
    /* check for a numeric string */
    /* via conversion to double   */
    local_double = (SDOUBLE) strtod( (char*) string_ptr, (char**) &last_ptr);
    if ((errno == ERANGE) || ((*last_ptr != '\0') && (*last_ptr != ' ')) ) {
        errno = 0;
        api_retcode = API_NOT_NUMBER;
    }
  
    if (api_retcode == API_OK) {
        /* check for number of digits   */
        if (API_STRLEN(string_ptr) > (size_t) API_DOUBLE_PREC) {
            /* if length > double-precision */
            /* check for E-notation         */
            e_pos_ptr = (UCHAR*) API_STRCHR(string_ptr, 'e');
            if (e_pos_ptr == NULL) {
                e_pos_ptr = (UCHAR*) API_STRCHR(string_ptr, 'E');
            }
            /* terminate string without E-not*/
            if (e_pos_ptr != NULL) {
                string_len = (UWORD) (e_pos_ptr - string_ptr);
                API_STRNCPY((UCHAR*) local_string,
                            string_ptr,
                            string_len);
                local_string [string_len] = '\0';
            }
            else {
                API_STRCPY( (UCHAR*) local_string, string_ptr);
            }
            /* check for number of used dig.*/
            aptanly( local_string,
                     (UWORD*) &right_digits, (UWORD*) &left_digits,
                     (UWORD*) &sign_digits, (UWORD*) &sign_indicator,
                     (SWORD*) &exponent);
            /* check if truncation leads to */
            /* data-loss or truncation      */ 
            if ((UWORD)(right_digits + left_digits) > API_DOUBLE_PREC) {
                API_SPRINTF( (char*) local_string, PRINT_DOUBLE, local_double);
                apdexp(local_string, (SWORD FAR *) &exponent);  
                if (exponent > (API_DOUBLE_PREC + 1) ) {
                    api_retcode = API_DATA_LOSS;
                }
                else {
                    api_retcode = API_TRUNCATE;
                }
            }
        }
    
        if (api_retcode != API_DATA_LOSS) {
            /* convert the double variable  */
            /* to a character string        */
            pa08flt(string_ptr, (SDOUBLE) local_double, SQL_DOUBLE);
        }
   
    }

    API_TRACE(API_TR_EXIT,"aptchst", 0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode", &api_retcode);
    if (api_retcode != API_DATA_LOSS)
        {
            if (string_ptr != NULL) {
                API_TRACE(API_TR_STRING,"*string", string_ptr);
            }
        }

    return(api_retcode);
} /* aptchst */


enum ScannerStates {
    ST_START,
    ST_LEFTDIGITS,
    ST_RIGHTDIGITS,
    ST_EXP,
    ST_EXPSIGN,
    ST_EXPDIGITS,
    ST_SUCCESS,
    ST_ERROR
};


/* try to match string_ptr with the regular expression
 * [{+|-}]<digit>*[.<digit>*][{d|D|e|E}[{+|-}]<digit>*]
 *
 * This function may replace aptanly ...
 */
tsp00_Bool pa04tcIsNumberString ( UCHAR  *string_ptr )
{
    tsp00_Int4 pos = 0;
    tsp00_Int4 state = ST_START;
    tsp00_Int4 numLeftDigits = 0;
    tsp00_Int4 numRightDigits = 0;
    tsp00_Int4 numExpDigits = 0;
    
    API_TRACE(API_TR_ENTRY,"pa04tcIsNumberString", 0);
    do {
        switch (state) {
        case ST_START:
            switch (string_ptr[pos]) {
            case '\0':
                state = ST_SUCCESS; /* empty string is ok */
                break;
            case ' ':
            case '\t': /* skip leading whitespaces */
                pos++;
                break;
            case '+':
            case '-':
                pos++;
                state = ST_LEFTDIGITS;
                break;
            case '.':
                pos++;
                state = ST_RIGHTDIGITS;
                break;
            default:
                if (isdigit(string_ptr[pos])) {
                    state = ST_LEFTDIGITS;
                } else {
                    state = ST_ERROR;
                };
                break;
            }; /* switch */
            break;
        case ST_LEFTDIGITS: /* scan zero or more digits */
            switch (string_ptr[pos]) {
            case '\0':
                state = ST_SUCCESS;
                break;
            case '.':
                pos++;
                state = ST_RIGHTDIGITS;
                break;
            default:
                if (isdigit(string_ptr[pos])) {
                    numLeftDigits++;
                    pos++;
                } else if (numLeftDigits > 0) {
                    state = ST_EXP;
                } else {
                    state = ST_ERROR;
                }; /* else */
            }; /* switch */
            break;
        case ST_RIGHTDIGITS:/* scan one or more digits */
            switch (string_ptr[pos]) {
            case '\0':
                if (numRightDigits>0) {
                    state = ST_SUCCESS;
                } else {
                    state = ST_ERROR;
                };
                break;
            default:
                if (isdigit(string_ptr[pos])) {
                    numRightDigits++;
                    pos++;
                } else if (numRightDigits > 0) {
                    state = ST_EXP;
                } else {
                    state = ST_ERROR;
                }; /* else */
            }; /* switch */
            break;
        case ST_EXP: /* scan optional exponent */
            switch (string_ptr[pos]) {
            case '\0':
                state = ST_SUCCESS;
                break;
            case 'd':
            case 'D':
            case 'e':
            case 'E':
                pos++;
                state = ST_EXPSIGN;
                break;
            default:
                state = ST_ERROR;
                break;
            }; /* switch */
            break;
        case ST_EXPSIGN:
            switch (string_ptr[pos]) {
            case '-':
            case '+':
                pos++;
                break;
            default:
                if (isdigit(string_ptr[pos])) {
                    state = ST_EXPDIGITS;
                } else {
                    state = ST_ERROR;
                };
                break;
            }; /* switch */
            break;
        case ST_EXPDIGITS: /* scan one or more digits */
            switch (string_ptr[pos]) {
            case '\0':
                if (numExpDigits > 0) {
                    state = ST_SUCCESS;
                } else {
                    state = ST_ERROR;
                };
                break;
            default:
                if (isdigit(string_ptr[pos])) {
                    pos++;
                    numExpDigits++;
                } else {
                    state = ST_ERROR;
                };
                break;
            }; /* switch */
            break;
        default:
            API_TRACE( API_TR_SDWORD, "invalid scanner state", &state);
            state = ST_ERROR; /* unknown scanner state */
            break;
        }; /* switch */
    } while (state != ST_SUCCESS && state != ST_ERROR);
    API_TRACE(API_TR_EXIT,"pa04tcIsNumberString", 0);

    return (tsp00_Bool) (state == ST_SUCCESS);
} /* pa04tcIsNumberString */

/* function to check whether the input string is a number */
/*  ---------> !!!! this is not done yet, perhaps function */
/* will be changed so that reponse will be passed back,    */
/* which indicates whether OK or not OK                    */
/* analyze_nr determines the number of digits to the right */
/* and to the left side of the decimal point. The number   */
/* of significant digits will be evaluated depending on the*/
/* number of right digits and the digits before the decimal*/
/* point                                                   */
VOID aptanly ( UCHAR  *string_ptr,
               UWORD  *right_digits_ptr,
               UWORD  *left_digits_ptr,
               UWORD  *sign_digits_ptr,
               UWORD  *sign_indicator_ptr,
               SWORD  *exponent_ptr)
{
    SWORD i, j, k;
    UWORD string_length;
    UCHAR FAR * e_ptr;
    UCHAR exponent[10];
    API_TRACE(API_TR_ENTRY,"aptanly", 0);
    if (string_ptr != NULL) {
        API_TRACE(API_TR_STRING,"*string", string_ptr);
    }
  
    /* drop exponetial part localy */
    if ((e_ptr = (UCHAR*) API_STRCHR(string_ptr, 'e')) == (UCHAR*) NULL)
        e_ptr = (UCHAR*) API_STRCHR(string_ptr, 'E');
    if (e_ptr != NULL) {
        API_STRNCPY(exponent, e_ptr, sizeof(exponent)-1);
        *e_ptr = '\0';
    }     
  
    string_length = (UWORD) API_STRLEN((UCHAR*) string_ptr);
    i = j = k = 0;
    API_TRACE(API_TR_UWORD,"string_length", &string_length);

    if (string_ptr [0]  == '-')  /* set sign indicator    */
        {
            *sign_indicator_ptr = SIGN_NEGATIV;
            i = 1;
            k = 1;
        }
    else
        {
            if (string_ptr [0]  == '+') /* ignore sign indicator */
                i = 1;
            *sign_indicator_ptr = SIGN_POSITIV;
        }
    API_TRACE(API_TR_UWORD,"sign_indicator", sign_indicator_ptr);

    /* delete leading blancs     */
    for (; string_ptr [i]  == ' ' &&
             i < (SWORD)(API_STRLEN(string_ptr) -1); i++);

    /* delete leading zeroes     */
    for (; string_ptr [i]  == '0' &&
             i < (SWORD)(API_STRLEN(string_ptr) -1); i++);

    /* delete appending blancs   */
    for (j = (UWORD) (API_STRLEN(string_ptr) - 1);
         j > 0 && string_ptr [j]  == ' '; j--);
  
    /* delete appending zeroes   */
    /* after decimal point       */
    if (((UCHAR*) API_STRCHR(string_ptr+i, '.')) !=
        (UCHAR*) NULL) {
        for (; string_ptr [j]  == '0' && j > 0; j--);
    }

    for (; i <= j; i++, k++)
        string_ptr [k] = string_ptr [i] ;
  
    if (k > 1 && string_ptr[k-1] == '.')
        k--;
    string_ptr [k]  = '\0';
    API_TRACE(API_TR_STRING,"*string", string_ptr);
  
    if (k == 1 && (string_ptr[0] == '-' || string_ptr[0] == '.')) {
        *sign_indicator_ptr = SIGN_POSITIV;
        string_ptr[0] = '0';
    }
  
    if (k == 2 && string_ptr[0] == '.' && string_ptr[1] == '0') {
        *sign_indicator_ptr = SIGN_POSITIV;
        string_ptr[0] = '0';
        string_ptr[1] = '\0';
    }

    /* set position of dec. point*/
    for (i = 0; string_ptr [i]  != '.' && string_ptr [i]  != '\0'; i++);

    /* get nr of significant dig.*/
    if (*sign_indicator_ptr == SIGN_NEGATIV && i == 1)
        *sign_digits_ptr = (UWORD) (2);
    if (*sign_indicator_ptr == SIGN_POSITIV && i == 1)
        *sign_digits_ptr = (UWORD) (1);
    else
        *sign_digits_ptr = i;

    /* get nr of right digits    */
    *right_digits_ptr = i;

    /* get nr of left digits     */
    if (i != (SWORD)API_STRLEN(string_ptr))
        *left_digits_ptr = (UWORD) (API_STRLEN(string_ptr) - i - 1);
    else
        *left_digits_ptr = 0;
 
    if (e_ptr != NULL) {
        API_STRCAT(string_ptr, exponent);
        apdexp(string_ptr, exponent_ptr);
    }
    else {
        *exponent_ptr = 0;
    }
  
    API_TRACE(API_TR_EXIT,"aptanly", 0);
    API_TRACE(API_TR_STRING,"*string", string_ptr);
    API_TRACE(API_TR_UWORD,"*right_digits", right_digits_ptr);
    API_TRACE(API_TR_UWORD,"*left_digits", left_digits_ptr);
    API_TRACE(API_TR_UWORD,"*sign_digits", sign_digits_ptr);
    API_TRACE(API_TR_UWORD,"*sign_indicator", sign_indicator_ptr);
    API_TRACE(API_TR_SWORD,"*exponent", exponent_ptr);
    return;
} /* aptanly */


/* aptchsl() - check against limit_values for short/long */

#define BIG_MIN "-9223372036854775808"
#define SBIG_MAX "9223372036854775807"
#define UBIG_MAX "18446744073709551615"

/* the following depend on SQL_MAXNUMBER_LEN */
#define NUMERIC_MAX "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /* ? ... */
#define NUMERIC_MIN "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /* ? ... */


API_RETCODE aptchsl( UCHAR *string_ptr, UWORD format)     
{
    UWORD right_digits;
    UWORD left_digits;
    UWORD sign_digits;
    UWORD sign_indicator;
    SWORD exponent;
    UWORD length_limit_value;
    UCHAR limit_value_string [22];
    UCHAR *limit_value_ptr;
    API_RETCODE api_retcode;

    API_TRACE(API_TR_ENTRY,"aptchsl",0);
    API_TRACE(API_TR_PTR,"string_ptr",&string_ptr);
    API_TRACE(API_TR_SWORD, "format", &format);

    limit_value_ptr = (UCHAR*) limit_value_string;

    api_retcode = API_OK;

    /* check string               */
    aptanly( string_ptr,
             (UWORD*) &right_digits,
             (UWORD*) &left_digits,
             (UWORD*) &sign_digits,
             (UWORD*) &sign_indicator,  
             (SWORD*) &exponent);
    if (!pa04tcIsNumberString(string_ptr)) {
        api_retcode = API_NOT_NUMBER;
    } else {
        /* check for limitation        */
        if (string_ptr [0]  == '-') {
            signed long ce_cs; 
            switch ((SWORD)format) {
            case (SQL_C_TINYINT): {}
            case (SQL_C_STINYINT): {
                ce_cs = SCHAR_MIN;
                break;
            }
            case (SQL_C_SHORT): {}
            case (SQL_C_SSHORT): {
                ce_cs = SHRT_MIN;
                break;
            }
            case (SQL_C_LONG): {}
            case (SQL_C_SLONG): {
                ce_cs = SAPDB_MIN_INT4;
                break;
            }
            case (SQL_C_BIT): {}
            case (SQL_C_UTINYINT): {}
            case (SQL_C_USHORT): {}
            case (SQL_C_ULONG): {
                ce_cs = 0;
                break;
            }
            case (SQL_C_UBIGINT): { /* new in 3.0 */
                limit_value_ptr = (UCHAR*) "0";
                break;
            case (SQL_C_SBIGINT): {} /* new in 3.0 */
                limit_value_ptr = (UCHAR*) BIG_MIN;
                break;
            }
            case (SQL_C_NUMERIC): { /* new in 3.0 */
                limit_value_ptr = (UCHAR*) NUMERIC_MIN;
                break;
            }
            case (API_INT4_TYPE) : {
                ce_cs = 1-MAX_INT4_SP00;
            }
            }
            if (((SWORD) format) != SQL_C_SBIGINT
                && ((SWORD) format) != SQL_C_UBIGINT
                && ((SWORD) format) != SQL_C_NUMERIC ) {
                API_SPRINTF( (char*) limit_value_ptr, PRINT_LONG, ce_cs);
            }; /* if */
        }
        else {
            unsigned long ce_cs; 
            switch ((SWORD)format) {
            case (SQL_C_BIT): {
                ce_cs = 1;
                break;
            }
            case (SQL_C_TINYINT): {}
            case (SQL_C_STINYINT): {
                ce_cs = SCHAR_MAX;
                break;
            }
            case (SQL_C_SHORT): {}
            case (SQL_C_SSHORT): {
                ce_cs = SAPDB_MAX_INT2;       /* PTS 1119281 */
                break;
            }
            case (SQL_C_LONG): {}
            case (SQL_C_SLONG): {
                ce_cs = SAPDB_MAX_INT4;
                break;
            }
            case (SQL_C_UTINYINT): {
                ce_cs = UCHAR_MAX;
                break;
            }
            case (SQL_C_USHORT): {
                ce_cs = SAPDB_MAX_UINT2;
                break;
            }
            case (SQL_C_ULONG): {
                ce_cs = SAPDB_MAX_UINT4;
                break;
            }
            /* these three are new in 3.0 */
            case (SQL_C_NUMERIC): {
                limit_value_ptr = (UCHAR*) NUMERIC_MAX;
                break;
            }
            case (SQL_C_SBIGINT): {
                limit_value_ptr = (UCHAR*) SBIG_MAX;
                break;
            }
            case (SQL_C_UBIGINT): {
                limit_value_ptr = (UCHAR*) UBIG_MAX;
                break;
            }
            case (API_INT4_TYPE) : {
                ce_cs = MAX_INT4_SP00;
            }
            }
            if (((SWORD) format) != SQL_C_SBIGINT
                && ((SWORD) format) != SQL_C_UBIGINT
                && ((SWORD) format) != SQL_C_NUMERIC ) {
                API_SPRINTF( (char*) limit_value_ptr, PRINT_ULONG, ce_cs);
            }; /* if */
        }
        API_TRACE(API_TR_STRING, "limit_value", limit_value_ptr);
        length_limit_value = (UWORD) (API_STRLEN(limit_value_ptr));

        if ((right_digits > length_limit_value) ||
            ((right_digits == length_limit_value) &&
             (API_STRCMP(string_ptr, limit_value_ptr) > 0))) {
            api_retcode = API_DATA_LOSS;
        }
        else {
            if (left_digits > 0) {
                api_retcode = API_TRUNCATE;
            }
        }
    }; /* else */
    API_TRACE(API_TR_EXIT,"aptchsl",0);
    API_TRACE(API_TR_API_RETCODE,"retcode",&api_retcode);
    if (string_ptr != NULL) {
        API_TRACE(API_TR_STRING,"string_ptr",string_ptr);
    }

    return(api_retcode);
} /* aptchsl */


/* aptchfd() - check for float/double limit_values */
API_RETCODE aptchfd( UCHAR *string_ptr,
                     SWORD  format)
{
    UWORD right_digits;
    UWORD left_digits;
    UWORD sign_digits;
    UWORD sign_indicator;
    SWORD exponent = 0;
    UWORD max_digits;
    SWORD max_expo;
    SDOUBLE max_value, min_value;
    SDOUBLE local_double;
    SWORD e = 0;
    API_RETCODE api_retcode;

    API_TRACE(API_TR_ENTRY,"aptchfd",0);
    API_TRACE(API_TR_PTR,"string_ptr", &string_ptr);
    API_TRACE(API_TR_SWORD,"format",&format);

    api_retcode = API_OK;

    switch (format) {
    case (SQL_DOUBLE): {}
    case (SQL_FLOAT): {
        max_digits = API_FLOAT_PREC;
        max_expo = API_MAXDOUBLE_EXP;
        max_value = API_MAXDOUBLE;
        min_value = API_MINDOUBLE;	    
        break;
    }
    case (SQL_REAL) : {}
    default: {
        max_digits = API_REAL_PREC;
        max_expo = API_MAXFLOAT_EXP;
        max_value = API_MAXFLOAT;
        min_value = API_MINFLOAT;	    
        break;
    }
    }
    API_TRACE(API_TR_UWORD, "max_expo", &max_expo);
    API_TRACE(API_TR_UWORD, "max_digits", &max_digits);
	 
    aptanly( string_ptr,
             (UWORD*) &right_digits,
             (UWORD*) &left_digits,
             (UWORD*) &sign_digits,
             (UWORD*) &sign_indicator,
             &exponent);
    if (!pa04tcIsNumberString(string_ptr)) {
        api_retcode = API_NOT_NUMBER;
    } else {
        if ((UWORD)(right_digits-sign_indicator) > 1)
            e = (SWORD)((right_digits-sign_indicator) - 1);
        else {
            if ((right_digits-sign_indicator) == 0 && left_digits > 1)
                e = -((SWORD) (left_digits -1));
        }
        API_TRACE(API_TR_SWORD, "e", &e);
        e = (exponent > 0) ? exponent + e : -(exponent + e);
        API_TRACE(API_TR_SWORD, "e", &e);
        if (e > (SWORD)max_expo) { 
            api_retcode = API_DATA_LOSS;
        }
        else {
            if ((UWORD)(right_digits + left_digits) > max_digits) {
                api_retcode = API_TRUNCATE;
            }
            if (e == max_expo) {
                API_TRACE(API_TR_STRING,"string_ptr", string_ptr);
                local_double = atof( (char*) string_ptr);
                if (errno == ERANGE) {
                    errno = 0;
                    api_retcode = API_DATA_LOSS;
                }
                else {
                    API_TRACE(API_TR_SDOUBLE, "double", &local_double);
                    local_double = (local_double > 0.0)
                        ? local_double : -local_double;
                    if (exponent > 0) {	
                        if (local_double > max_value)
                            api_retcode = API_DATA_LOSS;
                    }
                    else {
                        if (local_double < min_value)
                            api_retcode = API_DATA_LOSS;	       
                    }
                }
            }      
        }
    }; /* else */
    API_TRACE(API_TR_EXIT,"aptchfd",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);
    API_TRACE(API_TR_STRING,"*string_ptr",string_ptr);

    return(api_retcode);
} /* aptchfd */


/* aptbinary() - convert C to SQL: Binary */
API_RETCODE aptbinary(UCHAR  *in_ptr,
                      UDWORD  in_length,
                      SWORD   in_format,
                      UCHAR  *out_ptr,
                      UDWORD  out_length,
                      UWORD   out_scale,
                      SWORD   out_format, 
                      UDWORD *used)
{
    API_RETCODE api_retcode;
    UDWORD len;
    const tsp77encoding *out_encoding;
    UCHAR *ptr;

    API_TRACE(API_TR_ENTRY, "aptbinary", 0);
    API_TRACE(API_TR_PTR, "in_ptr", &in_ptr);
    API_TRACE_BUF(in_ptr, 1, ((in_length > 40) ? 40 : in_length));
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE(API_TR_SWORD, "in_format", &in_format);
    API_TRACE(API_TR_PTR, "out_ptr", &out_ptr);
    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE(API_TR_UWORD, "out_scale", &out_scale);
    API_TRACE(API_TR_SWORD, "out_format", &out_format);  
    API_TRACE(API_TR_PTR, "used", &used);  

    api_retcode = API_OK;
   
    switch (out_format) {
    case (SQL_CHAR): {}
    case (SQL_UNICODE): {}
    case (SQL_VARCHAR): {}
    case (SQL_UNICODE_VARCHAR): {}
    case (SQL_LONGVARCHAR): {}
    case (SQL_UNICODE_LONGVARCHAR): {
#ifdef BINARY	 
        if (in_length * 2 > out_length-1) {
            len = (out_length-1) / 2;
            api_retcode = API_TRUNCATE;
        }
        else 
            len = in_length;
#else
        if (in_length > out_length-1) {
            len = (out_length-1);
            api_retcode = API_TRUNCATE;
        }
        else 
            len = in_length;
#endif	 
#ifdef BINARY      
        s40gbyte ( in_ptr, 1, (int)len, out_ptr, 1, (int)out_length, (char *)&trunc);
        API_TRACE(API_TR_SWORD, "trunc", &trunc);
        if (trunc) {
            api_retcode = API_TRUNCATE;
        }
        *used = len*2;
#else	 
        *used = len;

        /* if Unicode, the number of bytes must be even
           http://pts:1080/webpts?wptsdetail=yes&ErrorType=0&ErrorID=1126177 */
        if (out_format == SQL_WCHAR  &&  *used & 1) {
          api_retcode = API_TRUNCATE_22001;
          break;
        }

        API_MEMCPY(out_ptr, in_ptr, (int)*used);
#endif

        out_encoding = pa04gGetEncodingType (out_format);
        ptr = out_ptr + *used;

        if (out_format == SQL_CHAR || out_format == SQL_WCHAR) {
            unsigned int length;

            length = out_length - *used - out_encoding->terminatorSize;
            *used = out_length;
            out_encoding->fillString ((void**) &ptr, &length, length, ' ');
        }

        API_MEMSET (ptr, 0, out_encoding->terminatorSize);
        break;
    }
    case (SQL_BINARY): {}
    case (SQL_VARBINARY): {}
    case (SQL_LONGVARBINARY): {}
    case (SQL_BIT): {
        if (in_length > out_length-1) {
            len = out_length;
            api_retcode = API_TRUNCATE;
        }
        else 
            len = in_length;
        *used = len;
        API_MEMCPY(out_ptr, in_ptr, (int)*used);
        break;
    }
    case (SQL_SMALLINT): {
        *used = sizeof (SWORD);
        API_MEMCPY(out_ptr, in_ptr, (int)*used);
        break;
    }
    case (SQL_INTEGER): {
        *used = sizeof (SDWORD);
        API_MEMCPY(out_ptr, in_ptr, (int)*used);
        break;
    }
    case (SQL_REAL): {
        *used = sizeof (SFLOAT);
        API_MEMCPY(out_ptr, in_ptr, (int)*used);
        break;
    }
    case (SQL_FLOAT): {}
    case (SQL_DOUBLE): {
        *used = sizeof (SDOUBLE);
        API_MEMCPY(out_ptr, in_ptr, (int)*used);
        break;
    }
    case (SQL_NUMERIC): {}
    case (SQL_DECIMAL): {   
        api_retcode = aptchst(in_ptr);
        if (api_retcode == API_OK) {
            *used = in_length;
            API_MEMCPY(out_ptr, in_ptr, (int)*used);
        }
        break;
    }
    case (SQL_TYPE_DATE):
    case (SQL_DATE): {
        api_retcode = apgchdt(in_ptr);
        if (api_retcode == API_OK) {
            *used = API_DATE_PREC;
            API_MEMCPY(out_ptr, in_ptr, (int)*used);
        }
        break;
    }
    case (SQL_TYPE_TIME): {
        api_retcode = apgchtm(in_ptr);
        if (api_retcode == API_OK) {
            *used = API_TIME_PREC;
            API_MEMCPY(out_ptr, in_ptr, (int)*used);
        }
        break;
    }
    case (SQL_TYPE_TIMESTAMP): {
        api_retcode = apgchts(in_ptr);
        if (api_retcode == API_OK) {
            *used = API_TIMESTAMP_EXT_PREC;
            API_MEMCPY(out_ptr, in_ptr, (int)*used);
        }
        break;
    }
    default: {
        API_TRACE(API_TR_SWORD, "format not supported", &out_format);
        api_retcode = API_NOT_OK;	 
        break;
    }
    }
    API_TRACE(API_TR_UDWORD, "*used", used);
    API_TRACE_BUF(out_ptr, 1, ((*used > 40) ? 40 : *used));
    API_TRACE(API_TR_EXIT,"aptbinary",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* aptbinary */


/* aptchar() - convert C to SQL: Character */
API_RETCODE aptchar(UCHAR  *in_ptr,
                    UDWORD  in_length,
                    SWORD   in_format,
                    UCHAR  *out_ptr,
                    UDWORD  out_length,
                    UWORD   out_scale,
                    SWORD   out_format,
                    UDWORD *used)
{
    API_RETCODE api_retcode;

    API_TRACE(API_TR_ENTRY, "aptchar", 0);
    API_TRACE(API_TR_PTR, "&in_ptr", &in_ptr);
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE(API_TR_SWORD, "in_format", &in_format);
    API_TRACE(API_TR_PTR, "&out_ptr", &out_ptr);
    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE(API_TR_SWORD, "out_format", &out_format);  
    API_TRACE(API_TR_PTR, "&used", &used);  

    api_retcode = API_OK;

    if (in_format == SQL_C_WCHAR) {
      in_length  = (in_length & 1)  ? in_length-1  : in_length;

      switch (out_format) {
      case (SQL_WCHAR): {}
      case (SQL_WVARCHAR): {}
      case (SQL_WLONGVARCHAR): {
        UCHAR * ptr;
        unsigned int length;

        out_length = (out_length & 1) ? out_length-1 : out_length;
        if (in_length < out_length)  
            {
                if (out_format == SQL_WCHAR) {
                    API_MEMCPY(out_ptr, in_ptr, (int) in_length);
                    if (out_length > sizeof(tsp81_UCS2Char)) {
                      ptr = out_ptr+in_length;
                      length = out_length - in_length - sizeof(tsp81_UCS2Char);
                      sp77encodingUCS2Native->fillString ((void**) &ptr, &length, length, ' ');
                      length = sizeof (tsp81_UCS2Char);
                      sp77encodingUCS2Native->fillString ((void**) &ptr, &length, length, '\0');
                    }
                    else {
                      ptr = out_ptr;
                      length = sizeof (tsp81_UCS2Char);
                      sp77encodingUCS2Native->fillString ((void**) &ptr, &length, length, '\0');
                    }
                    *used = out_length;
                }
                else {   /* WVARCHAR */
                    /* remove trailing blanks */
                    UDWORD len = in_length;

                    ptr = in_ptr;

                    if (out_format == SQL_WVARCHAR) {
                      len = sp77encodingUCS2Native->countPadChars (in_ptr, in_length, ' ');
                      len = in_length - len*sizeof (tsp81_UCS2Char);
                    }
                    API_MEMCPY(out_ptr, in_ptr, (int)len);
                    if (out_format == SQL_WVARCHAR) {
                      ptr = out_ptr+len;
                      length = sizeof (tsp81_UCS2Char);
                      sp77encodingUCS2Native->fillString ((void**) &ptr, &length, length, '\0');
                    }
                    *used = len;
                }
            }
        else {     /* in_length >= out_length  */
            /* ADIS 1001692
             * pa20AllocLong allocates extra space for the null terminator (sizeof(tsp81_UCS2Char))
             * so -1 is not necessary.
             * used should be length exclusive null terminator */
          ptr = in_ptr + out_length;
          length = sp77encodingUCS2Native->countPadChars (ptr, in_length-out_length, ' ');
          length *= sizeof (tsp81_UCS2Char);

          if ( ((tsp81_UCS2Char*)(ptr+length))->s != 0 )      /* terminated? */
            api_retcode = API_TRUNCATE;	 

          API_MEMCPY(out_ptr, in_ptr, (int) out_length);
          length = sizeof (tsp81_UCS2Char);
          ptr = out_ptr + out_length;                         /* PTS 1119132 */
          sp77encodingUCS2Native->fillString ((void**) &ptr, &length, length, '\0');
          *used = out_length;
        }
        goto exit;     /* skip following case block (only for SQL_C_CHAR) */
      }


      case (SQL_CHAR): {}
      case (SQL_VARCHAR): {}
      case (SQL_LONGVARCHAR): {

        tsp00_Uint4   cbWrite;        /* number of bytes written */
        tsp00_Uint4   cbParsed;       /* number of bytes parsed */
        tsp78ConversionResult convRes;

        convRes = sp78convertBuffer(sp77encodingAscii, out_ptr, out_length,
                                    &cbWrite,
                                    sp77encodingUCS2Native, in_ptr, in_length,
                                    &cbParsed);
        *used = (UDWORD) cbWrite;
        switch (convRes) {
        case sp78_TargetExhausted:   api_retcode = API_TRUNCATE;  break;
        case sp78_Ok:                api_retcode = API_OK;        break;
        default:                     api_retcode = API_NOT_OK;    break;
        }

        if (api_retcode != API_NOT_OK)
          /* append terminator */
          API_MEMCPY (((CHAR*)out_ptr)+*used,
                      sp77encodingUCS2Native->charTable->terminator.bytes,
                      sp77encodingUCS2Native->charTable->terminator.byteCount);
        
        goto exit;     /* skip following case block (only for SQL_C_CHAR) */
      }

      case (SQL_BINARY): {}
      case (SQL_VARBINARY): {}
      case (SQL_LONGVARBINARY): {
        break;
      }
      case (SQL_BIT): {}

      case (SQL_SMALLINT): {}
      case (SQL_INTEGER): {}
      case (SQL_REAL): {}
      case (SQL_FLOAT): {}
      case (SQL_DOUBLE): {
        /* recursive */
        break;
      }
    case (SQL_TYPE_TIME): {}
    case (SQL_TYPE_DATE): {}
    case (SQL_TYPE_TIMESTAMP): {}
    case (SQL_TIME): {}
    case (SQL_DATE): {}
    case (SQL_TIMESTAMP): {
        aptbinary (in_ptr, in_length, in_format, 
                   out_ptr, out_length, out_scale, out_format, used);
        break;
    }

    case (SQL_DECIMAL): {}
    case (SQL_NUMERIC): {
        api_retcode = aptnm2chw( in_ptr,
                                in_format,
                                out_ptr,
                                out_length,
                                out_scale,
                                out_format,
                                used);
        break;
    }
    default: {	 
        api_retcode = API_NOT_OK;
        break;
    }
      }
    }




   
    if (in_length == SQL_NTS) {
        in_length = (SQLUINTEGER) API_STRLEN(in_ptr);
    }
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE_LEN(API_TR_ODBC_STRING, "in_ptr", in_ptr, in_length);
    switch (out_format) {
    case (SQL_CHAR): {}
    case (SQL_VARCHAR): {}
    case (SQL_LONGVARCHAR): {
        UCHAR FAR * ptr;
        if (in_length < out_length)  
            {
				/* PTS: 1107628 - Unicode (MaO)*/
                if (out_format == SQL_CHAR || out_format == SQL_UNICODE_CHAR) {
                    API_MEMCPY(out_ptr, in_ptr, (int) in_length);
                    if (out_length > 1) {
                        API_MEMSET(out_ptr+in_length, ' ', (int) (out_length -1 - in_length));
                        *(out_ptr+out_length-1) = 0;
                    }
                    else
                        *(out_ptr) = 0;
                    *used = out_length;
                }
                else {
                    /* remove trailing blanks */
                    UDWORD len;
                    len = in_length;
					/* PTS: 1107628 - Unicode (MaO)*/
                    if (out_format == SQL_VARCHAR || out_format == SQL_UNICODE_VARCHAR) {
                        ptr = in_ptr + len -1;	    
                        while (len > 0 && *(ptr) == ' ') {
                            ptr--;
                            len--;
                        }
                    }
                    API_MEMCPY(out_ptr, in_ptr, (int)len);
					/* PTS: 1107628 - Unicode (MaO)*/
                    if (out_format != SQL_VARCHAR && out_format != SQL_UNICODE_VARCHAR) {
                        *used = len;
                    }
                    else {
                        *(out_ptr+len) = 0;
                        *used = len /* +1 */; /* ADIS 1001692 */
                    }
                }
            }
        else {
            /* ADIS 1001692
             * pa20AllocLong allocates extra space for the null terminator
             * so -1 is not necessary.
             * used should be length exclusive null terminator */
            ptr = in_ptr + out_length /* -1 */ ;
            while (*ptr == ' ')
                ptr++;
            if (*ptr != '\0')
                api_retcode = API_TRUNCATE;	 
            API_MEMCPY(out_ptr, in_ptr, (int) (out_length /* -1 */ ));
            *(out_ptr+out_length /* -1 */ ) = 0;
            *used = out_length;
        }
        break;
    }
    case (SQL_UNICODE_CHAR): {}
    case (SQL_UNICODE_VARCHAR): {}
    case (SQL_UNICODE_LONGVARCHAR): {
        UCHAR FAR * ptr;
        const tsp77encoding *in_encoding;
        const tsp77encoding *out_encoding;
        tsp78ConversionResult rc;
        tsp00_Uint4 destBytesWritten, srcBytesParsed;

        in_encoding = pa04gGetEncodingType(in_format);
        out_encoding = pa04gGetEncodingType(out_format);

        if (in_length < out_length)  
            {
            rc = sp78convertBuffer(out_encoding, out_ptr, out_length,
                                   &destBytesWritten,
                                   in_encoding, in_ptr, in_length,
                                   &srcBytesParsed);
            if (rc == sp78_TargetExhausted)         /* PTS 1119132 */
                api_retcode = API_TRUNCATE;	 

            *used = (UDWORD) destBytesWritten;
            /* add terminator for WCHAR and WVARCHAR */
            if (out_format != SQL_WLONGVARCHAR)
                API_MEMSET (out_ptr+destBytesWritten, 0, out_encoding->terminatorSize);
            }
        else {
            /* ADIS 1001692
             * pa20AllocLong allocates extra space for the null terminator
             * so -1 is not necessary.
             * used should be length exclusive null terminator 
            ptr = in_ptr + out_length / -1 / ;
            while (*ptr == ' ')
                ptr++;
            if (*ptr != '\0')
                api_retcode = API_TRUNCATE;	 
            API_MEMCPY(out_ptr, in_ptr, (int) (out_length / -1 / ));
            *(out_ptr+out_length / -1 / ) = 0;
            *used = out_length; */

            ptr = in_ptr + out_length /* -1 */ ;
            while (API_MEMCMP (ptr, in_encoding->charTable->blank.bytes,
                               in_encoding->charTable->blank.byteCount) == 0)
                ptr += in_encoding->fixedCharacterSize;
            if (API_MEMCMP (ptr, in_encoding->charTable->terminator.bytes,
                            in_encoding->charTable->terminator.byteCount) != 0)
                api_retcode = API_TRUNCATE;	 

            rc = sp78convertBuffer(out_encoding, out_ptr, out_length,
                                   &destBytesWritten,
                                   in_encoding, in_ptr, out_length,
                                   &srcBytesParsed);
            *used = (UDWORD) destBytesWritten;
            API_MEMSET (out_ptr+destBytesWritten, 0, out_encoding->terminatorSize);
        }
        break;
    }
    case (SQL_BINARY): {}
    case (SQL_VARBINARY): {}
    case (SQL_LONGVARBINARY): {
        SWORD invalid = 0;
        UDWORD len_in;

        switch (in_format) {
        case SQL_CHAR: {
          int localLen;              /* PTS 1113731 */

          if (in_length/2 <= out_length)  
              len_in  = in_length;
          else {
            len_in  = out_length / 2;     /* out_length * 2;! */
            api_retcode = API_TRUNCATE;
          }
          s41pbyte ( (char*) out_ptr, 1, &localLen, (char*) in_ptr, 1,
                     (int)len_in, (char *)&invalid );
          out_length = localLen;

          API_TRACE(API_TR_UDWORD, "out_length", &out_length);
          API_TRACE_BUF(out_ptr, 1, out_length);
          API_TRACE(API_TR_SWORD, "invalid", &invalid);

          if (invalid)
            api_retcode = API_NOT_NUMBER;
          else 
            *used = out_length;
          break;
        }
        case SQL_WCHAR: {
          char *buffer;
          int  bufLen;

          if (in_length/(2*sizeof(tsp81_UCS2Char)) <= out_length)  
              len_in  = in_length;
          else {
            len_in  = out_length * (2*sizeof(tsp81_UCS2Char));
            api_retcode = API_TRUNCATE;
          }

          /* convert to CHAR */
          bufLen = len_in;
          buffer = apdallo (bufLen);
          if (buffer != NULL) {
              tsp00_Uint4   cbWrite;        /* number of bytes written */
              tsp00_Uint4   cbParsed;       /* number of bytes parsed */
              tsp78ConversionResult rc;
              int localLen;              /* PTS 1113731 */

              rc = sp78convertBuffer(sp77encodingAscii, buffer, bufLen,
                                     &cbWrite,
                                     sp77encodingUCS2Native, in_ptr, in_length,
                                     &cbParsed);
              bufLen = cbWrite;
              s41pbyte ( (char*) out_ptr, 1, &localLen, (char*) buffer, 1,
                         (int)bufLen, (char *)&invalid );
              out_length = localLen;

              API_TRACE(API_TR_UDWORD, "out_length", &out_length);
              API_TRACE_BUF(out_ptr, 1, out_length);
              API_TRACE(API_TR_SWORD, "invalid", &invalid);

              if (invalid)
                api_retcode = API_NOT_NUMBER;
              else
                *used = out_length;

              apdfree (buffer);
          }
          break;
        }
        default: {
          api_retcode = API_NOT_OK;
          break;
        }
    }
        break;
    }
    case (SQL_BIT): {
        SWORD local;
        api_retcode = aptchsl(in_ptr, out_format);
        if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
            local = (SWORD) atoi((char*) in_ptr);
            if (errno == ERANGE) {
                errno = 0;
                api_retcode = API_DATA_LOSS;
            }
            else {
                if (local != 0)
                    *out_ptr = 1;
                else 
                    *out_ptr = 0;
            }
        }	
        break;
    }
    case (SQL_SMALLINT): {
        SWORD local;
        api_retcode = aptchsl(in_ptr, out_format);
        if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
            local = (SWORD) atoi( (char*) in_ptr);
            API_MEMCPY(out_ptr, (UCHAR*) &local, sizeof(local));
        }	
        break;
    }
    case (SQL_INTEGER): {
        tsp00_Int4 local;
        api_retcode = aptchsl(in_ptr, API_INT4_TYPE );
        if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
            local = atol( (char*) in_ptr );
            API_MEMCPY(out_ptr, (UCHAR*) &local, sizeof(local));
        }	
        break;
    }
    case (SQL_REAL): {
        SFLOAT local;
        api_retcode = aptchfd(in_ptr, out_format);
        if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
            SDOUBLE local_double;
            local_double = atof( (char*) in_ptr);
            if (local_double > FLT_MAX || local_double < FLT_MIN) {
                api_retcode = API_DATA_LOSS;
            } else {
                local = (SFLOAT) local_double;
                API_MEMCPY( out_ptr, (UCHAR*) &local, sizeof(local));
            }; /* else */
        }	
        break;
    }      
    case (SQL_FLOAT): {}
    case (SQL_DOUBLE): {
        SDOUBLE local;
        api_retcode = aptchfd(in_ptr, out_format);
        if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
            local = atof( (char*) in_ptr);
            API_MEMCPY( out_ptr, (UCHAR*) &local, sizeof(local));
        }	
        break;
    }
    case (SQL_TYPE_TIME): {}
    case (SQL_TYPE_DATE): {}
    case (SQL_TYPE_TIMESTAMP): {}
    case (SQL_TIME): {}
    case (SQL_DATE): {}
    case (SQL_TIMESTAMP): {
        aptbinary (in_ptr, in_length, in_format, 
                   out_ptr, out_length, out_scale, out_format, used);
        break;
    }
    case (SQL_DECIMAL): {}
    case (SQL_NUMERIC): {
        api_retcode = aptnm2ch( in_ptr,
                                in_format,
                                out_ptr,
                                out_length,
                                out_scale,
                                out_format,
                                used);
        break;
    }
    default: {	 
        api_retcode = API_NOT_OK;
        break;
    }	 
    }

 exit:
    API_TRACE(API_TR_UDWORD, "*used", used);
    API_TRACE_BUF(out_ptr, 1, ((*used > 40) ? 40 : *used));
    API_TRACE(API_TR_EXIT,"aptchar",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* aptchar */


/* aptnumeric() - convert C to SQL: Numeric */
API_RETCODE aptnumeric(UCHAR   *in_ptr,
                       UDWORD   in_length,
                       UWORD    in_scale,
                       SWORD    in_format,
                       UCHAR   *out_ptr,
                       UDWORD   out_length,
                       UWORD    out_scale,
                       SWORD    out_format,
                       UDWORD  *used)
{
    API_RETCODE api_retcode;
    UCHAR local_string [API_CHAR_LENGTH_CHAR]; 
    BOOL csigned;

    API_TRACE(API_TR_ENTRY, "aptnumeric", 0);
    API_TRACE(API_TR_PTR, "in_ptr", &in_ptr);
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE(API_TR_UWORD, "in_scale", &in_scale);
    API_TRACE(API_TR_SWORD, "in_format", &in_format);
    API_TRACE(API_TR_PTR, "out_ptr", &out_ptr);
    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE(API_TR_UWORD, "out_scale", &out_scale);
    API_TRACE(API_TR_SWORD, "out_format", &out_format);  
    API_TRACE(API_TR_PTR, "used", &used);  

    api_retcode = API_OK;
    switch (in_format) {
    case (SQL_C_WCHAR): {
      UCHAR *inPtr;
      UCHAR localString[sizeof(tsp81_UCS2Char) * (API_CHAR_LENGTH_CHAR+1)];
      int  allocFlag = 0;
      tsp78ConversionResult convRes;
      tsp00_Uint4 destBytesWritten, srcBytesParsed;

      if (in_length >= sizeof (localString)) {
        allocFlag = 1;
        inPtr = apdallo (in_length);
        if (inPtr == NULL) {
          api_retcode = API_NOT_OK;
        }
      }
      else
        inPtr = localString;

      if (api_retcode == API_OK) {
        convRes = sp78convertString (sp77encodingAscii, 
                                     inPtr, in_length,
                                     &destBytesWritten,
                                     TRUE,
                                     sp77encodingUCS2Native,
                                     in_ptr, in_length,
                                     &srcBytesParsed);
        in_length = destBytesWritten;
        if (convRes != sp78_Ok)
          api_retcode = API_NOT_OK;
        else
          api_retcode = aptnumeric (inPtr,   in_length,  in_scale, SQL_C_CHAR,
                                    out_ptr, out_length, out_scale, out_format, used);
      }
      if (allocFlag != 0)
        apdfree (inPtr);
      break;
    }
    case (SQL_C_CHAR): {                /* ODBC book ,pg 488 */
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_SMALLINT): {
            SWORD local;
            api_retcode = aptchsl(in_ptr, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local = (SWORD) atoi( (char*) in_ptr);
                if (errno == ERANGE) {
                    errno = 0;
                    api_retcode = API_DATA_LOSS;
                }
                else {
                    API_MEMCPY(out_ptr, (UCHAR*) &local, sizeof(local));		     
                    API_TRACE(API_TR_SWORD, "SMALLINT", out_ptr);  
                }
            }	
            break;
	    }
	    case (SQL_INTEGER): {
            tsp00_Int4 local;
            api_retcode = aptchsl(in_ptr, API_INT4_TYPE );
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local = atol( (char*) in_ptr);
                if (errno == ERANGE) {
                    errno = 0;
                    api_retcode = API_DATA_LOSS;
                }
                else {
                    API_MEMCPY(out_ptr, (UCHAR*) &local, sizeof(local));
                    API_TRACE(API_TR_SDWORD, "INTEGER", out_ptr);  
                }
            }	
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float=(SFLOAT) 0.0;
            api_retcode = aptchfd(in_ptr, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local_float = (SFLOAT) atof( (char*) in_ptr);
                API_TRACE(API_TR_SFLOAT, "float", &local_float);
                API_MEMCPY(out_ptr, (UCHAR*) &local_float,
                           sizeof(SFLOAT));
                API_TRACE(API_TR_SFLOAT, "REAL", out_ptr);  
            }	
            break;
	    }      
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            api_retcode = aptchfd(in_ptr, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local_double = atof( (char*) in_ptr);
                API_TRACE(API_TR_SDOUBLE, "double", &local_double);
                API_MEMCPY(out_ptr, (UCHAR*) &local_double,
                           sizeof(SDOUBLE));
                API_TRACE(API_TR_SDOUBLE, "DOUBLE", out_ptr);  
            }	
            break;
	    }
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {}
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {
            api_retcode = aptnm2ch( in_ptr,
                                    in_format,
                                    out_ptr,
                                    out_length,
                                    out_scale,
                                    out_format,
                                    used);
            break;
            }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            api_retcode = aptnm2chw(in_ptr,
                                    in_format,
                                    out_ptr,
                                    out_length,
                                    out_scale,
                                    out_format,
                                    used);
            break;
	    }
	    case (SQL_BIT): {
            SWORD local;
            api_retcode = aptchsl(in_ptr, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local = (SWORD) atoi( (char*) in_ptr);
                if (errno == ERANGE) {
                    errno = 0;
                    api_retcode = API_DATA_LOSS;
                }
                else {
                    if (local != 0)
                        *out_ptr = 1;
                    else 
                        *out_ptr = 0;
                }
            }	
            break;
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {	 
            api_retcode = API_NOT_OK;
            break;
	    }	 
        } /* inner switch */
        break;
    }   /* inner definition area */
    case (SQL_C_SSHORT): {}
    case (SQL_C_USHORT): {}
    case (SQL_C_SHORT): {                
        SWORD local_short;
        UWORD local_ushort;	 
        if (in_format == SQL_C_USHORT) {
            csigned = FALSE;
            API_MEMCPY((UCHAR*) &local_ushort, in_ptr, sizeof(SWORD));
            API_TRACE(API_TR_UWORD, "USHORT", &local_ushort);  
            API_SPRINTF( (char*) local_string, PRINT_USHORT, local_ushort);
        }
        else {
            csigned = TRUE;
            API_MEMCPY((UCHAR*) &local_short, in_ptr, sizeof(SWORD));
            API_TRACE(API_TR_SWORD, "SHORT", &local_short);  
            API_SPRINTF( (char*) local_string, PRINT_SHORT, local_short);
        }
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {}
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {	       
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch( local_string,
                                    in_format,
                                    out_ptr,
                                    out_length,
                                    out_scale,
                                    out_format,
                                    used);
            break;
	    }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw(local_string,
                                    in_format,
                                    out_ptr,
                                    out_length,
                                    out_scale,
                                    out_format,
                                    used);
            break;
	    }
	    case (SQL_BIT): {
            if (csigned)
                *out_ptr = (UCHAR) (local_short ? 1 : 0);
            else
                *out_ptr = (UCHAR) (local_ushort ? 1 : 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            if (!csigned && local_ushort > SHRT_MAX) {
                /* Numeric value out of range */
                api_retcode = API_DATA_LOSS;
            } else {
                API_MEMCPY( out_ptr, in_ptr, sizeof(SWORD));
                *used = sizeof(SWORD);
                API_TRACE(API_TR_SWORD, "short", out_ptr);
            }; /* else */
            break;
	    }
	    case (SQL_INTEGER): {
            SDWORD local_long;
            if (csigned)
                local_long = local_short;
            else
                local_long = local_ushort;
            API_MEMCPY(out_ptr, (UCHAR*) &local_long, sizeof(local_long));
            *used = sizeof(local_long);
            API_TRACE(API_TR_SDWORD, "long", &local_long);
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float;
            if (csigned)
                local_float = local_short;
            else
                local_float = local_ushort;
            API_MEMCPY(out_ptr, (UCHAR*) &local_float, sizeof(local_float));
            *used = sizeof(local_float);
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            if (csigned)
                local_double = local_short;
            else 
                local_double = local_ushort;
            API_MEMCPY(out_ptr, (UCHAR*) &local_double, sizeof(local_double));
            *used = sizeof(local_double);
            API_TRACE_BUF(out_ptr, 1, 8);
            break;
	    }	
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        }  /* inner switch */
        break;
    }   
    case (SQL_C_SLONG): {}
    case (SQL_C_ULONG): {}
    case (SQL_C_LONG): {                 
        SDWORD local_long;	 
        UDWORD local_ulong;	 
        if (in_format == SQL_C_ULONG) {
            csigned = FALSE;
            API_MEMCPY((UCHAR*) &local_ulong, in_ptr, sizeof(SDWORD));
            API_TRACE(API_TR_UDWORD, "ULONG", &local_ulong);  
            API_SPRINTF( (char*) local_string, PRINT_ULONG, local_ulong);
        }
        else {
            csigned = TRUE;
            API_MEMCPY((UCHAR*) &local_long, in_ptr, sizeof(SDWORD));
            API_TRACE(API_TR_SDWORD, "LONG", &local_long);  
            API_SPRINTF( (char*) local_string, PRINT_LONG, local_long);
        }
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {}
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw (local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_BIT): {
            if (csigned)
                *out_ptr = (UCHAR) (local_long ? 1 : 0);
            else
                *out_ptr = (UCHAR) (local_ulong ? 1 : 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            SWORD local_short;
            api_retcode = aptchsl(local_string, out_format);
            if (api_retcode == API_OK) {
                if (csigned)
                    local_short = (SWORD)local_long;
                else
                    local_short = (SWORD)local_ulong;
                API_MEMCPY(out_ptr, (UCHAR*) &local_short, sizeof(SWORD));
                *used = sizeof(local_short);
            }
            break;
	    }
	    case (SQL_INTEGER): {
            API_MEMCPY(out_ptr, in_ptr, sizeof(SDWORD));
            *used = sizeof(SDWORD);
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                if (csigned)
                    local_float = (SFLOAT)local_long;
                else
                    local_float = (SFLOAT)local_ulong;
                API_MEMCPY(out_ptr, (UCHAR*) &local_float, sizeof(SFLOAT));
                *used = sizeof(local_float);
            }
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                if (csigned)
                    local_double = local_long;
                else
                    local_double = local_ulong;
                API_MEMCPY(out_ptr, (UCHAR*) &local_double, sizeof(SDOUBLE));
                *used = sizeof(local_double);
                break;
            }
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        } /* inner switch */
        break;
    } /* inner definition area */

    case (SQL_C_STINYINT): {}
    case (SQL_C_UTINYINT): {}
    case (SQL_C_TINYINT): {}
    case (SQL_C_BIT): {                 
        SCHAR local_char;	 
        UCHAR local_uchar;
        if (in_format == SQL_C_UTINYINT) {
            csigned = FALSE;
            API_MEMCPY((UCHAR*) &local_uchar, in_ptr, sizeof(SCHAR));
            API_TRACE(API_TR_UCHAR, "UCHAR", &local_uchar);  
            API_SPRINTF( (char*) local_string, PRINT_USHORT,
                         (UWORD) local_uchar);
        }
        else {
            csigned = TRUE;
            API_MEMCPY((UCHAR*) &local_char, in_ptr, sizeof(SCHAR));
            API_TRACE(API_TR_SCHAR, "SCHAR", &local_char);  
            API_SPRINTF( (char*) local_string, PRINT_SHORT, (SWORD) local_char);
        }
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {}
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw (local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_BIT): {
            if (csigned)
                *out_ptr = (UCHAR) (local_char ? 1 : 0);
            else
                *out_ptr = (UCHAR) (local_uchar ? 1 : 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            SWORD local_short;
            if (csigned)
                local_short = local_char;
            else
                local_short = local_uchar;
            API_MEMCPY(out_ptr, (UCHAR*) &local_short, sizeof(SWORD));
            *used = sizeof(local_short);
            break;
	    }
	    case (SQL_INTEGER): {
            SDWORD local_long;
            if (csigned)
                local_long = local_char;
            else
                local_long = local_uchar;
            API_MEMCPY(out_ptr, (UCHAR*) &local_long, sizeof(SDWORD));
            *used = sizeof(local_long);
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                if (csigned)
                    local_float = local_char;
                else 
                    local_float = local_uchar;
                API_MEMCPY(out_ptr, (UCHAR*) &local_float, sizeof(SFLOAT));
                *used = sizeof(local_float);
            }
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                if (csigned)
                    local_double = local_char;
                else 
                    local_double = local_uchar;
                API_MEMCPY(out_ptr, (UCHAR*) &local_double, sizeof(SDOUBLE));
                *used = sizeof(local_double);
                break;
            }
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        } /* inner switch */
        break;
    } /* inner definition area */
    case (SQL_C_NUMERIC): {     /* new in 3.0 */
        SQL_NUMERIC_STRUCT local_numeric;
        API_MEMCPY( (UCHAR*) &local_numeric,
                    in_ptr,
                    sizeof(SQL_NUMERIC_STRUCT));
        pa05Numeric2String( &local_numeric, in_scale,
                            local_string,
                            sizeof( local_string ));
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
            case (SQL_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     MAX_NUMERIC_DIGITS_PA05+2,
                                     out_format,
                                     used);
            break;
            }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
            case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw (local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     MAX_NUMERIC_DIGITS_PA05+2,
                                     out_format,
                                     used);
            break;
            }
	    case (SQL_DECIMAL): {}
            case (SQL_NUMERIC): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
            }
	    case (SQL_BIT): {
            *out_ptr = (UCHAR) (pa04t_NumericNotNull( &local_numeric ) ?
                                1 : 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            SWORD local_short;
            api_retcode = aptchsl( local_string, out_format );
            if (api_retcode == API_OK) {
                API_MEMCPY( &local_short,
                            (UCHAR*) local_numeric.val,
                            sizeof(SWORD));
                if (local_numeric.sign == NUMERIC_NEGATIVE_SIGN) {
                    local_short = -local_short;
                }; /* if */
                API_MEMCPY( out_ptr,
                            (UCHAR*) &local_short,
                            sizeof(SWORD));
                *used = sizeof(SWORD);
            }
            break;
	    }
	    case (SQL_INTEGER): {
            tsp00_Int4 local_int4;
            api_retcode = aptchsl( local_string, API_INT4_TYPE );
            if (api_retcode == API_OK) {
                API_MEMCPY( &local_int4,
                            (UCHAR*) local_numeric.val,
                            sizeof(local_int4));
                if (local_numeric.sign == NUMERIC_NEGATIVE_SIGN) {
                    local_int4 = -local_int4;
                }; /* if */                
                API_MEMCPY( out_ptr,
                            (UCHAR*) &local_int4,
                            sizeof(local_int4));
                *used = sizeof(local_int4);
            }
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float;
            api_retcode = aptchfd( local_string, out_format );
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                SDOUBLE local_double;
                local_double = atof( (char*) in_ptr);
                if (local_double > FLT_MAX || local_double < FLT_MIN) {
                    api_retcode = API_DATA_LOSS;
                } else {
                    local_float = (SFLOAT) local_double;
                    API_MEMCPY( out_ptr,
                                (UCHAR*) &local_float,
                                sizeof(local_float));
                    *used = sizeof(local_float);
                }; /* else */
            }
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local_double = atof( (char*) local_string );
                API_MEMCPY(out_ptr, (UCHAR*) &local_double, sizeof(SDOUBLE));
                *used = sizeof(local_double);
                break;
            }
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        } /* inner switch */
        break;
    }
#ifdef BIGINT_SUPPORTED    
    case (SQL_C_SBIGINT): {} /* new in 3.0 */
    case (SQL_C_UBIGINT): {
        API_BIGINT local_bigint;	 
        if (in_format == SQL_C_UBIGINT) {
            csigned = FALSE;
            API_MEMCPY( (UCHAR*) &local_bigint, in_ptr, sizeof(API_BIGINT));
            /* wsprintf == API_SPRINTF does not work with _int64 */
            sprintf( (char*) local_string, PRINT_UBIGINT, local_bigint);
        }
        else {
            csigned = TRUE;
            API_MEMCPY( (UCHAR*) &local_bigint, in_ptr, sizeof(API_BIGINT));
            /* wsprintf == API_SPRINTF does not work with _int64 */            
            sprintf( (char*) local_string, PRINT_SBIGINT, local_bigint);
        }
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {}
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw (local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_BIT): {
            *out_ptr = (UCHAR) (local_bigint != 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            SWORD local_short;
            api_retcode = aptchsl( local_string, out_format);
            if (api_retcode == API_OK) {
                local_short = (SWORD) local_bigint;
                API_MEMCPY( out_ptr, (UCHAR*) &local_short, sizeof(SWORD));
                *used = sizeof(local_short);
            }
            break;
	    }
	    case (SQL_INTEGER): {
            tsp00_Int4 local_int4;
            api_retcode = aptchsl( local_string, API_INT4_TYPE );
            if (api_retcode == API_OK) {
                local_int4 = (tsp00_Int4) local_bigint;
                API_MEMCPY( out_ptr, &local_int4, sizeof(local_int4));
                *used = sizeof(local_int4);
            }
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local_float = (SFLOAT) atof( (char*) local_string );
                API_MEMCPY(out_ptr, (UCHAR*) &local_float, sizeof(SFLOAT));
                *used = sizeof(local_float);
            }
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            api_retcode = aptchfd(local_string, out_format);
            if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
                local_double = (SDOUBLE) atof( (char*) local_string );
                API_MEMCPY(out_ptr, (UCHAR*) &local_double, sizeof(SDOUBLE));
                *used = sizeof(local_double);
                break;
            }
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        } /* inner switch */
        break;
    }
#endif /* BIGINT_SUPPORTED */    
    case (SQL_C_FLOAT): {                /* ODBC book ,pg 488 */
        SFLOAT local_float;
        API_MEMCPY(&local_float, in_ptr, sizeof(local_float));
        API_TRACE(API_TR_SFLOAT, "SFLOAT", &local_float);  
        pa08flt(local_string, (SDOUBLE) local_float, in_format); 
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     API_REAL_PREC,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw (local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     API_REAL_PREC,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_BIT): {
            *out_ptr = (UCHAR)((local_float) ? 1 : 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            SWORD local_short;
            api_retcode = aptchsl(local_string, out_format);
            switch (api_retcode) {
            case API_TRUNCATE: {
                local_short = (SWORD) atoi( (char*) local_string);
                API_MEMCPY(out_ptr, (UCHAR*) &local_short, sizeof(local_short));
                *used = sizeof(local_short);
                break;
            }
            case API_OK: {
                local_short = (SWORD) local_float;
                API_MEMCPY(out_ptr, (UCHAR*) &local_short, sizeof(local_short));
                *used = sizeof(local_short);
                break;
            }
            default: {
                break;
            }
            }
            break;
	    }
	    case (SQL_INTEGER): {
            tsp00_Int4 local_int4;
            api_retcode = aptchsl(local_string, API_INT4_TYPE);
            switch (api_retcode) {
            case API_TRUNCATE: {
                local_int4 = atol( (char*) local_string);
                API_MEMCPY(out_ptr, (UCHAR*) &local_int4, sizeof(local_int4));
                *used = sizeof(local_int4);
                break;
            }
            case API_OK: {
                local_int4 = (SDWORD) local_float;
                API_MEMCPY(out_ptr, (UCHAR*) &local_int4, sizeof(local_int4));
                *used = sizeof(local_int4);
                break;
            }
            default: {
                break;
            }
            }
            break;
	    }
	    case (SQL_REAL): {
            API_MEMCPY(out_ptr, in_ptr, sizeof(float));
            *used = sizeof(SFLOAT);
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            SDOUBLE local_double;
            local_double = (SDOUBLE) local_float;
            API_MEMCPY(out_ptr,(UCHAR*) &local_double, sizeof(local_double));
            *used = sizeof(local_double);
            break;
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        } /* inner switch */
        break;
    }   /* inner definition area */
    case (SQL_C_DOUBLE): {               /* ODBC book ,pg 488 */
        SDOUBLE local_double;
        API_MEMCPY((UCHAR*) &local_double, in_ptr, sizeof(double));
        API_TRACE(API_TR_SDOUBLE, "SDOUBLE", &local_double);  
        pa08flt(local_string, local_double, in_format); 
        switch (out_format) {              /* INNER SWITCH      */
	    case (SQL_CHAR): {}
	    case (SQL_VARCHAR): {}
	    case (SQL_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     API_FLOAT_PREC,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_UNICODE): {}
	    case (SQL_UNICODE_VARCHAR): {}
	    case (SQL_UNICODE_LONGVARCHAR): {
            API_TRACE(API_TR_STRING, "local_string", local_string);  
            api_retcode = aptnm2chw (local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     API_FLOAT_PREC,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_DECIMAL): {}
	    case (SQL_NUMERIC): {
            api_retcode = aptnm2ch ( local_string,
                                     in_format,
                                     out_ptr,
                                     out_length,
                                     out_scale,
                                     out_format,
                                     used);
            break;
	    }
	    case (SQL_BIT): {
            *out_ptr = (UCHAR)((local_double) ? 1 : 0);
            api_retcode = API_OK;
            break;
	    }
	    case (SQL_SMALLINT): {
            SWORD local_short;
            api_retcode = aptchsl(local_string, out_format);
            switch (api_retcode) {
            case API_TRUNCATE: {
                local_short = (SWORD) atoi( (char*) local_string);
                API_MEMCPY(out_ptr, (UCHAR*) &local_short, sizeof(local_short));
                *used = sizeof(local_short);
                break;
            }
            case API_OK: {
                local_short = (SWORD) local_double;
                API_MEMCPY(out_ptr, (UCHAR*) &local_short, sizeof(local_short));
                *used = sizeof(local_short);
                break;
            }
            default: {
                break;
            }
            }
            break;
	    }
	    case (SQL_INTEGER): {
            tsp00_Int4 local_int4;
            api_retcode = aptchsl(local_string, API_INT4_TYPE);
            switch (api_retcode) {
            case API_TRUNCATE: {
                local_int4 = atol( (char*) local_string);
                API_MEMCPY(out_ptr, (UCHAR*) &local_int4, sizeof(local_int4));
                *used = sizeof(local_int4);
                break;
            }
            case API_OK: {
                local_int4 = (tsp00_Int4) local_double;
                API_MEMCPY(out_ptr, (UCHAR*) &local_int4, sizeof(local_int4));
                *used = sizeof(local_int4);
                break;
            }
            default: {
                break;
            }
            }
            break;
	    }
	    case (SQL_REAL): {
            SFLOAT local_float;
            api_retcode = aptchfd(local_string, out_format);
            switch (api_retcode) {
            case API_TRUNCATE: {
                api_retcode = API_OK;
                local_float = (SFLOAT) atof( (char*) local_string);
                API_MEMCPY(out_ptr, (UCHAR*) &local_float, sizeof(local_float));
                *used = sizeof(local_float);
                break;
            }
            case API_OK: {
                local_float = (SFLOAT) local_double;
                API_MEMCPY(out_ptr, (UCHAR*) &local_float, sizeof(local_float));
                *used = sizeof(local_float);
                break;
            }
            default: {
                break;
            }
            }
            break;
	    }
	    case (SQL_FLOAT): {}
	    case (SQL_DOUBLE): {
            API_MEMCPY(out_ptr, in_ptr, sizeof(SDOUBLE));
            *used = sizeof(SDOUBLE);
            break;
	    }
	    case (SQL_TYPE_DATE): {}
	    case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
	    case (SQL_DATE): {}
	    case (SQL_TIME): {}
	    case (SQL_TIMESTAMP): {
            api_retcode = API_INVALID;	       
            break;
	    }
	    default: {
            API_TRACE(API_TR_SWORD,"** unknown ** out_format", &out_format);
            api_retcode = API_NOT_OK;
            break;
	    }
        }   /* inner switch */
        break;
    }
    default: {
        API_TRACE(API_TR_SWORD,"** unknown ** in_format", &out_format);
        api_retcode = API_NOT_OK;
        break;
    }
    } /* end switch out format */
    API_TRACE(API_TR_UDWORD, "*used", used);
    API_TRACE(API_TR_EXIT,"aptnumeric",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* aptnumeric */


/* aptbit() - convert C to SQL: Bit */
API_RETCODE aptbit(UCHAR FAR * in_ptr,
                   UDWORD in_length,
                   SWORD in_format,
                   UCHAR FAR * out_ptr,
                   UDWORD out_length,
                   UWORD out_scale,
                   SWORD out_format,
                   UDWORD *used)
{
    API_RETCODE api_retcode;

    API_TRACE(API_TR_ENTRY, "aptbit", 0);
    API_TRACE(API_TR_PTR, "in_ptr", &in_ptr);
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE(API_TR_SWORD, "in_format", &in_format);
    API_TRACE(API_TR_PTR, "out_ptr", &out_ptr);
    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE(API_TR_UWORD, "out_scale", &out_scale);
    API_TRACE(API_TR_SWORD, "out_format", &out_format);  
    API_TRACE(API_TR_PTR, "used", &used);  

    api_retcode = API_OK;
   
    switch (out_format) {
    case (SQL_BINARY): {}
    case (SQL_VARBINARY): {}
    case (SQL_LONGVARBINARY): {}
    case (SQL_TYPE_DATE): {}
    case (SQL_TYPE_TIME): {}
    case (SQL_TYPE_TIMESTAMP): {}
    case (SQL_DATE): {}
    case (SQL_TIME): {}
    case (SQL_TIMESTAMP): {
        api_retcode = API_INVALID;	       
        break;
    }

    case (SQL_BIT): {
      *used = 1;
      *out_ptr = *in_ptr;
      break;
    }
    case (SQL_CHAR): {}
    case (SQL_VARCHAR): {}
    case (SQL_LONGVARCHAR): {}
    case (SQL_UNICODE): {}
    case (SQL_UNICODE_VARCHAR): {}
    case (SQL_UNICODE_LONGVARCHAR): {
        tsp00_Uint4 destBytesWritten, srcBytesParsed;
        UCHAR local;
        const tsp77encoding *out_encoding;
          
        local = *in_ptr != 0 ? '1' : '0';
        out_encoding = pa04gGetEncodingType (out_format);

        if (out_length >= (UDWORD) out_encoding->fixedCharacterSize) {
            sp78convertBuffer (out_encoding, out_ptr, out_encoding->fixedCharacterSize,
                               &destBytesWritten,
                               sp77encodingAscii, &local, 1,
                               &srcBytesParsed);
            *used = destBytesWritten;
            /* add null terminator */
            if (out_length >= (UDWORD) out_encoding->fixedCharacterSize + out_encoding->terminatorSize)
                API_MEMSET (out_ptr + *used, 0, out_encoding->terminatorSize);
        }
        break;
    }
    case (SQL_INTEGER): {
        tsp00_Int4 local = *in_ptr != 0;
        API_MEMCPY (out_ptr, (UCHAR*) &local, sizeof(local));
        break;
        }	
    case (SQL_SMALLINT): {
        SWORD local = *in_ptr != 0;
        API_MEMCPY (out_ptr, (UCHAR*) &local, sizeof(local));
        break;
    }
    case (SQL_NUMERIC): {}
    case (SQL_DECIMAL): {
        UCHAR local_string[2];

        local_string[0] = *in_ptr;
        local_string[1] = '\0';
        api_retcode = aptnm2ch (local_string, in_format,
                                out_ptr,      out_length, out_scale, out_format,
                                used);
        break;
    }
    case (SQL_REAL): {
        SFLOAT local = (SFLOAT) (*in_ptr != 0);
        API_MEMCPY (out_ptr, (UCHAR*) &local, sizeof(local));
        break;
    }
    case (SQL_FLOAT): {}
    case (SQL_DOUBLE): {
        SDOUBLE local = *in_ptr != 0;
        API_MEMCPY (out_ptr, (UCHAR*) &local, sizeof(local));
        break;
    }

    default: {	 
        api_retcode = API_NOT_OK;
        break;
    }	 
    }
    API_TRACE(API_TR_UDWORD, "*used", used);
    API_TRACE(API_TR_EXIT,"aptbit",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* aptbit */


/* aptdate() - convert C to SQL: Date */
API_RETCODE aptdate(UCHAR FAR * in_ptr,
                    UDWORD in_length,
                    SWORD in_format,
                    UCHAR FAR * out_ptr,
                    UDWORD out_length,
                    UWORD out_scale,
                    SWORD out_format, 
                    UDWORD *used)
{
    API_RETCODE api_retcode;
    UCHAR local_string [API_CHAR_LENGTH_CHAR];
    time_t ltime;
    struct tm *ltm;

    API_TRACE(API_TR_ENTRY, "aptdate", 0);
    API_TRACE(API_TR_PTR, "in_ptr", &in_ptr);
    API_TRACE_BUF(in_ptr, 1, ((in_length > 40) ? 40 : in_length));
    API_TRACE(API_TR_UDWORD, "in_length", &in_length);
    API_TRACE(API_TR_SWORD, "in_format", &in_format);
    API_TRACE(API_TR_UDWORD, "out_length", &out_length);
    API_TRACE(API_TR_SWORD, "out_format", &out_format);  
    API_TRACE(API_TR_PTR, "used", &used);  

    api_retcode = API_OK;
    if (apgischar(out_format) || apgistime(out_format)) {
        switch(in_format) {
        case (SQL_C_TYPE_DATE):
        case (SQL_C_DATE): {
            UCHAR time_str[12];
            API_SPRINTF( (char*) time_str, "00:00:00");
            switch(out_format) {
            case SQL_TYPE_TIMESTAMP:
            case SQL_TIMESTAMP: {   
                DATE_STRUCT *sD;
                sD = (DATE_STRUCT *)in_ptr;
                API_SPRINTF( (char*) local_string, "%04d%c%02d%c%02d %s.000000",
                             sD->year, PA_DATE_SEP,
                             sD->month, PA_DATE_SEP, sD->day, time_str);
                break;
            }
            case SQL_TYPE_TIME:
            case SQL_TIME: {
                api_retcode = API_INVALID;	       
                break;
            }
            default: {	       
                DATE_STRUCT *sD;
                sD = (DATE_STRUCT *)in_ptr;
                API_SPRINTF( (char*) local_string, "%04d%c%02d%c%02d",
                             sD->year, PA_DATE_SEP,
                             sD->month, PA_DATE_SEP, sD->day);	    
                break;
            }
            }
            break;
        }
        case (SQL_C_TYPE_TIME):
        case (SQL_C_TIME): {
            UCHAR date_str[12];
            time(&ltime);
            ltm = localtime(&ltime);
            strftime( (char*) date_str, sizeof(date_str), "%Y-%m-%d", ltm);
            switch(out_format) {
            case SQL_TYPE_TIMESTAMP:
            case SQL_TIMESTAMP: {
                TIME_STRUCT *sT;
                sT = (TIME_STRUCT *)in_ptr;
                API_SPRINTF( (char*) local_string,
                             "%s %02d%c%02d%c%02d.000000",
                             date_str, sT->hour, PA_TIME_SEP, 
                             sT->minute, PA_TIME_SEP, sT->second );
                break;
            }
            case SQL_TYPE_DATE:	       
            case SQL_DATE: {
                api_retcode = API_INVALID;	       
                break;
            }
            default: {	       
                TIME_STRUCT *sT;
                sT = (TIME_STRUCT *)in_ptr;
                API_SPRINTF( (char*) local_string, "%02d%c%02d%c%02d",
                             sT->hour, PA_TIME_SEP, 
                             sT->minute, PA_TIME_SEP, sT->second );
                break;
            }
            }
            break;
        }
        case (SQL_C_TYPE_TIMESTAMP):
        case SQL_C_TIMESTAMP: {
            TIMESTAMP_STRUCT *sTS;
            sTS = (TIMESTAMP_STRUCT *)in_ptr;
            switch(out_format) {
            case SQL_TYPE_DATE:
            case SQL_DATE: {	       
                API_SPRINTF( (char*) local_string, "%04d%c%02d%c%02d",
                             sTS->year, PA_DATE_SEP,
                             sTS->month, PA_DATE_SEP, sTS->day);
                if (sTS->hour != 0 || sTS->minute != 0 || sTS->second != 0)
                    api_retcode = API_TRUNCATE;		     
                break;
            }
            case SQL_TYPE_TIME:
            case SQL_TIME: {
                API_SPRINTF( (char*) local_string, "%02d%c%02d%c%02d",
                             sTS->hour, PA_TIME_SEP, 
                             sTS->minute, PA_TIME_SEP, sTS->second );
                if (sTS->year != 0 || sTS->month != 0 || sTS->day != 0)
                    api_retcode = API_TRUNCATE;		     
                break;
            }
            default: {	       
                API_SPRINTF( (char*) local_string,
                             /* PTS 1119281 */
                             /* "%04d%c%02d%c%02d%c%02d%c%02d%c%02d%c%06ld", */
                             "%04d%c%02d%c%02d%c%02d%c%02d%c%02d%c%06d",
                             sTS->year, PA_DATE_SEP,
                             sTS->month, PA_DATE_SEP, sTS->day,
                             PA_TIMESTAMP_SEP, sTS->hour,
                             PA_TIME_SEP, sTS->minute,
                             PA_TIME_SEP, sTS->second,
                             PA_FRAC_SEP, sTS->fraction );
                break;
            }
            }
            break;
        }
        case (SQL_C_WCHAR): {
          UCHAR localString[sizeof(tsp81_UCS2Char)*API_CHAR_LENGTH_CHAR];
          tsp78ConversionResult convRes;
          tsp00_Uint4 destBytesWritten, srcBytesParsed;

          convRes = sp78convertString (sp77encodingAscii, 
                                       local_string, in_length,
                                       &destBytesWritten,
                                       TRUE,
                                       sp77encodingUCS2Native,
                                       in_ptr, in_length,
                                       &srcBytesParsed);
          in_length = destBytesWritten;
          if (convRes != sp78_Ok)
            api_retcode = API_NOT_OK;
          else
            api_retcode = aptdate (localString, in_length,  SQL_C_CHAR,
                                   out_ptr,     out_length, out_scale, out_format, used);
          break;
        }
        case (SQL_C_CHAR): {
            API_STRCPY(local_string,in_ptr);
            switch(out_format) {
            case (SQL_TYPE_DATE):
            case (SQL_DATE): {
                api_retcode = apgchdt(local_string);
                break;
            }
            case (SQL_TYPE_TIME): {
                api_retcode = apgchtm(local_string);
                break;
            }
            case (SQL_TYPE_TIMESTAMP): {
                UCHAR *p;
                size_t len;
                api_retcode = apgchts(local_string);		  
                if (api_retcode == API_OK) {
                    p = (UCHAR*) API_STRCHR(local_string, ':');
                    if (!p) {
                        len = API_STRLEN(local_string);
                        if (len < sizeof(local_string) - 8) {
                            API_STRCAT(local_string, " 00:00:00");
                        }
                    }
                    p = (UCHAR*) API_STRCHR(local_string, '.');
                    if (!p) {
                        API_STRCAT(local_string, ".");
                        p = (UCHAR*) API_STRCHR(local_string, '.');
                    }
                    len = API_STRLEN(local_string);
                    if (len < API_TIMESTAMP_EXT_PREC) {
                        UCHAR sf[6];			
                        API_STRCPY(sf, p+1);
                        for (;len < API_TIMESTAMP_EXT_PREC; len++)
                            API_STRCAT(local_string, "0");
                        API_STRCAT(local_string, sf);
                    }     		     		     
                }
                else {
                    api_retcode = apgchtm(local_string);
                    if (api_retcode == API_OK) {
                        UCHAR date_str[API_TIMESTAMP_EXT_PREC];
                        UCHAR FAR *p;
                        time(&ltime);
                        ltm = localtime(&ltime);
                        strftime( (char*) date_str,
                                  sizeof(date_str), "%Y-%m-%d ", ltm);
                        for (p = local_string; *p != '\0'; p++) {
                            if (!isspace(*p))
                                break;
                        }
                        API_STRNCAT(&date_str[11], p, 8);			   
                        API_STRCPY(local_string, date_str);			   
                        API_STRCAT(local_string, ".000000");			   
                    }			
                }
                break;
            }
            } /* end switch */
            break;
        }
        case (SQL_C_SSHORT): {}
        case (SQL_C_USHORT): {}
        case (SQL_C_SHORT): {}
        case (SQL_C_SLONG): {}
        case (SQL_C_ULONG): {}
        case (SQL_C_LONG): {}
        case (SQL_C_STINYINT): {}
        case (SQL_C_UTINYINT): {}
        case (SQL_C_TINYINT): {}
        case (SQL_C_BIT): {}
        case (SQL_C_FLOAT): {}
        case (SQL_C_DOUBLE): {}
        case (SQL_C_BINARY): {}
        /* these three are new in 3.0 */
        case (SQL_C_NUMERIC): {}
        case (SQL_C_SBIGINT): {}
        case (SQL_C_UBIGINT): {
            api_retcode = API_INVALID;	       
        }
        default:{
            API_TRACE(API_TR_SWORD, "in_format not supported", &in_format);
            api_retcode = API_NOT_OK;	 
            break;
        }
        } /* end switch */
        *used = (SQLUINTEGER) API_STRLEN(local_string);
    }
    if (api_retcode == API_OK || api_retcode == API_TRUNCATE) {
        API_TRACE(API_TR_STRING, "local_string", &local_string);
        switch (out_format) {
        case (SQL_TYPE_DATE): {}
        case (SQL_TYPE_TIME): {}
        case (SQL_TYPE_TIMESTAMP): {}
        case (SQL_DATE): {}
        case (SQL_TIME): {}
        case (SQL_TIMESTAMP): {}
        case (SQL_CHAR): {}
        case (SQL_UNICODE): {}
        case (SQL_VARCHAR): {}
        case (SQL_UNICODE_VARCHAR): {}
        case (SQL_LONGVARCHAR): {}
        case (SQL_UNICODE_LONGVARCHAR): {}
        case (SQL_BINARY): {}
        case (SQL_VARBINARY): {}
        case (SQL_LONGVARBINARY): {	 
            API_RETCODE ret_retcode;
            ret_retcode = aptchar( local_string, *used, in_format, out_ptr, 
                                   out_length, out_scale, out_format, used);
            if (ret_retcode != API_OK)
                api_retcode = ret_retcode;
            break;
        }
        case (SQL_INTEGER): {}
        case (SQL_SMALLINT): {}
        case (SQL_NUMERIC): {}
        case (SQL_DECIMAL): {}
        case (SQL_FLOAT): {}
        case (SQL_DOUBLE): {
            api_retcode = API_INVALID;	       
            break;
        }
        default: {
            API_TRACE(API_TR_SWORD, "format not supported", &out_format);
            api_retcode = API_NOT_OK;	 
            break;
        }
        } /* end switch */
    }
    API_TRACE(API_TR_UDWORD, "*used", used);
    API_TRACE_BUF(out_ptr, 1, ((*used > 40) ? 40 : *used));
    API_TRACE(API_TR_EXIT,"aptdate",0);
    API_TRACE(API_TR_API_RETCODE,"api_retcode",&api_retcode);

    return(api_retcode);
} /* aptdate */


/* apdexp()   - Dependent routine to get the exponent as an   */
/*              numeric field                                 */

VOID apdexp(UCHAR FAR *string_ptr, SWORD FAR *exponent_ptr)
{
    UCHAR FAR * e_ptr;

    API_TRACE(API_TR_ENTRY,"apdexp",0);
    API_TRACE(API_TR_PTR,"string_ptr",&string_ptr);
    API_TRACE(API_TR_PTR,"exponent_ptr",&exponent_ptr);

    if ((e_ptr = (UCHAR*) API_STRCHR(string_ptr, 'e')) == (UCHAR*) NULL)
        e_ptr = (UCHAR*) API_STRCHR(string_ptr, 'E');  
    if (e_ptr != NULL) {
        *(e_ptr) = 'E';
        *exponent_ptr = (SWORD)atoi( (char*) e_ptr+1);
    }
    else 
        *exponent_ptr = 0;     
    API_TRACE(API_TR_EXIT,"apdexp",0);
    API_TRACE(API_TR_STRING,"string_ptr", string_ptr);
    API_TRACE(API_TR_SWORD,"*exponent_ptr", exponent_ptr);

    return;
} /* apdexp */


BOOLEAN pa04t_NumericNotNull( SQL_NUMERIC_STRUCT  *numeric )
{
    SWORD i;

    for (i = 0; i < SQL_MAX_NUMERIC_LEN; i++) {
        if (numeric->val[i] != 0) {
            return TRUE;
        }; /* if */
    }; /* for */

    return FALSE;
} /* pa04t_NumericNotNull */


/* end of vpa04tc */
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
