/*
_____       _    _    Corso   Italia,  178
(_|__   .  (_   |_|_  56125           Pisa
(_|_) |)|(()_)()| |   tel.  +39  050 46380
  |   |               picosoft@picosoft.it

 Copyright (C) Picosoft s.r.l. 1995-2002

 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.

*/
# include "cfield.h"
static char rcsid[] = "$Id: cfield.cpp 5.2 2001/09/24 13:36:03 picoSoft Exp Marco $";
static char rcsidh[] = cfield_h;
extern "C" {
# include <stdlib.h>
# include <string.h>
};
# include "dberror.h"
# include "datatype.h" 
# include "attribut.h"
# include "sqlpars.h"
PCLASSID(CField)

Error
CField::ToExt (SqlParser *sp, unsigned long numElem)
{
   Error Return = SQL_SUCCESS;
   char *bufNum;
   long len;
   char *locBuffer = &Buffer[numElem * BufferLen];
   long *locByteRed = &ByteRed[numElem];
   char saveBuffer = *locBuffer;
   long saveByteRed = *locByteRed;
   
   *locBuffer = 0;
   *locByteRed = BufferLen;    // purche' sia diverso da SQL_NULL_DATA (-1)
   switch (CType) {
   case SQL_C_CHAR:
      if (DBAttr->getAttr()->getDateType() == T_TIMESTAMP)
         Return = DBAttr->ToTsChar (&bufNum, *locByteRed);
      else
         Return = DBAttr->ToChar (&bufNum, *locByteRed);
      len = *locByteRed;
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         if (len >= BufferLen) {
            len =  BufferLen - 1;
            PrintError ( 0, 0, sp, E_WARNING_004, "");
            Return = SQL_SUCCESS_WITH_INFO;
         }
         if (len >= 0) {
            sp->GetDB()->IntlFromServer (bufNum, locBuffer, (int) len);
            locBuffer[len] = 0;
         } 
         break;
      case T_CLOB:
      {
         BlobField *blob = DBAttr->getBlob();
         if (blob != 0) {
            len = blob->getToRead();
            if (len == 0) {
               if (blob->getBlobLen() == 0)
                  *locByteRed = SQL_NULL_DATA;
               else
                  Return = SQL_NO_DATA_FOUND;
            } else {
               if (len >= BufferLen) {
                  len = BufferLen - 1;
                  PrintError ( 0, 0, sp, E_WARNING_004, "");
                  Return = SQL_SUCCESS_WITH_INFO;
               }
               locBuffer[len] = '\0';
               *locByteRed = blob->getToRead();
               memcpy (locBuffer, blob->getBlobPiece(len), len);
            }
         } else {
            PrintError ( 0, 0, sp, E_GENERAL_ERROR_000, "Attribute has not a BLOB");
            Return = SQL_ERROR;
         }
         break;
      }
      case T_BLOB:
      {
         if (( len << 1) >= BufferLen) {
            len = (BufferLen >> 1) - 1;
            PrintError ( 0, 0, sp, E_WARNING_004, "");
            Return = SQL_SUCCESS_WITH_INFO;
         }
         unsigned char c, a = 'A' - 10;
         int i, j;
         for (i = 0, j = 0; i < len; i++) {
            c = (bufNum[i] & 0xF0) >> 4;
            c = c <= 9 ? c + '0' : c + a;
            locBuffer[j++] = c;
            c = (bufNum[i] & 0x0F);
            c = c <= 9 ? c + '0' : c + a;
            locBuffer[j++] = c;
         }
         locBuffer[j] = 0;
	 *locByteRed = (len << 1);
         break;
      }
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
         if (*locByteRed >= BufferLen) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
            Return = SQL_ERROR;
         } else if (len >= 0)   
            strcpy (locBuffer, bufNum);
         break;
      case T_FLOAT: 
      case T_DOUBLE:
         if (*locByteRed >= BufferLen)
            if (BufferLen > 8) {
               sprintf (locBuffer, "%.*lg", BufferLen - 7, atof(bufNum));
               break;
            } else {
               PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
               *locBuffer = saveBuffer;
               *locByteRed = saveByteRed;
               Return = SQL_ERROR;
            }
         else if (len >= 0)
            strcpy (locBuffer, bufNum);
         break;
      }
      break;
   case SQL_C_SHORT:
   case SQL_C_SSHORT:
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
         break;
      case T_BLOB: // Solo in prima istanza
      case T_CLOB: // Solo in prima istanza
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
      case T_FLOAT:
      case T_DOUBLE:
         if ((Return = DBAttr->ToShort (*((short *)locBuffer), *locByteRed)) == SQL_ERROR) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
         }                            
         break;
      }
      break; 
   case SQL_C_USHORT:
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
         break;
      case T_BLOB: // Solo in prima istanza
      case T_CLOB: // Solo in prima istanza
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
      case T_FLOAT:
      case T_DOUBLE:
         if ((Return = DBAttr->ToUShort (*((unsigned short *)locBuffer), *locByteRed)) == SQL_ERROR) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
         }                            
         break;
      }
      break;
   case SQL_C_LONG:
   case SQL_C_SLONG:
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
         break;
      case T_BLOB: // Solo in prima istanza
      case T_CLOB: // Solo in prima istanza
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
      case T_FLOAT:
      case T_DOUBLE: 
         if ((Return = DBAttr->ToLong (*((long *)locBuffer), *locByteRed)) == SQL_ERROR) {
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
         }
         break;
      }
      break;
   case SQL_C_ULONG:
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
         break;
      case T_BLOB: // Solo in prima istanza
      case T_CLOB: // Solo in prima istanza
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
      case T_FLOAT:
      case T_DOUBLE: 
         if ((Return = DBAttr->ToULong (*((unsigned long *)locBuffer), *locByteRed)) == SQL_ERROR) {
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
         }
         break;
      }
      break;
   case SQL_C_FLOAT:
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
         break;
      case T_BLOB: // Solo in prima istanza
      case T_CLOB: // Solo in prima istanza
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
      case T_FLOAT:
      case T_DOUBLE: 
         if ((Return = DBAttr->ToFloat (*((float *)locBuffer), *locByteRed)) == SQL_ERROR) {
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
         }
         break;
      }
      break;
   case SQL_C_DOUBLE:
      switch (DBAttr->getAttr()->GetType()) {
      case T_CSTRING:
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
         break;
      case T_BLOB: // Solo in prima istanza
      case T_CLOB: // Solo in prima istanza
      case T_PACKED_ORDERED:
      case T_SHORT:
      case T_LONG:
      case T_FLOAT:
      case T_DOUBLE: 
         if ((Return = DBAttr->ToDouble (*((double *)locBuffer), *locByteRed)) == SQL_ERROR) {
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
         }
         break;
      }
      break;
   case SQL_C_DEFAULT:
      if (DBAttr->getAttr()->getDateType() == T_TIMESTAMP) {
         if (BufferLen < sizeof(TIMESTAMP_STRUCT)) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
         } else
             if ((Return = DBAttr->ToTimeStamp ((TIMESTAMP_STRUCT *)locBuffer, *locByteRed)) == SQL_ERROR) {
                PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                *locBuffer = saveBuffer;
                *locByteRed = saveByteRed;
             }
      } else {
         switch (DBAttr->getAttr()->GetType()) {
         case T_CSTRING:
            Return = DBAttr->ToChar (&bufNum, *locByteRed);
            len = *locByteRed;
            if (len >= BufferLen) {
               len =  BufferLen - 1;
               PrintError ( 0, 0, sp, E_WARNING_004, "");
               Return = SQL_SUCCESS_WITH_INFO;
            }
            if (len >= 0) {
               sp->GetDB()->IntlFromServer (DBAttr->GetBuffer (),
                                            locBuffer, (int) len);
               locBuffer[len] = 0;
            }
            break;
         case T_BLOB:
         case T_CLOB:
         {
            BlobField *blob = DBAttr->getBlob();
            if (blob != 0) {
               len = blob->getToRead();
               if (len == 0) {
                  if (blob->getBlobLen() == 0)
                     *locByteRed = SQL_NULL_DATA;
                  else
                     Return = SQL_NO_DATA_FOUND;
               } else {
                  if (DBAttr->getAttr()->GetType() == T_BLOB) {
                     if (len > BufferLen) {
                        len = BufferLen;
                        PrintError ( 0, 0, sp, E_WARNING_004, "");
                        Return = SQL_SUCCESS_WITH_INFO;
                     }
                  } else if (DBAttr->getAttr()->GetType() == T_CLOB) {
                     if (len >= BufferLen) {
                        len = BufferLen - 1;
                        PrintError ( 0, 0, sp, E_WARNING_004, "");
                        Return = SQL_SUCCESS_WITH_INFO;
                     }
                     locBuffer[len] = '\0';
                  }
                  *locByteRed = blob->getToRead();
                  memcpy (locBuffer, blob->getBlobPiece(len), len);
               }
            } else {
               PrintError ( 0, 0, sp, E_GENERAL_ERROR_000, "Attribute has not a BLOB");
               Return = SQL_ERROR;
            }
            break;
         }
         case T_PACKED_ORDERED:
# ifdef NO_MS_ACCESS
            Return = DBAttr->ToChar (&bufNum, *locByteRed);
            len = *locByteRed;
            if (len >= BufferLen) {
               len =  BufferLen - 1;
               PrintError ( 0, 0, sp, E_WARNING_004, "");
               Return = SQL_SUCCESS_WITH_INFO;
            }
# else
// I tipi COBOL hanno un default sempre DOUBLE per problemi di MS-ACCESS
// Questa parte deve essere in sincronia con Int2OdbcType in results.cpp
            if ((Return = DBAttr->ToDouble (*((double *)locBuffer), *locByteRed)) == SQL_ERROR) {
               PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
               *locBuffer = saveBuffer;
               *locByteRed = saveByteRed;
            }
# endif
            break;
// Vedi commento sopra         
         case T_SHORT:
            if (DBAttr->getAttr()->GetSign() == UNSIGNED) {
               if ((Return = DBAttr->ToLong (*((long *)locBuffer), *locByteRed)) == SQL_ERROR) {
                  PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                  *locBuffer = saveBuffer;
                  *locByteRed = saveByteRed;
               }                          
            } else
               if ((Return = DBAttr->ToShort (*((short *)locBuffer), *locByteRed)) == SQL_ERROR) {
                  PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                  *locBuffer = saveBuffer;
                  *locByteRed = saveByteRed;
            }
            break;
// Vedi commento sopra
         case T_LONG:
            if (DBAttr->getAttr()->GetSign() == UNSIGNED) {
               if ((Return = DBAttr->ToDouble (*((double *)locBuffer), *locByteRed)) == SQL_ERROR) {
                  PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                  *locBuffer = saveBuffer;
                  *locByteRed = saveByteRed;
               }
            } else
               if ((Return = DBAttr->ToLong (*((long *)locBuffer), *locByteRed)) == SQL_ERROR) {
                  PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                  *locBuffer = saveBuffer;
                  *locByteRed = saveByteRed;
               }
            break;
         case T_FLOAT:
            if ((Return = DBAttr->ToFloat (*((float *)locBuffer), *locByteRed)) == SQL_ERROR) {
               PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
            }
            break;
         case T_DOUBLE:
            if ((Return = DBAttr->ToDouble (*((double *)locBuffer), *locByteRed)) == SQL_ERROR) {
               PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
               *locBuffer = saveBuffer;
               *locByteRed = saveByteRed;
            }
            break;
         }
      }
      break;
   case SQL_C_TIMESTAMP:
      if (DBAttr->getAttr()->getDateType() == T_TIMESTAMP) {
         if (BufferLen < sizeof(TIMESTAMP_STRUCT)) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
         } else
             if ((Return = DBAttr->ToTimeStamp ((TIMESTAMP_STRUCT *)locBuffer, *locByteRed)) == SQL_ERROR) {
                PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                *locBuffer = saveBuffer;
                *locByteRed = saveByteRed;
             }
      } else {
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
      }
      break;
   case SQL_C_TIME:
      if (DBAttr->getAttr()->getDateType() == T_TIMESTAMP) {
         TIMESTAMP_STRUCT ts;
         TIME_STRUCT *t;
         if (BufferLen < sizeof(TIME_STRUCT)) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
         } else
             if ((Return = DBAttr->ToTimeStamp (&ts, *locByteRed)) == SQL_ERROR) {
                PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                *locBuffer = saveBuffer;
                *locByteRed = saveByteRed;
             } else {
                t = (TIME_STRUCT *)locBuffer;
                t->hour = ts.hour;
                t->minute = ts.minute;
                t->second = ts.second;
             }
      } else {
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
      }
      break;
   case SQL_C_DATE:
      if (DBAttr->getAttr()->getDateType() == T_TIMESTAMP) {
         TIMESTAMP_STRUCT ts;
         DATE_STRUCT *d;
         if (BufferLen < sizeof(DATE_STRUCT)) {
            PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
            *locBuffer = saveBuffer;
            *locByteRed = saveByteRed;
         } else
             if ((Return = DBAttr->ToTimeStamp (&ts, *locByteRed)) == SQL_ERROR) {
                PrintError ( 0, 0, sp, E_DATA_EXCEPT_003, "");
                *locBuffer = saveBuffer;
                *locByteRed = saveByteRed;
             } else {
                d = (DATE_STRUCT *)locBuffer;
                d->year = ts.year;
                d->month = ts.month;
                d->day = ts.day;
             }
      } else {
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         *locBuffer = saveBuffer;
         *locByteRed = saveByteRed;
         Return = SQL_ERROR;
      }
      break;
   case SQL_C_BINARY:
      switch (DBAttr->getAttr()->GetType()) {
      case T_BLOB:
      case T_CLOB:
      {
         BlobField *blob = DBAttr->getBlob();
         if (blob != 0) {
            len = blob->getToRead();
            if (len == 0) {
               if (blob->getBlobLen() == 0)
                  *locByteRed = SQL_NULL_DATA;
               else
                  Return = SQL_NO_DATA_FOUND;
            } else {
               if (len > BufferLen) {
                  len = BufferLen;
                  PrintError ( 0, 0, sp, E_WARNING_004, "");
                  Return = SQL_SUCCESS_WITH_INFO;
               }
               *locByteRed = blob->getToRead();
               memcpy (locBuffer, blob->getBlobPiece(len), len);
            }
         } else {
            PrintError ( 0, 0, sp, E_GENERAL_ERROR_000, "Attribute has not a BLOB");
            Return = SQL_ERROR;
         }
         break;
      }
      case T_CSTRING:
      default:
         Return = DBAttr->ToChar (&bufNum, *locByteRed);
         len = *locByteRed;
         if (len >= BufferLen) {
            len =  BufferLen - 1;
            PrintError ( 0, 0, sp, E_WARNING_004, "");
            Return = SQL_SUCCESS_WITH_INFO;
         }
         if (len >= 0) {
            memcpy (locBuffer, bufNum, (int) len);
            locBuffer[len] = 0;
         } 
         break;
         // Return = SQL_ERROR;
         // PrintError (0,0,sp,E_DATA_EXCEPT_003,"Attribute is not a BLOB");
         ///break;
      }
      break;
   case SQL_C_BIT:
   case SQL_C_TINYINT:
   default:
      PrintError ( 0, 0, sp, E_GENERAL_ERROR_003, "");
      *locBuffer = saveBuffer;
      *locByteRed = saveByteRed;
      Return = SQL_ERROR;
      break;
   }
   return Return;
}

void
CField::SetTimeStamp ()
{
   const char *fmt = TIMEST_INTFMT;
   ParamAttr.deleteBuffer ();
   ParamAttr.getAttr()->setType (T_CSTRING, strlen(fmt), 0);
   ParamAttr.getAttr()->setDateFmt (fmt);   
   ParamAttr.allocBuffer ();
}

void
CField::SetParamAttr (DataType t, long i, int d)
{
   ParamAttr.deleteBuffer ();
   ParamAttr.getAttr()->setType (t, i, d);
   ParamAttr.getAttr()->setDateFmt (0);
   ParamAttr.allocBuffer ();
}

Error
CField::FromExt (SqlParser *sp)
{
   Error Return = SQL_SUCCESS;
   long len;
   
   if (*ByteRed == SQL_LEN_DATA_AT_EXEC_OFFSET) {
      len = localBufferLen;
      Buffer = localBuffer;
   } else if (*ByteRed > ParamAttr.getAttr()->getFldSize() || *ByteRed == SQL_NTS)
      len = ParamAttr.getAttr()->getFldSize();
   else
      len = *ByteRed;

   ParamAttr.setNullBuffer ();
   if (len > 0) {
      ParamAttr.setNull (PFalse);
      if (ParamAttr.getAttr()->getDateType() == T_TIMESTAMP) {
         const char *fmt;
         switch (CType) {
         case SQL_C_CHAR:
            if (fmt = isStringTimeStamp(Buffer, len)) {
               TIMESTAMP_STRUCT ts;
               StringToTimeStamp (&ts, Buffer, len, fmt, sp->GetDB()->GetStartDate());
               Return = ParamAttr.FromTimeStamp (&ts);
            } else
               Return = SQL_ERROR;
            break;
         case SQL_C_TIMESTAMP:
            Return = ParamAttr.FromTimeStamp ((TIMESTAMP_STRUCT *) Buffer);
            break;
         case SQL_C_TIME:
            {
               TIMESTAMP_STRUCT ts;
               TIME_STRUCT *t = (TIME_STRUCT *) Buffer;
               Return = ParamAttr.FromTimeStamp (&ts);
               t->hour = ts.hour;
               t->minute = ts.minute;
               t->second = ts.second;
            }
            break;
         case SQL_C_DATE:
            {
               TIMESTAMP_STRUCT ts;
               DATE_STRUCT *d = (DATE_STRUCT *) Buffer;
               Return = ParamAttr.FromTimeStamp (&ts);
               d->year = ts.year;
               d->month = ts.month;
               d->day = ts.day;
            }
            break;
         default:
            Return = SQL_ERROR;
            break;
         }
      } else {
         switch (ParamAttr.getAttr()->GetType()) {
         case T_CSTRING:
            sp->GetDB()->IntlToServer (Buffer, ParamAttr.GetBuffer(),
                                       (int) len);
            break;
         case T_DOUBLE:
            switch (CType) {
            case SQL_C_CHAR:
               Return = ParamAttr.FromString (Buffer);
               break;
            case SQL_C_SHORT:
               Return = ParamAttr.FromDouble ((double) *((short *) Buffer));
               break;
            case SQL_C_LONG:
               Return = ParamAttr.FromDouble ((double) *((long *) Buffer));
               break;
            case SQL_C_FLOAT:
               Return = ParamAttr.FromDouble ((double) *((float *) Buffer));
               break;
            case SQL_C_DOUBLE:
               Return = ParamAttr.FromDouble ((double) *((double *) Buffer));
               break;
            default:
               Return = SQL_ERROR;
               break;
            }
            break;
         case T_BLOB:
         case T_CLOB:
            switch (CType) {
            case SQL_C_CHAR:
            case SQL_C_BINARY:
               Return = ParamAttr.setBlob((unsigned char*) Buffer, *ByteRed);
               break;
            default:
               Return = SQL_ERROR;
               break;
            }
            break;
         default:
            Return = SQL_ERROR;
            break;
         }
      }
      if (Return != SQL_SUCCESS) { 
         PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
         return Return;
      }
   }
         
   if (DBAttr != 0)
      Return = DBAttr->FromAttr (ParamAttr);
 
   if (Return == SQL_ERROR) {
      PrintError ( 0, 0, sp, E_DATA_EXCEPT_018, "");
      return Return;
   } else if (Return == SQL_SUCCESS_WITH_INFO) {
      PrintError ( 0, 0, sp, E_WARNING_004, DBAttr->getName());
   }
   return Return;
}

void
CField::putData (char *b, long len)
{
   if (localBuffer == 0) {
      localBuffer = (char *) malloc (len);
      memcpy (localBuffer, b, len);
      localBufferLen = len;
   } else {
      localBuffer = (char *) realloc (localBuffer, localBufferLen + len);
      memcpy (&localBuffer[localBufferLen], b, len);
      localBufferLen += len;
   }
   *ByteRed += len;
}

CField::~CField ()
{
   if (localBuffer != 0)
      free (localBuffer);
}

void
CField::reset ()
{
   if (localBuffer != 0)
      free (localBuffer);
   DBAttr = 0;
   Buffer = 0;
   localBuffer = 0;
   localBufferLen = 0;
   ParamAttr.deleteBuffer ();
   ParamAttr.getAttr()->setType (T_UNKNOWN, 0, 0);
   ParamAttr.getAttr()->setDateFmt (0);
}
