home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / kdbf / brecord.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  83.2 KB  |  3,321 lines

  1. /*******************************************************************
  2. **
  3. **                          BRECORD.CPP
  4. **
  5. ** This file contains the member functions of the BRecord class.
  6. **
  7. *********************************************************************/
  8.  
  9. // DBF - (C) Copyright 1994 by Borland International
  10.  
  11. #include "kdbf.h"
  12. #pragma hdrstop
  13.  
  14. #ifdef __DLL__
  15.    #define EXPORT _export
  16. #else
  17.    #define EXPORT
  18. #endif
  19.  
  20. //
  21. // prototypes for utility functions
  22. //
  23.  
  24. Retcode EXPORT addRecord(curdef *, BRecord *);
  25. void    EXPORT deleteRecord(curdef *, BRecord *);
  26. Retcode EXPORT addBlob(recdef *, blbdef *);
  27. Retcode EXPORT convertFld(void *, PXFieldType, int,  // Source value
  28.                    void *, PXFieldType, int);        // destination.
  29. Retcode EXPORT strToDate(const char *str, BDate *dt);
  30. Retcode EXPORT strToTime(const char *str, BTime *dt);
  31. Retcode EXPORT strToTimeStamp(const char *str, BTimeStamp *dt);
  32. Retcode EXPORT dateToStr(const BDate *dt, char *str);
  33. Retcode EXPORT timeToStr(const BTime *dt, char *str);
  34. Retcode EXPORT timeStampToStr(const BTimeStamp *dt, char *str);
  35.  
  36. // Constructor for making a generic record object for an open cursor.
  37.  
  38. BRecord::BRecord(BCursor *cursor)
  39. {
  40.     CURProps    curProps;
  41.  
  42.     recdef *ro;
  43.  
  44.     try
  45.     {
  46.         ro = new recdef;                // See the INTSTRCT.H file.
  47.     }
  48.     catch(xalloc)
  49.     {
  50.         lastError = DBIERR_NOMEMORY;
  51.         recH = NULL;
  52.         curH = 0;
  53.         return;
  54.     }
  55.                                
  56.     lastError = DBIERR_NONE;
  57.     ro->handleCnt = 0;
  58.     recH = NULL;
  59.     recobj = (void *)ro;
  60.     curH = cursor;
  61.     if (!cursor)                  // Null cursor ->  unattached record.
  62.     {
  63.         return;
  64.     }
  65.     if (!cursor->isOpen)
  66.     {
  67.         lastError = PXERR_CURSORNOTOPEN;
  68.     }
  69.     else
  70.     {
  71.         if ((lastError = DbiGetCursorProps(curH->tabH, &curProps))
  72.             != DBIERR_NONE)
  73.         {
  74.             return;
  75.         }
  76.  
  77.         try
  78.         {
  79.             recH = new BYTE[curProps.iRecBufSize];
  80.         }
  81.         catch(xalloc)
  82.         {
  83.             lastError = DBIERR_NOMEMORY;
  84.             recH = NULL;
  85.             return;
  86.         }
  87.  
  88.         iRecBufSize = curProps.iRecBufSize;
  89.         addRecord((curdef *)cursor->curobj, this);
  90.         clear();
  91.     }
  92. }
  93.  
  94. // Destructor for BRecord objects.
  95.  
  96. BRecord::~BRecord()
  97. {
  98.     detach();
  99.  
  100.     recdef *ro  = (recdef *)recobj;
  101.  
  102.     if (ro)
  103.     {
  104.         if (ro->handleCnt)
  105.         {
  106.             delete [] ro->recblb;
  107.             ro->recblb = NULL;
  108.         }
  109.         delete ro;
  110.         ro = NULL;
  111.     }
  112. }
  113.  
  114. // Delete the record's association with the cursor.
  115.  
  116. Retcode BRecord::detach()
  117. {
  118.     curdef *co;
  119.     recdef *ro;
  120.  
  121.     if (!recH)
  122.     {
  123.         return lastError = DBIERR_INVALIDHNDL;
  124.     }
  125.  
  126.     if (curH == 0)
  127.     {
  128.         return lastError = PXERR_RECNOTATT;
  129.     }
  130.  
  131.     co = (curdef *)curH->curobj;
  132.     ro = (recdef *)recobj;
  133.  
  134.     // Mark BLOB status as closed. The resources allocated for all
  135.     // BLOBs will be freed by the Paradox Engine with a RecBufClose call.
  136.  
  137.     for (int i=0; i < ro->handleCnt; i++)
  138.     {
  139.         if (ro->recblb[i].blbRecH == recH)
  140.         {
  141.             ro->recblb[i].state = blbClosed;
  142.             lastError = DbiFreeBlob(curH->tabH, recH, 0);
  143.             if (lastError != DBIERR_NONE)
  144.             {
  145.                 // If BLOB's previously closed, does not matter
  146.                 if (lastError == DBIERR_BLOBNOTOPENED)
  147.                 {
  148.                     lastError = DBIERR_NONE;
  149.                 }
  150.             }
  151.         }
  152.     }
  153.  
  154.     deleteRecord(co, this);
  155.  
  156.     delete recH;
  157.     recH = NULL;
  158.  
  159.     return lastError;
  160. }
  161.  
  162. // Attach the record object to an open cursor.
  163.  
  164. Retcode BRecord::attach(BCursor *cur)
  165. {
  166.     CURProps    curProps;
  167.  
  168.     if (recH)
  169.     {
  170.         return (lastError = PXERR_RECALREADYATT);
  171.     }
  172.  
  173.     if (!cur->isOpen)
  174.     {
  175.         return (lastError = PXERR_CURSORNOTOPEN);
  176.     }
  177.  
  178.     curH = cur;
  179.  
  180.     if ((lastError = DbiGetCursorProps(curH->tabH, &curProps))
  181.         != DBIERR_NONE)
  182.     {
  183.         return lastError;
  184.     }
  185.  
  186.     try
  187.     {
  188.         recH = new BYTE[(curProps.iRecBufSize)];
  189.     }
  190.     catch(xalloc)
  191.     {
  192.         recH = NULL;
  193.         lastError = DBIERR_NOMEMORY;
  194.         return lastError;
  195.     }
  196.  
  197.     iRecBufSize = curProps.iRecBufSize;
  198.     addRecord((curdef *)cur->curobj, this);
  199.     clear();
  200.  
  201.     return (lastError = DBIERR_NONE);
  202. }
  203.  
  204. // Clear the record buffer and set fields to "empty" values.
  205. // RecBufEmpty will fail if a BLOB is open. This function
  206. // doesn't perform operations on BLOBs.
  207.  
  208. Retcode BRecord::clear()
  209. {
  210.      if (!recH)
  211.      {
  212.           return (lastError = DBIERR_INVALIDHNDL);
  213.      }
  214.  
  215.      return (lastError = DbiInitRecord(curH->tabH, recH));
  216. }
  217.  
  218. // For the descriptor in use, return the field handle for a
  219. // given name. For generic records, the table descriptor and
  220. // record descriptor are the same.
  221.  
  222. FIELDNUMBER BRecord::getFieldNumber(const char *fldName)
  223. {
  224.     curdef *co = (curdef *)curH->curobj;
  225.     if (! recH)
  226.     {
  227.         lastError = DBIERR_INVALIDHNDL;
  228.         return 0;
  229.     }
  230.  
  231.     lastError = DBIERR_NONE;
  232.     for (int i=0; i < co->fieldCnt; i++)
  233.     {
  234.         if ( ! _fstrcmp(co->desc[i].fldName, (char far *) fldName))
  235.         {
  236.             lastError = DBIERR_NONE;
  237.             return i+1;
  238.         }
  239.     }
  240.     lastError = DBIERR_INVALIDFIELDNAME;
  241.     
  242.     return 0;
  243. }
  244.  
  245. // Get the table field number for the record. For generic
  246. // records, there is no difference between record and
  247. // table field numbers.
  248.  
  249. FIELDNUMBER BRecord::getTblFieldNumber(FIELDNUMBER fldnbr)
  250. {
  251.     lastError = DBIERR_NONE;
  252.     return fldnbr;
  253. }
  254.  
  255. // For the generic table (and record) descriptor in use,
  256. // return its field count.
  257.  
  258. int BRecord::getFieldCount()
  259. {
  260.     curdef *co = (curdef *)curH->curobj;
  261.     if (!recH)
  262.     {
  263.         lastError = DBIERR_INVALIDHNDL;
  264.         return 0;
  265.     }
  266.     lastError = DBIERR_NONE;
  267.     return co->fieldCnt;
  268. }
  269.  
  270. // Given a field handle, return a field descriptor describing
  271. // the field's name, type, length, and so on. For generic
  272. // records, use the field descriptor in the cursor. (Table and
  273. // record descriptors are the same).
  274.  
  275. Retcode BRecord::getFieldDesc(FIELDNUMBER fldnbr, FieldDesc& desc)
  276. {
  277.     curdef *co = (curdef *)curH->curobj;
  278.     if (!recH)
  279.     {
  280.         lastError = DBIERR_INVALIDHNDL;
  281.         return lastError;
  282.     }
  283.     if (fldnbr > co->fieldCnt || fldnbr < 1)
  284.     {
  285.         lastError = DBIERR_INVALIDHNDL;
  286.         return lastError;
  287.     }
  288.     desc = co->desc[fldnbr-1];
  289.  
  290.     return (lastError = DBIERR_NONE);
  291. }
  292.  
  293. // This function performs the same operation as the previous
  294. // function except this signature returns the field type,
  295. // subtype, and length.
  296.  
  297. Retcode BRecord::getFieldDesc(FIELDNUMBER fldnbr,
  298.                               PXFieldType &fldType, PXFieldSubtype &fldSubtype,
  299.                               int &fldLen)                   {
  300.     curdef *co = (curdef *)curH->curobj;
  301.     if (!recH)
  302.     {
  303.         lastError = DBIERR_INVALIDHNDL;
  304.         return lastError;
  305.     }
  306.     if (fldnbr > co->fieldCnt || fldnbr < 1)
  307.     {
  308.         lastError = DBIERR_INVALIDHNDL;
  309.         return lastError;
  310.     }
  311.     fldType    = co->desc[fldnbr-1].fldType;
  312.     fldSubtype = co->desc[fldnbr-1].fldSubtype;
  313.     fldLen     = co->desc[fldnbr-1].fldLen;
  314.  
  315.     return (lastError = DBIERR_NONE);
  316. }
  317.  
  318. // Copy the contents of a record, one field at a time, to
  319. // compatible fields of another record.
  320.  
  321. Retcode BRecord::copyTo(BRecord *destRec)
  322. {
  323.     BOOL custom = strcmp(nameOf(), "BRecord") ||
  324.                   strcmp(destRec->nameOf(), "BRecord");
  325.  
  326.     // custom record may have undefined recH and it is not fatal.
  327.     if (!recH || !destRec->recH || !_fmemcpy(destRec->recH, recH,
  328.                                              iRecBufSize))
  329.     {
  330.         if (!custom)                       // See the BRECORD.H file.
  331.         {
  332.             return lastError = DBIERR_INVALIDHNDL;
  333.         }
  334.     }
  335.  
  336.     // Register the fact that the BLOBs in the destRec are now closed.
  337.  
  338.     recdef *ro = (recdef *)destRec->recobj;
  339.     for (int i=0;i < ro->handleCnt; i++)
  340.     {
  341.         if (ro->recblb[i].blbRecH == destRec->recH)
  342.         {
  343.             ro->recblb[i].state = blbClosed;
  344.             lastError = DbiFreeBlob(curH->tabH, recH, 0);
  345.             if (lastError != DBIERR_NONE)
  346.             {
  347.                 // If BLOB's previously closed, does not matter
  348.                 if (lastError == DBIERR_BLOBNOTOPENED)
  349.                 {
  350.                     lastError = DBIERR_NONE;
  351.                 }
  352.             }
  353.         }
  354.     }
  355.  
  356.     // If either the source or the destination record is a custom record,
  357.     // transfer values to or from custom record fields, one field at a time.
  358.  
  359.     if (custom)
  360.     {
  361.         char *buf;
  362.         try
  363.         {
  364.             buf = new char[256];
  365.         }
  366.         catch(xalloc)
  367.         {
  368.             return (lastError = DBIERR_NOMEMORY);
  369.         }
  370.  
  371.         Retcode         ret;
  372.         PXFieldType     fldType1, fldType2;
  373.         PXFieldSubtype  fldSubtype;
  374.         int             fldLen1, fldLen2;
  375.         BOOL            fNull;
  376.  
  377.         int cnt = destRec->getFieldCount();
  378.         for (int i=1; i <= cnt; i++)
  379.         {
  380.             if (isNull(i))
  381.             {
  382.                 destRec->setNull(i);
  383.                 continue;
  384.             }
  385.             destRec->clearNull(i);
  386.             getFieldDesc(i,fldType1,fldSubtype,fldLen1);
  387.             destRec->getFieldDesc(i,fldType2,fldSubtype,fldLen2);
  388.             if (fldType2 == fldBlob)
  389.             {
  390.                 continue;                     // BLOB handling is separate.
  391.             }
  392.  
  393.             if ((ret = getField(i, (void *) buf, 255, fNull)) == DBIERR_NONE)
  394.             {
  395.                 if (fldType1 != fldType2)
  396.                 {
  397.                     ret = convertFld((void *)buf,fldType1, fldLen1,
  398.                                      (void *)buf,fldType2, fldLen2);
  399.                     if (ret == DBIERR_NONE)
  400.                     {
  401.                         ret = destRec->putField(i, (void *) buf);
  402.                     }
  403.                 }
  404.                 if (ret)
  405.                 {
  406.                     delete buf;
  407.                     buf = NULL;
  408.                     return (lastError = ret);
  409.                 }
  410.             }
  411.         }
  412.         delete buf;
  413.         buf = NULL;
  414.     }
  415.     return (lastError = DBIERR_NONE);
  416. }
  417.  
  418. //  Copy the contents of srcRec, one field at a time, to compatible
  419. //  fields in this record.
  420.  
  421. Retcode BRecord::copyFrom(BRecord *srcRec)
  422. {
  423.     if (!recH ||!srcRec->recH)
  424.     {
  425.         lastError = DBIERR_INVALIDHNDL;
  426.     }
  427.  
  428.     return (lastError = srcRec->copyTo(this));
  429. }
  430.  
  431. // Obtain values for fields of a generic record; store the
  432. // field as a character string regardless of its base type.
  433.  
  434. Retcode BRecord::getField(FIELDNUMBER fldnbr, char *buf,
  435.                           int bufLen, BOOL& fNull)
  436. {
  437.     PXFieldType    fldType;
  438.     PXFieldSubtype fldSubtype;
  439.     int            fldLen;
  440.  
  441.     if ((lastError = getField(fldnbr, (void *) buf, bufLen, fNull))
  442.         != DBIERR_NONE)
  443.     {
  444.         return lastError;
  445.     }
  446.     if (fNull)
  447.     {
  448.         strcpy(buf, "");
  449.         return (lastError = DBIERR_NONE);
  450.     }
  451.  
  452.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  453.  
  454.     return (lastError = convertFld((void *)buf, fldType, fldLen,
  455.                                    (void *)buf, fldChar, bufLen));
  456. }
  457.  
  458. // Get the field's value in its native format and return a pointer to
  459. // the value as a void pointer.
  460.  
  461. Retcode BRecord::getField(FIELDNUMBER fldnbr, void *buf,
  462.                           int bufLen, BOOL& fNull)
  463. {
  464.     BDate       *dt = (BDate *)buf;
  465.     BTime       *tm = (BTime *)buf;
  466.     BTimeStamp  *ts = (BTimeStamp *)buf;
  467.     UINT16      m,d;
  468.     INT16       y;
  469.     UINT16      h;
  470.     UINT16      min;
  471.     UINT16      ms;
  472.     curdef      *co = (curdef *)curH->curobj;
  473.     UINT32      n;
  474.     pCHAR       ps = (pCHAR) buf;   
  475.  
  476.     if (!recH)
  477.     {
  478.         return (lastError = DBIERR_INVALIDHNDL);
  479.     }
  480.  
  481.     if (fldnbr > co->fieldCnt || fldnbr < 1)
  482.     {
  483.         return (lastError = DBIERR_INVALIDHNDL);
  484.     }
  485.     FieldDesc far &desc = co->desc[fldnbr-1];
  486.  
  487.     switch (desc.fldType)
  488.     {
  489.         case fldChar:
  490.         case fldCharIdapi:
  491.         case fldVarBytes:
  492.             if (desc.fldLen > bufLen ) //? Len (max) of fld > buffer
  493.             {
  494.                 lastError = DBIERR_BUFFTOOSMALL;
  495.                 return lastError;
  496.             }
  497.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf,
  498.                                     &fNull);
  499.             if (fNull)
  500.             {
  501.                 strcpy((char *)buf, "");
  502.                 return (lastError = DBIERR_NONE);
  503.             }
  504.             return lastError;
  505.         case fldBool:
  506.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf,
  507.                                     &fNull);
  508.             if (fNull)
  509.             {
  510.                 *(BOOL *)buf = FALSE;
  511.                 return (lastError = DBIERR_NONE);
  512.             }
  513.             return lastError;
  514.         case fldBlob :
  515.             openBlobRead(fldnbr);
  516.             if (lastError != DBIERR_NONE)
  517.             {
  518.                 return (lastError);
  519.             }
  520.  
  521.             n = getBlobSize( fldnbr ) + 1; //Incl. required term. null
  522.             if (lastError != DBIERR_NONE)
  523.             {
  524.                 return lastError;
  525.             }
  526.  
  527.             //? Blob smaller than alloc buf
  528.             if (n < bufLen)
  529.             {
  530.                 bufLen = (int)n;
  531.             }
  532.  
  533.             //Leave rm for term. null
  534.             getBlob(fldnbr, bufLen - 1, 0, buf);
  535.             if (lastError != DBIERR_NONE)
  536.             {
  537.                 return lastError;
  538.             }
  539.  
  540.             *(ps + bufLen - 1) = '\0';
  541.  
  542.             //941103 only FALSE does DbiFreeBlob!
  543.             closeBlob(fldnbr, FALSE);
  544.             if (lastError != DBIERR_NONE)
  545.             {
  546.                 return lastError;
  547.             }
  548.  
  549.             //? Blob larger than alloc buf
  550.             if ( n > bufLen )
  551.             {
  552.                 lastError = DBIERR_BUFFTOOSMALL;
  553.             }
  554.  
  555.             return lastError;
  556.         case fldShort:
  557.         case fldUInt16:
  558.             if (bufLen < sizeof(INT16))
  559.             {
  560.                 return (lastError = DBIERR_BUFFTOOSMALL);
  561.             }
  562.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf, &fNull);
  563.             if (fNull)
  564.             {
  565.                 *(INT16 *)buf = 0;
  566.                 return (lastError = DBIERR_NONE);
  567.             }
  568.             return lastError;
  569.         case fldLong:
  570.         case fldUInt32:
  571.             if (bufLen < sizeof(INT32))
  572.             {
  573.                 return (lastError = DBIERR_BUFFTOOSMALL);
  574.             }
  575.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf, &fNull);
  576.             if (fNull)
  577.             {
  578.                 *(INT32 *)buf = 0L;
  579.                 return (lastError = DBIERR_NONE);
  580.             }
  581.             return lastError;
  582.         case fldDouble:
  583.             if (bufLen < sizeof(FLOAT))
  584.             {
  585.                 return (lastError = DBIERR_BUFFTOOSMALL);
  586.             }
  587.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf, &fNull);
  588.             if (fNull)
  589.             {
  590.                 *(FLOAT *)buf = 0L;
  591.                 return (lastError = DBIERR_NONE);
  592.             }
  593.             return lastError;
  594.         case fldDate:
  595.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf, &fNull);
  596.             if (fNull)
  597.             {
  598.                 memset(buf, 0, sizeof(BDate));
  599.                 return (lastError = DBIERR_NONE);
  600.             }
  601.             if (lastError == DBIERR_NONE)
  602.             {
  603.                 DbiDateDecode(*((pDATE)buf), &m, &d, &y);
  604.                 dt->month = m;
  605.                 dt->day = d;
  606.                 dt->year = y;
  607.             }
  608.             return lastError;
  609.         case fldTime:
  610.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf, &fNull);
  611.             if (fNull)
  612.             {
  613.                 memset(buf, 0, sizeof(BTime));
  614.                 return (lastError = DBIERR_NONE);
  615.             }
  616.             if (lastError == DBIERR_NONE)
  617.             {
  618.                 DbiTimeDecode(*((pTIME)buf), &h, &min, &ms);
  619.                 tm->hour = h;
  620.                 tm->minute = min;
  621.                 tm->milSec = ms;
  622.             }
  623.             return lastError;
  624.         case fldTimeStamp:
  625.             lastError = DbiGetField(curH->tabH, fldnbr, recH, (pBYTE)buf, &fNull);
  626.             if ((fNull) && (lastError != DBIERR_NONE))
  627.             {
  628.                 memset(buf, 0, sizeof(BTime));
  629.                 return (lastError = DBIERR_NONE);
  630.             }
  631.             if (lastError == DBIERR_NONE)
  632.             {
  633.                 DATE tempDate;
  634.                 TIME tempTime;
  635.                 
  636.                 DbiTimeStampDecode(*((pTIMESTAMP)buf), &tempDate, &tempTime); 
  637.  
  638.                 DbiDateDecode(tempDate, &m, &d, &y);
  639.                 ts->BDay.month = m;
  640.                 ts->BDay.day = d;
  641.                 ts->BDay.year = y;
  642.  
  643.                 DbiTimeDecode(tempTime, &h, &min, &ms);
  644.                 ts->BHour.hour = h;
  645.                 ts->BHour.minute = min;
  646.                 ts->BHour.milSec = ms;                   
  647.             }
  648.             return lastError;
  649.         case fldBcd:
  650.             lastError = DBIERR_NOTSUPPORTED;
  651.             return lastError;
  652.         default:
  653.             return (lastError = PXERR_TYPEMISMATCH);
  654.     }   
  655. }
  656.  
  657. Retcode BRecord::getField(FIELDNUMBER fldnbr, double& val, BOOL& fNull)
  658. {
  659.     PXFieldType    fldType;
  660.     PXFieldSubtype fldSubtype;
  661.     int            fldLen;
  662.     char           buf[31];
  663.  
  664.     if ((lastError = getField(fldnbr, (void *) buf, 30, fNull)) != DBIERR_NONE)
  665.     {
  666.         return lastError;
  667.     }
  668.  
  669.     if (fNull)
  670.     {
  671.         val = 0;
  672.         return (lastError = DBIERR_NONE);
  673.     }
  674.  
  675.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  676.  
  677.     return (lastError = convertFld((void *)buf,  fldType,  30,
  678.                                    (void *) &val, fldDouble, sizeof(double)));
  679. }
  680.  
  681. Retcode BRecord::getField(FIELDNUMBER fldnbr, INT16& val, BOOL& fNull)
  682. {
  683.     PXFieldType    fldType;
  684.     PXFieldSubtype fldSubtype;
  685.     int            fldLen;
  686.     char           buf[31];
  687.  
  688.     if ((lastError = getField(fldnbr, (void *)buf, 30, fNull)) != DBIERR_NONE)
  689.     {
  690.         return lastError;
  691.     }
  692.  
  693.     if (fNull)
  694.     {
  695.         val = 0;
  696.         return (lastError = DBIERR_NONE);
  697.     }
  698.  
  699.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  700.  
  701.     return (lastError = convertFld((void *)buf, fldType, 30,
  702.                                    (void *) &val, fldShort, sizeof(INT16)));
  703. }
  704.  
  705. Retcode BRecord::getField(FIELDNUMBER fldnbr, INT32& val, BOOL& fNull)
  706. {
  707.     PXFieldType    fldType;
  708.     PXFieldSubtype fldSubtype;
  709.     int            fldLen;
  710.     char           buf[31];
  711.  
  712.     if ((lastError = getField(fldnbr, (void *) buf, 30, fNull)) != DBIERR_NONE)
  713.     {
  714.         return lastError;
  715.     }
  716.  
  717.     if (fNull)
  718.     {
  719.         val = 0;
  720.         return (lastError = DBIERR_NONE);
  721.     }
  722.  
  723.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  724.  
  725.     return (lastError = convertFld((void *)buf, fldType, 30,
  726.                                    (void *) &val, fldLong, sizeof(INT32)));
  727. }
  728.  
  729. Retcode BRecord::getField(FIELDNUMBER fldnbr, UINT16& val, BOOL& fNull)
  730. {
  731.     PXFieldType    fldType;
  732.     PXFieldSubtype fldSubtype;
  733.     int            fldLen;
  734.     char           buf[31];
  735.  
  736.     if ((lastError = getField(fldnbr, (void *) buf, 30, fNull)) != DBIERR_NONE)
  737.     {
  738.         return lastError;
  739.     }
  740.  
  741.     if (fNull)
  742.     {
  743.         val = 0;
  744.         return (lastError = DBIERR_NONE);
  745.     }
  746.  
  747.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  748.  
  749.     return (lastError = convertFld((void *)buf, fldType, 30,
  750.                                    (void *) &val, fldUInt16, sizeof(UINT16)));
  751. }
  752.  
  753. Retcode BRecord::getField(FIELDNUMBER fldnbr, UINT32& val, BOOL& fNull)
  754. {
  755.     PXFieldType    fldType;
  756.     PXFieldSubtype fldSubtype;
  757.     int            fldLen;
  758.     char           buf[31];
  759.  
  760.     if ((lastError = getField(fldnbr, (void *) buf, 30, fNull)) != DBIERR_NONE)
  761.     {
  762.         return lastError;
  763.     }
  764.  
  765.     if (fNull)
  766.     {
  767.         val = 0;
  768.         return (lastError = DBIERR_NONE);
  769.     }
  770.  
  771.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  772.  
  773.     return (lastError = convertFld((void *)buf, fldType, 30,
  774.                                    (void *) &val, fldLong, sizeof(UINT32)));
  775. }
  776.  
  777. Retcode BRecord::getField(FIELDNUMBER fldnbr, FMTBcd& val, BOOL& fNull)
  778. {
  779.     PXFieldType    fldType;
  780.     PXFieldSubtype fldSubtype;
  781.     int            fldLen;
  782.     char           buf[51];
  783.  
  784.     if ((lastError = getField(fldnbr, (void *) buf, 50, fNull)) != DBIERR_NONE)
  785.     {
  786.         return lastError;
  787.     }
  788.  
  789.     if (fNull)
  790.     {
  791.         memset(&val, 0, sizeof(FMTBcd)); 
  792.         return (lastError = DBIERR_NONE);
  793.     }
  794.  
  795.     getFieldDesc(fldnbr, fldType, fldSubtype, fldLen);
  796.  
  797.     return (lastError = convertFld((void *)buf, fldType, 30,
  798.                                    (void *) &val, fldBcd, sizeof(FMTBcd)));
  799. }
  800.  
  801. Retcode BRecord::getField(FIELDNUMBER fldnbr, BDate& val, BOOL& fNull)
  802. {
  803.     PXFieldType    fldType;
  804.     PXFieldSubtype fldSubtype;
  805.     int            fldLen;
  806.     char           buf[31];
  807.  
  808.     if ((lastError = getField(fldnbr, (void *) buf, 30, fNull)) != DBIERR_NONE)
  809.     {
  810.         return lastError;
  811.     }
  812.  
  813.     if (fNull)
  814.     {
  815.         memset((void *)&val, 0, sizeof(BDate));
  816.         return (lastError = DBIERR_NONE);
  817.     }
  818.  
  819.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  820.  
  821.     return (lastError = convertFld((void *)buf, fldType, 30,
  822.                                    (void *) &val, fldDate, sizeof(BDate)));
  823. }
  824.  
  825. Retcode BRecord::getField(FIELDNUMBER fldnbr, BTime& val, BOOL& fNull)
  826. {
  827.     PXFieldType    fldType;
  828.     PXFieldSubtype fldSubtype;
  829.     int            fldLen;
  830.     char           buf[31];
  831.  
  832.     if ((lastError = getField(fldnbr, (void *) buf, 30, fNull)) != DBIERR_NONE)
  833.     {
  834.         return lastError;
  835.     }
  836.  
  837.     if (fNull)
  838.     {
  839.         memset((void *)&val, 0, sizeof(BDate));
  840.         return (lastError = DBIERR_NONE);
  841.     }
  842.  
  843.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  844.  
  845.     return (lastError = convertFld((void *)buf, fldType, 30,
  846.                                    (void *) &val, fldTime, sizeof(BTime)));
  847. }
  848.  
  849. Retcode BRecord::getField(FIELDNUMBER fldnbr, BTimeStamp& val, BOOL& fNull)
  850. {
  851.     PXFieldType    fldType;
  852.     PXFieldSubtype fldSubtype;
  853.     int            fldLen;
  854.     char           buf[61];
  855.  
  856.     if ((lastError = getField(fldnbr, (void *) buf, 60, fNull)) != DBIERR_NONE)
  857.     {
  858.         return lastError;
  859.     }
  860.  
  861.     if (fNull)
  862.     {
  863.         memset((void *)&val, 0, sizeof(BDate));
  864.         return (lastError = DBIERR_NONE);
  865.     }
  866.  
  867.     getFieldDesc(fldnbr,fldType,fldSubtype,fldLen);
  868.  
  869.     return (lastError = convertFld((void *)buf, fldType, 60,
  870.                                    (void *) &val, fldTimeStamp,
  871.                                    sizeof(BTimeStamp)));
  872. }
  873.  
  874. Retcode BRecord::getField(char *fldName, char *buf, int bufLen, BOOL& fNull)
  875. {
  876.     FIELDNUMBER fld;
  877.     if ((fld = getFieldNumber(fldName)) == 0)
  878.     {
  879.         return lastError;
  880.     }
  881.  
  882.     return (getField(fld, buf, bufLen,fNull));
  883. }
  884.  
  885. Retcode BRecord::getField(char *fldName, void *buf, int bufLen, BOOL& fNull)
  886. {
  887.     FIELDNUMBER fld;
  888.     if ((fld = getFieldNumber(fldName)) == 0)
  889.     {
  890.         return lastError;
  891.     }
  892.  
  893.     return (getField(fld, buf, bufLen, fNull));
  894. }
  895.  
  896. Retcode BRecord::getField(char *fldName, double& val, BOOL& fNull)
  897. {
  898.     FIELDNUMBER fld;
  899.  
  900.     if ((fld = getFieldNumber(fldName)) == 0)
  901.     {
  902.         return lastError;
  903.     }
  904.  
  905.     return (getField(fld, val, fNull));
  906. }
  907.  
  908. Retcode BRecord::getField(char *fldName, INT16& val, BOOL& fNull)
  909. {
  910.     FIELDNUMBER fld;
  911.  
  912.     if ((fld = getFieldNumber(fldName)) == 0)
  913.     {
  914.         return lastError;
  915.     }
  916.  
  917.     return (getField(fld, val, fNull));
  918. }
  919.  
  920. Retcode BRecord::getField(char *fldName, INT32& val, BOOL& fNull)
  921. {
  922.     FIELDNUMBER fld;
  923.  
  924.     if ((fld = getFieldNumber(fldName)) == 0)
  925.     {
  926.         return lastError;
  927.     }
  928.  
  929.     return (getField(fld, val, fNull));
  930. }
  931.  
  932. Retcode BRecord::getField(char *fldName, UINT16& val, BOOL& fNull)
  933. {
  934.     FIELDNUMBER fld;
  935.  
  936.     if ((fld = getFieldNumber(fldName)) == 0)
  937.     {
  938.         return lastError;
  939.     }
  940.  
  941.     return (getField(fld, val, fNull));
  942. }
  943.  
  944. Retcode BRecord::getField(char *fldName, UINT32& val, BOOL& fNull)
  945. {
  946.     FIELDNUMBER fld;
  947.  
  948.     if ((fld = getFieldNumber(fldName)) == 0)
  949.     {
  950.         return lastError;
  951.     }
  952.  
  953.     return (getField(fld, val, fNull));
  954. }
  955.  
  956. Retcode BRecord::getField(char *fldName, FMTBcd& val, BOOL& fNull)
  957. {
  958.     FIELDNUMBER fld;
  959.  
  960.     if ((fld = getFieldNumber(fldName)) == 0)
  961.     {
  962.         return lastError;
  963.     }
  964.  
  965.     return (getField(fld, val, fNull));
  966. }
  967.  
  968. Retcode BRecord::getField(char *fldName, BDate& val, BOOL& fNull)
  969. {
  970.     FIELDNUMBER fld;
  971.  
  972.     if ((fld = getFieldNumber(fldName)) == 0)
  973.     {
  974.         return lastError;
  975.     }
  976.  
  977.     return (getField(fld, val, fNull));
  978. }
  979.  
  980. Retcode BRecord::getField(char *fldName, BTime& val, BOOL& fNull)
  981. {
  982.     FIELDNUMBER fld;
  983.  
  984.     if ((fld = getFieldNumber(fldName)) == 0)
  985.     {
  986.         return lastError;
  987.     }
  988.  
  989.     return (getField(fld, val, fNull));
  990. }
  991.  
  992. Retcode BRecord::getField(char *fldName, BTimeStamp& val, BOOL& fNull)
  993. {
  994.     FIELDNUMBER fld;
  995.  
  996.     if ((fld = getFieldNumber(fldName)) == 0)
  997.     {
  998.         return lastError;
  999.     }
  1000.  
  1001.     return (getField(fld, val, fNull));
  1002. }
  1003.  
  1004. // The following putField functions provide counterpart
  1005. // operations to getField functions.
  1006.  
  1007. Retcode BRecord::putField(FIELDNUMBER fldnbr, const char *buf)
  1008. {
  1009.     PXFieldType    fldType;
  1010.     PXFieldSubtype fldSubtype;
  1011.     int            fldLen;
  1012.     char           tempBuf[31];
  1013.  
  1014.     int len = strlen(buf);
  1015.  
  1016.     if (!recH)
  1017.     {
  1018.         return (lastError = DBIERR_INVALIDHNDL);
  1019.     }
  1020.  
  1021.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1022.     {
  1023.         return (lastError = DBIERR_INVALIDHNDL);
  1024.     }
  1025.  
  1026.     if (fldType == fldBlob && fldSubtype == fldstMemo)
  1027.     {
  1028.         openBlobWrite(fldnbr, 0, FALSE);
  1029.         if (lastError != DBIERR_NONE)
  1030.         {
  1031.             return lastError;
  1032.         }
  1033.  
  1034.         //Term-null not incl.
  1035.         putBlob(fldnbr, strlen(buf), 0, (void*) buf);
  1036.         if (lastError != DBIERR_NONE)
  1037.         {
  1038.             return lastError;
  1039.         }
  1040.  
  1041.         closeBlob(fldnbr);
  1042.         return lastError;
  1043.     }  
  1044.     else if ((fldType != fldChar) && (fldType != fldCharIdapi))
  1045.     {
  1046.         if ((lastError = convertFld((void *)buf, fldChar, len,
  1047.                                     (void *)tempBuf,fldType, 30))
  1048.             != DBIERR_NONE)
  1049.         {
  1050.             return lastError;
  1051.         }
  1052.  
  1053.         return (lastError = putField(fldnbr, (void *)tempBuf));
  1054.     }
  1055.     else
  1056.     {
  1057.         return (lastError = putField(fldnbr, (void *)buf));
  1058.     }
  1059. }
  1060.  
  1061. Retcode BRecord::putField(FIELDNUMBER fldnbr, const void *buf)
  1062. {
  1063.     BDate       *dt = (BDate *)buf;
  1064.     BTime       *tm = (BTime *)buf;
  1065.     BTimeStamp  *ts = (BTimeStamp *)buf;
  1066.     curdef      *co = (curdef *)curH->curobj;
  1067.  
  1068.     if (!recH)
  1069.     {
  1070.         return (lastError = DBIERR_INVALIDHNDL);
  1071.     }
  1072.  
  1073.     if (fldnbr > co->fieldCnt || fldnbr < 1)
  1074.     {
  1075.         return (lastError = DBIERR_INVALIDHNDL);
  1076.     }
  1077.  
  1078.     FieldDesc far &desc = co->desc[fldnbr-1];
  1079.  
  1080.     switch (desc.fldType)
  1081.     {
  1082.         case fldChar:
  1083.         case fldCharIdapi:
  1084.         case fldBool:
  1085.         case fldVarBytes:
  1086.         case fldShort:
  1087.         case fldUInt16:
  1088.         case fldUInt32:
  1089.         case fldDouble:
  1090.         case fldLong:
  1091.             lastError = DbiPutField(curH->tabH, fldnbr, recH, (pBYTE)buf);
  1092.             return lastError;
  1093.         case fldDate:
  1094.             if ((lastError = DbiDateEncode((UINT16)dt->month, (UINT16)dt->day,
  1095.                                            (int)dt->year,  (pDATE)buf))
  1096.                  == DBIERR_NONE)
  1097.             {
  1098.                 lastError = DbiPutField(curH->tabH, fldnbr, recH, (pBYTE)buf);
  1099.             }
  1100.             return lastError;
  1101.         case fldTime:
  1102.             if ((lastError = DbiTimeEncode((UINT16)tm->hour, (UINT16)tm->minute,
  1103.                                            (UINT16)tm->milSec,  (pDATE)buf))
  1104.                  == DBIERR_NONE)
  1105.             {
  1106.                 lastError = DbiPutField(curH->tabH, fldnbr, recH, (pBYTE)buf);
  1107.             }
  1108.             return lastError;
  1109.         case fldTimeStamp:
  1110.             DATE   tempDate;
  1111.             TIME   tempTime;
  1112.             
  1113.             if ((lastError = DbiDateEncode((UINT16)ts->BDay.month,
  1114.                                            (UINT16)ts->BDay.day,
  1115.                                            (int)ts->BDay.year,  &tempDate))
  1116.                  != DBIERR_NONE)
  1117.             {
  1118.                 return lastError;
  1119.             }
  1120.             if ((lastError = DbiTimeEncode((UINT16)ts->BHour.hour,
  1121.                                            (UINT16)ts->BHour.minute,
  1122.                                            (UINT16)ts->BHour.milSec,
  1123.                                            &tempTime))
  1124.                  != DBIERR_NONE)
  1125.             {
  1126.                 return lastError;
  1127.             }
  1128.             if ((lastError = DbiTimeStampEncode(tempDate, tempTime,
  1129.                                                 (pTIMESTAMP)buf))
  1130.                  == DBIERR_NONE)
  1131.             {
  1132.                 lastError = DbiPutField(curH->tabH, fldnbr, recH, (pBYTE)buf);
  1133.             }
  1134.             return lastError;
  1135.         case fldBcd:
  1136.             lastError = DBIERR_NOTSUPPORTED;
  1137.             return lastError;
  1138.         default:
  1139.             return (lastError = PXERR_TYPEMISMATCH);
  1140.     }
  1141. }
  1142.  
  1143. Retcode BRecord::putField(FIELDNUMBER fldnbr, double val)
  1144. {
  1145.     PXFieldType    fldType;
  1146.     PXFieldSubtype fldSubtype;
  1147.     int            fldLen;
  1148.     char           buf[31];
  1149.  
  1150.     if (!recH)
  1151.     {
  1152.         return (lastError = DBIERR_INVALIDHNDL);
  1153.     }
  1154.  
  1155.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1156.     {
  1157.         return (lastError = DBIERR_INVALIDHNDL);
  1158.     }
  1159.  
  1160.     if ((lastError = convertFld((void *)&val, fldDouble, sizeof(double),
  1161.                                 (void *)buf,fldType, 30)) != DBIERR_NONE)
  1162.     {
  1163.         return lastError;
  1164.     }
  1165.  
  1166.     return (lastError = putField(fldnbr, (void *) buf));
  1167. }
  1168.  
  1169. Retcode BRecord::putField(FIELDNUMBER fldnbr, INT16 val)
  1170. {
  1171.     PXFieldType    fldType;
  1172.     PXFieldSubtype fldSubtype;
  1173.     int            fldLen;
  1174.     char           buf[31];
  1175.  
  1176.     if (!recH)
  1177.     {
  1178.         return (lastError = DBIERR_INVALIDHNDL);
  1179.     }
  1180.  
  1181.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1182.     {
  1183.         return (lastError = DBIERR_INVALIDHNDL);
  1184.     }
  1185.  
  1186.     if ((lastError = convertFld((void *)&val, fldShort, sizeof(short),
  1187.                                 (void *)buf,fldType, 30)) != DBIERR_NONE)
  1188.     {
  1189.         return lastError;
  1190.     }
  1191.  
  1192.     return (lastError = putField(fldnbr, (void *) buf));
  1193. }
  1194.  
  1195. Retcode BRecord::putField(FIELDNUMBER fldnbr, INT32 val)
  1196. {
  1197.     PXFieldType    fldType;
  1198.     PXFieldSubtype fldSubtype;
  1199.     int            fldLen;
  1200.     char           buf[31];
  1201.  
  1202.     if (!recH)
  1203.     {
  1204.         return (lastError = DBIERR_INVALIDHNDL);
  1205.     }
  1206.  
  1207.     if (getFieldDesc(fldnbr, fldType, fldSubtype, fldLen))
  1208.     {
  1209.         return (lastError = DBIERR_INVALIDHNDL);
  1210.     }
  1211.  
  1212.     if ((lastError = convertFld((void *)&val, fldLong, sizeof(long),
  1213.                                 (void *)buf, fldType, 30)) != DBIERR_NONE)
  1214.     {
  1215.         return lastError;
  1216.     }
  1217.  
  1218.     return (lastError = putField(fldnbr, (void *) buf));
  1219. }
  1220.  
  1221. Retcode BRecord::putField(FIELDNUMBER fldnbr, UINT16 val)
  1222. {
  1223.     PXFieldType    fldType;
  1224.     PXFieldSubtype fldSubtype;
  1225.     int            fldLen;
  1226.     char           buf[31];
  1227.  
  1228.     if (!recH)
  1229.     {
  1230.         return (lastError = DBIERR_INVALIDHNDL);
  1231.     }
  1232.  
  1233.     if (getFieldDesc(fldnbr, fldType, fldSubtype, fldLen))
  1234.     {
  1235.         return (lastError = DBIERR_INVALIDHNDL);
  1236.     }
  1237.  
  1238.     if ((lastError = convertFld((void *)&val, fldUInt16, sizeof(int),
  1239.                                 (void *)buf, fldType, 30)) != DBIERR_NONE)
  1240.     {
  1241.         return lastError;
  1242.     }
  1243.  
  1244.     return (lastError = putField(fldnbr, (void *) buf));
  1245. }
  1246.  
  1247. Retcode BRecord::putField(FIELDNUMBER fldnbr, UINT32 val)
  1248. {
  1249.     PXFieldType    fldType;
  1250.     PXFieldSubtype fldSubtype;
  1251.     int            fldLen;
  1252.     char           buf[31];
  1253.  
  1254.     if (!recH)
  1255.     {
  1256.         return (lastError = DBIERR_INVALIDHNDL);
  1257.     }
  1258.  
  1259.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1260.     {
  1261.         return (lastError = DBIERR_INVALIDHNDL);
  1262.     }
  1263.  
  1264.     if ((lastError = convertFld((void *)&val, fldLong, sizeof(long),
  1265.                                 (void *)buf, fldType, 30)) != DBIERR_NONE)
  1266.     {
  1267.         return lastError;
  1268.     }
  1269.  
  1270.     return (lastError = putField(fldnbr, (void *) buf));
  1271. }
  1272.  
  1273. Retcode BRecord::putField(FIELDNUMBER fldnbr, FMTBcd val)
  1274. {
  1275.     PXFieldType    fldType;
  1276.     PXFieldSubtype fldSubtype;
  1277.     int            fldLen;
  1278.     char           buf[31];
  1279.  
  1280.     if (!recH)
  1281.     {
  1282.         return (lastError = DBIERR_INVALIDHNDL);
  1283.     }
  1284.  
  1285.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1286.     {
  1287.         return (lastError = DBIERR_INVALIDHNDL);
  1288.     }
  1289.  
  1290.     if ((lastError = convertFld((void *)&val, fldBcd, sizeof(FMTBcd),
  1291.                                 (void *)buf, fldType, 30)) != DBIERR_NONE)
  1292.     {
  1293.         return lastError;
  1294.     }
  1295.  
  1296.     return (lastError = putField(fldnbr, (void *) buf));
  1297. }
  1298.  
  1299. Retcode BRecord::putField(FIELDNUMBER fldnbr, const BDate& val)
  1300. {
  1301.     PXFieldType    fldType;
  1302.     PXFieldSubtype fldSubtype;
  1303.     int            fldLen;
  1304.     char           buf[31];
  1305.  
  1306.     if (!recH)
  1307.     {
  1308.         return (lastError = DBIERR_INVALIDHNDL);
  1309.     }
  1310.  
  1311.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1312.     {
  1313.         return (lastError = DBIERR_INVALIDHNDL);
  1314.     }
  1315.  
  1316.     if ((lastError = convertFld((void *)&val, fldDate, sizeof(BDate),
  1317.                                 (void *)buf,fldType, 30)) != DBIERR_NONE)
  1318.     {
  1319.         return lastError;
  1320.     }
  1321.  
  1322.     return (lastError = putField(fldnbr, (void *) buf));
  1323. }
  1324.  
  1325. Retcode BRecord::putField(FIELDNUMBER fldnbr, const BTime& val)
  1326. {
  1327.     PXFieldType    fldType;
  1328.     PXFieldSubtype fldSubtype;
  1329.     int            fldLen;
  1330.     char           buf[31];
  1331.  
  1332.     if (!recH)
  1333.     {
  1334.         return (lastError = DBIERR_INVALIDHNDL);
  1335.     }
  1336.  
  1337.     if (getFieldDesc(fldnbr,fldType,fldSubtype,fldLen))
  1338.     {
  1339.         return (lastError = DBIERR_INVALIDHNDL);
  1340.     }
  1341.  
  1342.     if ((lastError = convertFld((void *)&val, fldTime, sizeof(BTime),
  1343.                                 (void *)buf, fldType, 30)) != DBIERR_NONE)
  1344.     {
  1345.         return lastError;
  1346.     }
  1347.  
  1348.     return (lastError = putField(fldnbr, (void *) buf));
  1349. }
  1350.  
  1351. Retcode BRecord::putField(FIELDNUMBER fldnbr, const BTimeStamp& val)
  1352. {
  1353.     PXFieldType    fldType;
  1354.     PXFieldSubtype fldSubtype;
  1355.     int            fldLen;
  1356.     char           buf[51];
  1357.  
  1358.     if (!recH)
  1359.     {
  1360.         return (lastError = DBIERR_INVALIDHNDL);
  1361.     }
  1362.  
  1363.     if (getFieldDesc(fldnbr, fldType, fldSubtype, fldLen))
  1364.     {
  1365.         return (lastError = DBIERR_INVALIDHNDL);
  1366.     }
  1367.  
  1368.     if ((lastError = convertFld((void *)&val, fldTimeStamp, sizeof(BTimeStamp),
  1369.                                 (void *)buf, fldType, 30)) != DBIERR_NONE)
  1370.     {
  1371.         return lastError;
  1372.     }
  1373.  
  1374.     return (lastError = putField(fldnbr, (void *) buf));
  1375. }
  1376.  
  1377. Retcode BRecord::putField(char *fldName, const char *buf)
  1378. {
  1379.     FIELDNUMBER fld;
  1380.  
  1381.     if ((fld = getFieldNumber(fldName)) == 0)
  1382.     {
  1383.         return lastError;
  1384.     }
  1385.  
  1386.     return (putField(fld, buf));
  1387. }
  1388.  
  1389. Retcode BRecord::putField(char *fldName, const void *buf)
  1390. {
  1391.     FIELDNUMBER fld;
  1392.     if ((fld = getFieldNumber(fldName)) == 0)
  1393.     {
  1394.         return lastError;
  1395.     }
  1396.  
  1397.     return (putField(fld, buf));
  1398. }
  1399.  
  1400. Retcode BRecord::putField(char *fldName, double val)
  1401. {
  1402.     FIELDNUMBER fld;
  1403.     if ((fld = getFieldNumber(fldName)) == 0)
  1404.     {
  1405.         return lastError;
  1406.     }
  1407.  
  1408.     return (putField(fld, val));
  1409. }
  1410.  
  1411. Retcode BRecord::putField(char *fldName, INT16 val)
  1412. {
  1413.     FIELDNUMBER fld;
  1414.     if ((fld = getFieldNumber(fldName)) == 0)
  1415.     {
  1416.         return lastError;
  1417.     }
  1418.  
  1419.     return (putField(fld, val));
  1420. }
  1421.  
  1422. Retcode BRecord::putField(char *fldName, INT32 val)
  1423. {
  1424.     FIELDNUMBER fld;
  1425.  
  1426.     if ((fld = getFieldNumber(fldName)) == 0)
  1427.     {
  1428.         return lastError;
  1429.     }
  1430.  
  1431.     return (putField(fld, val));
  1432. }
  1433.  
  1434. Retcode BRecord::putField(char *fldName, UINT16 val)
  1435. {
  1436.     FIELDNUMBER fld;
  1437.  
  1438.     if ((fld = getFieldNumber(fldName)) == 0)
  1439.     {
  1440.         return lastError;
  1441.     }
  1442.  
  1443.     return (putField(fld, val));
  1444. }
  1445.  
  1446. Retcode BRecord::putField(char *fldName, UINT32 val)
  1447. {
  1448.     FIELDNUMBER fld;
  1449.  
  1450.     if ((fld = getFieldNumber(fldName)) == 0)
  1451.     {
  1452.         return lastError;
  1453.     }
  1454.  
  1455.     return (putField(fld, val));
  1456. }
  1457.  
  1458. Retcode BRecord::putField(char *fldName, FMTBcd val)
  1459. {
  1460.     FIELDNUMBER fld;
  1461.  
  1462.     if ((fld = getFieldNumber(fldName)) == 0)
  1463.     {
  1464.         return lastError;
  1465.     }
  1466.  
  1467.     return (putField(fld, val));
  1468. }
  1469.  
  1470. Retcode BRecord::putField(char *fldName, const BDate& val)
  1471. {
  1472.     FIELDNUMBER fld;
  1473.  
  1474.     if ((fld = getFieldNumber(fldName)) == 0)
  1475.     {
  1476.         return lastError;
  1477.     }
  1478.  
  1479.     return (putField(fld, val));
  1480. }
  1481.  
  1482. Retcode BRecord::putField(char *fldName, const BTime& val)
  1483. {
  1484.     FIELDNUMBER fld;
  1485.  
  1486.     if ((fld = getFieldNumber(fldName)) == 0)
  1487.     {
  1488.         return lastError;
  1489.     }
  1490.  
  1491.     return (putField(fld, val));
  1492. }
  1493.  
  1494. Retcode BRecord::putField(char *fldName, const BTimeStamp& val)
  1495. {
  1496.     FIELDNUMBER fld;
  1497.  
  1498.     if ((fld = getFieldNumber(fldName)) == 0)
  1499.     {
  1500.         return lastError;
  1501.     }
  1502.  
  1503.     return (putField(fld, val));
  1504. }
  1505.  
  1506. // Test if a field is null.
  1507.  
  1508. BOOL BRecord::isNull(FIELDNUMBER fldnbr)
  1509. {
  1510.     BOOL blank;
  1511.  
  1512.     if ((lastError = DbiGetField(curH->tabH, fldnbr, recH, NULL,
  1513.                                     &blank)) != DBIERR_NONE)
  1514.     {
  1515.         return FALSE;
  1516.     }
  1517.  
  1518.     return blank;
  1519. }
  1520.  
  1521. BOOL BRecord::isNull(const char *fldname)
  1522. {
  1523.     FIELDNUMBER fld;
  1524.  
  1525.     if ((fld = getFieldNumber(fldname)) == 0)
  1526.     {
  1527.         return FALSE;
  1528.     }
  1529.  
  1530.     return (isNull(fld));
  1531. }
  1532.  
  1533. // Set a field to blank.
  1534.  
  1535. Retcode BRecord::setNull(FIELDNUMBER fldnbr)
  1536. {
  1537.     PXFieldType    fldType;
  1538.     PXFieldSubtype fldSubtype;
  1539.     int            fldLen;
  1540.  
  1541.     if (!recH)
  1542.     {
  1543.         return (lastError = PXERR_RECNOTATT);
  1544.     }
  1545.  
  1546.     getFieldDesc(fldnbr, fldType, fldSubtype, fldLen);
  1547.  
  1548.     if (fldType != fldBlob)
  1549.     {
  1550.         lastError = DbiPutField(curH->tabH, fldnbr, recH, NULL);
  1551.     }
  1552.     else
  1553.     {
  1554.         recdef *ro = (recdef *)recobj;
  1555.  
  1556.         for (int i=0; i < ro->handleCnt; i++)
  1557.         {
  1558.             if (ro->recblb[i].fldnbr == fldnbr && !((int) ro->recblb[i].state))
  1559.             {
  1560.                 break;
  1561.             }
  1562.         }
  1563.  
  1564.         if (i == ro->handleCnt)
  1565.         {
  1566.             return lastError = PXERR_BLOBOPEN;
  1567.         }
  1568.  
  1569.         dropBlob(fldnbr);
  1570.     }
  1571.  
  1572.     return lastError;
  1573. }
  1574.  
  1575. Retcode BRecord::setNull(const char *fldName)
  1576. {
  1577.     FIELDNUMBER fld;
  1578.  
  1579.     if ((fld = getFieldNumber(fldName)) == 0)
  1580.     {
  1581.         return lastError;
  1582.     }
  1583.  
  1584.     return (setNull(fld));
  1585. }
  1586.  
  1587. Retcode BRecord::clearNull(FIELDNUMBER fldnbr)
  1588. {
  1589.     curdef *co = (curdef *)curH->curobj;
  1590.  
  1591.     if (!recH)
  1592.     {
  1593.         return (lastError = DBIERR_INVALIDHNDL);
  1594.     }
  1595.  
  1596.     if (fldnbr > co->fieldCnt || fldnbr < 1)
  1597.     {
  1598.         return (lastError = DBIERR_INVALIDHNDL);
  1599.     }
  1600.  
  1601.     return (PXERR_NOCLEARNULL);
  1602. }
  1603.  
  1604. Retcode BRecord::clearNull(const char *fldName)
  1605. {
  1606.     FIELDNUMBER fld;
  1607.  
  1608.     if ((fld = getFieldNumber(fldName)) == 0)
  1609.     {
  1610.         return lastError;
  1611.     }
  1612.  
  1613.     return (clearNull(fld));
  1614. }
  1615.  
  1616. RECORDHANDLE BRecord::getHandle()
  1617. {
  1618.  
  1619.     if (!recH)
  1620.     {
  1621.         lastError = DBIERR_INVALIDHNDL;
  1622.         return 0;
  1623.     }
  1624.  
  1625.     lastError = DBIERR_NONE;
  1626.  
  1627.     return recH;
  1628. }
  1629.  
  1630.  
  1631. // Open a BLOB for subsequent read or write operations based on mode.
  1632.  
  1633. Retcode BRecord::openBlobRead(FIELDNUMBER fldnbr, BOOL usePrivateCopy)
  1634. {
  1635.     blbdef blb;
  1636.  
  1637.     if (!recH)
  1638.     {
  1639.         return (lastError = PXERR_RECNOTATT);
  1640.     }
  1641.     
  1642.      // Use the field number of the BLOB in the table, not the
  1643.     // custom record. That way, this function does not need
  1644.     // to be duplicated in custom record classes.
  1645.  
  1646.     FIELDNUMBER tblfld = getTblFieldNumber(fldnbr);
  1647. /*
  1648.      if (usePrivateCopy)
  1649.      {
  1650.  
  1651.              if ((lastError = PXBlobClone(recH, tblfld)) != DBIERR_NONE)
  1652.              {
  1653.                      return lastError;
  1654.              }
  1655.  
  1656.       }
  1657. */
  1658.     if ((lastError = DbiOpenBlob(curH->tabH, recH, tblfld, dbiREADONLY)) != DBIERR_NONE)
  1659.     {
  1660.         return lastError;
  1661.     }
  1662.  
  1663.     blb.fldnbr      = fldnbr;
  1664.     blb.privateBlb  = usePrivateCopy;
  1665.     blb.state       = blbOpenRead;
  1666.     blb.blbRecH     = recH;
  1667.      // IDAPI stores BLOB handle internally
  1668.     blb.blbH        = tblfld;
  1669.  
  1670.      return (lastError = addBlob((recdef *)recobj, &blb));
  1671. }
  1672.  
  1673. #pragma argsused
  1674. Retcode BRecord::openBlobWrite(FIELDNUMBER fldnbr, long size, BOOL copyOld)
  1675. {
  1676.     blbdef blb;
  1677.  
  1678.     if (!recH)
  1679.     {
  1680.         return (lastError = PXERR_RECNOTATT);
  1681.     }
  1682.  
  1683.     FIELDNUMBER tblfld = getTblFieldNumber(fldnbr);
  1684.  
  1685.     if ((lastError = DbiOpenBlob(curH->tabH, recH, tblfld, dbiREADWRITE))
  1686.         != DBIERR_NONE)
  1687.     {
  1688.         return lastError;
  1689.     }
  1690.  
  1691.     blb.fldnbr      = fldnbr;
  1692.     blb.privateBlb  = FALSE;
  1693.     blb.state       = blbOpenWrite;
  1694.     blb.blbRecH     = recH;
  1695.  
  1696.     // IDAPI stored BLOB handle internally
  1697.     blb.blbH        = tblfld;
  1698.     lastError       = addBlob((recdef *)recobj, &blb);
  1699.  
  1700.     return lastError;
  1701. }
  1702.  
  1703. // Get a BLOB Header.
  1704.  
  1705. #pragma argsused
  1706. Retcode BRecord::getBlobHeader(FIELDNUMBER fldnbr, int size,
  1707.                                void *buffer, int& bytesRead)
  1708. {
  1709.     if (!recH)
  1710.     {
  1711.         return (lastError = PXERR_RECNOTATT);
  1712.     }
  1713.  
  1714.     curdef *co = (curdef *)curH->curobj;
  1715.     if (!recH)
  1716.     {
  1717.         lastError = DBIERR_INVALIDHNDL;
  1718.         return lastError;
  1719.     }
  1720.  
  1721.     if (!strcmp(curH->tabtype, szPARADOX))
  1722.     {
  1723.         fldnbr = getTblFieldNumber(fldnbr);
  1724.  
  1725.         if (size < (co->desc[fldnbr].fldLen - 1))
  1726.         {
  1727.             lastError = DBIERR_BUFFTOOSMALL;
  1728.             return lastError;
  1729.         }
  1730.  
  1731.         lastError = DbiGetBlobHeading(curH->tabH, fldnbr, recH, (pBYTE)buffer);
  1732.     }
  1733.     else
  1734.     {
  1735.         lastError = openBlobRead(fldnbr, FALSE);
  1736.         if (lastError != DBIERR_NONE)
  1737.         {
  1738.             return lastError;
  1739.         }
  1740.         getBlob(fldnbr, size, 0, buffer);
  1741.         if (lastError != DBIERR_NONE)
  1742.         {
  1743.             closeBlob(fldnbr, TRUE);
  1744.             return lastError;
  1745.         }
  1746.         lastError = closeBlob(fldnbr, TRUE);
  1747.         if (lastError != DBIERR_NONE)
  1748.         {
  1749.             closeBlob(fldnbr, TRUE);
  1750.             return lastError;
  1751.         }
  1752.     }
  1753.  
  1754.     return lastError;
  1755. }
  1756.  
  1757. //  Get the size of an open BLOB.
  1758.  
  1759. unsigned long BRecord::getBlobSize(FIELDNUMBER fld)
  1760. {
  1761.     PXFieldType    fldType;
  1762.     PXFieldSubtype fldSubtype;
  1763.     int            fldLen;
  1764.  
  1765.     if (!recH)
  1766.     {
  1767.         return (lastError = PXERR_RECNOTATT);
  1768.     }
  1769.  
  1770.     if (getFieldDesc(fld, fldType, fldSubtype, fldLen))
  1771.     {
  1772.         lastError = DBIERR_INVALIDHNDL;
  1773.         return 0L;
  1774.     }
  1775.  
  1776.     if (fldType != fldBlob)
  1777.     {
  1778.         lastError = PXERR_TYPEMISMATCH;
  1779.         return 0L;
  1780.     }
  1781.  
  1782.     recdef *ro = (recdef *) recobj;
  1783.     unsigned long size;
  1784.  
  1785.     for (int i=0;i < ro->handleCnt; i++)
  1786.     {
  1787.         if (ro->recblb[i].fldnbr == fld && (BOOL) ro->recblb[i].state)
  1788.         {
  1789.             break;
  1790.         }
  1791.     }
  1792.  
  1793.     if (i == ro->handleCnt)
  1794.     {
  1795.         lastError = PXERR_BLOBNOTOPEN;
  1796.         return 0L;
  1797.     }
  1798.  
  1799.     if ((lastError = DbiGetBlobSize(curH->tabH, recH, ro->recblb[i].blbH, &size))
  1800.         != DBIERR_NONE)
  1801.     {
  1802.         return 0L;
  1803.     }
  1804.  
  1805.     return size;
  1806. }
  1807.  
  1808. // Read a segment of an open BLOB.
  1809.  
  1810. Retcode BRecord::getBlob(FIELDNUMBER fld, unsigned int size,
  1811.                          long offset, void far *buffer)
  1812. {
  1813.     PXFieldType     fldType;
  1814.     PXFieldSubtype  fldSubtype;
  1815.     int             fldLen;
  1816.     UINT32          bytesRead;
  1817.  
  1818.     if (!recH)
  1819.     {
  1820.         return (lastError = PXERR_RECNOTATT);
  1821.     }
  1822.  
  1823.     if (getFieldDesc(fld, fldType, fldSubtype, fldLen))
  1824.     {
  1825.         return (lastError = DBIERR_INVALIDHNDL);
  1826.     }
  1827.  
  1828.     if (fldType != fldBlob)
  1829.     {
  1830.         return (lastError = PXERR_TYPEMISMATCH);
  1831.     }
  1832.  
  1833.     recdef *ro = (recdef *) recobj;
  1834.  
  1835.     for (int i=0;i < ro->handleCnt; i++)
  1836.     {
  1837.         if (ro->recblb[i].fldnbr == fld && (int) ro->recblb[i].state)
  1838.         {
  1839.             break;
  1840.         }
  1841.     }
  1842.  
  1843.     if (i == ro->handleCnt)
  1844.     {
  1845.         return (lastError = PXERR_BLOBNOTOPEN);
  1846.     }
  1847.  
  1848.     lastError = DbiGetBlob(curH->tabH, recH, ro->recblb[i].blbH, offset,
  1849.                            size, (pBYTE)buffer, &bytesRead);
  1850.  
  1851.     return lastError;
  1852. }
  1853.  
  1854. // Close an open BLOB handle; closes both private and public BLOBs.
  1855. // For a field, at most, one BLOB can be open at any time.
  1856.  
  1857. // Note - accept does not do anything
  1858.  
  1859. Retcode BRecord::closeBlob(FIELDNUMBER fld, BOOL accept)
  1860. {
  1861.     PXFieldType    fldType;
  1862.     PXFieldSubtype fldSubtype;
  1863.     int            fldLen;
  1864.  
  1865.     if (!recH)
  1866.     {
  1867.         return (lastError = PXERR_RECNOTATT);
  1868.     }
  1869.  
  1870.     if (getFieldDesc(fld, fldType, fldSubtype, fldLen))
  1871.     {
  1872.         return (lastError = DBIERR_INVALIDHNDL);
  1873.     }
  1874.  
  1875.     if (fldType != fldBlob)
  1876.     {
  1877.         return (lastError = PXERR_TYPEMISMATCH);
  1878.     }
  1879.  
  1880.     recdef *ro = (recdef *) recobj;
  1881.  
  1882.     for (int i=0; i < ro->handleCnt; i++)
  1883.     {
  1884.         if (ro->recblb[i].fldnbr == fld && (int) ro->recblb[i].state)
  1885.         {
  1886.             break;
  1887.         }
  1888.     }
  1889.  
  1890.     if (i == ro->handleCnt)
  1891.     {
  1892.         return lastError = PXERR_BLOBNOTOPEN;
  1893.     }
  1894.  
  1895.     if (accept == FALSE)
  1896.     {
  1897.         dropBlob(fld);
  1898.         ro->recblb[i].state = blbClosed;
  1899.     }
  1900.  
  1901.     ro->recblb[i].privateBlb = FALSE;
  1902.  
  1903.     return lastError;
  1904. }
  1905.  
  1906. // Write a segment of an open BLOB.
  1907.  
  1908. Retcode BRecord::putBlob(FIELDNUMBER fld, unsigned long size,
  1909.                          unsigned long offset, void far *buffer)
  1910. {
  1911.      PXFieldType    fldType;
  1912.      PXFieldSubtype fldSubtype;
  1913.      int            fldLen;
  1914.  
  1915.      if (!recH)
  1916.      {
  1917.           return (lastError = PXERR_RECNOTATT);
  1918.      }
  1919.  
  1920.      if (getFieldDesc(fld, fldType, fldSubtype, fldLen))
  1921.      {
  1922.           return (lastError = DBIERR_INVALIDHNDL);
  1923.      }
  1924.  
  1925.      if (fldType != fldBlob)
  1926.      {
  1927.           return (lastError = PXERR_TYPEMISMATCH);
  1928.      }
  1929.  
  1930.      recdef *ro = (recdef *) recobj;
  1931.  
  1932.      for (int i=0;i < ro->handleCnt; i++)
  1933.      {
  1934.           if (ro->recblb[i].fldnbr == fld && (int) ro->recblb[i].state)
  1935.           {
  1936.                 break;
  1937.           }
  1938.      }
  1939.  
  1940.      if (i == ro->handleCnt)
  1941.      {
  1942.           return (lastError = PXERR_BLOBNOTOPEN);
  1943.      }
  1944.  
  1945.      if ((lastError = DbiPutBlob(curH->tabH, recH, ro->recblb[i].blbH,
  1946.                                  offset, (UINT32)size, (pBYTE)buffer))
  1947.           != DBIERR_NONE)
  1948.      {
  1949.           return lastError;
  1950.      }
  1951.  
  1952.      clearNull(fld);                // Clear the null bit in Custom records.
  1953.  
  1954.      return (lastError = DBIERR_NONE);
  1955. }
  1956.  
  1957. // Drop a BLOB field from a record.
  1958.  
  1959. Retcode BRecord::dropBlob(FIELDNUMBER fldnbr)
  1960. {
  1961.     lastError = DbiFreeBlob(curH->tabH, recH, fldnbr);
  1962.     return lastError;
  1963. }
  1964.  
  1965. // This function provides a place holder for preprocessing
  1966. // routines.
  1967.  
  1968. Retcode BRecord::preprocess()
  1969. {
  1970.     return (lastError = DBIERR_NONE);
  1971. }
  1972.  
  1973. // This function provides a place holder for postprocessing
  1974. // routines.
  1975.  
  1976. Retcode BRecord::postprocess()
  1977. {
  1978.     return (lastError = DBIERR_NONE);
  1979. }
  1980.  
  1981. // Redefine pure virtuals from the BDbObject class.
  1982.  
  1983. char * BRecord::nameOf() const
  1984. {
  1985.     return ("BRecord");
  1986. }
  1987.  
  1988. void BRecord::printOn( ostream& os)
  1989. {
  1990.     FieldDesc  desc;
  1991.     char *buf;
  1992.     
  1993.     try
  1994.     {
  1995.         buf = new char[256];
  1996.     }
  1997.     catch(xalloc)
  1998.     {
  1999.         lastError = DBIERR_NOMEMORY;
  2000.         return;
  2001.     }
  2002.  
  2003.      BOOL fNull;
  2004.  
  2005.     int cnt = getFieldCount();
  2006.  
  2007.     os << nameOf() << " { \n";
  2008.  
  2009.     for (int i=1; i <= cnt; i++)
  2010.     {
  2011.         getFieldDesc(i, desc);
  2012.         getField(i, buf, 256, fNull);
  2013.         os << "     " << desc.fldName << " = ";
  2014.         if (desc.fldType == fldBlob)
  2015.         {
  2016.             os << "Blob Field";
  2017.         }
  2018.         else
  2019.         {
  2020.             if (fNull)
  2021.             {
  2022.                 os << "Null" ;
  2023.             }
  2024.             else
  2025.             {
  2026.                 os << buf ;
  2027.             }
  2028.         }
  2029.         os << "\n";
  2030.     }
  2031.  
  2032.     os << "}\n";
  2033.     delete buf;
  2034.     buf = NULL;
  2035. }
  2036.  
  2037. // The following two routines are used to maintain a list of records
  2038. // for a cursor. The Database Framework does not assume the presence
  2039. // of any Class library (not even Borland's container library Classlib).
  2040. // Consequently, no List class is used.
  2041.  
  2042. Retcode addRecord(curdef *cur, BRecord *rec)
  2043. {
  2044.   // Add this record object to the record vector in the cursor.
  2045.  
  2046.     int i;
  2047.  
  2048.     BRecord **newvec;
  2049.  
  2050.     for (i = 0; i < cur->handleCnt; i++)
  2051.     {
  2052.         if (! cur->recList[i])            // empty slot ?
  2053.         {
  2054.             cur->recList[i] = rec;
  2055.             return DBIERR_NONE;
  2056.         }
  2057.     }
  2058.     
  2059.     try
  2060.     {
  2061.         newvec = new BRecord *[cur->handleCnt+4];    // Four more handles.
  2062.     }
  2063.     catch(xalloc)
  2064.     {           
  2065.         return DBIERR_NOMEMORY;
  2066.     }
  2067.  
  2068.  
  2069.      for (i = 0; i < cur->handleCnt; i++)
  2070.      {
  2071.         newvec[i] = cur->recList[i];
  2072.      }
  2073.  
  2074.     newvec[i++] = rec;
  2075.     newvec[i] = newvec[i+1] = newvec[i+2] = NULL;
  2076.     if (cur->handleCnt)
  2077.     {
  2078.         delete [] cur->recList;
  2079.         cur->recList;
  2080.     }
  2081.  
  2082.     cur->handleCnt += 4;
  2083.     cur->recList = newvec;
  2084.     return DBIERR_NONE;
  2085. }
  2086.  
  2087. // Delete the record from the Open Record list of its cursor.
  2088.  
  2089. void deleteRecord(curdef *cur, BRecord *rec)
  2090. {
  2091.     for (int i = 0; i < cur->handleCnt; i++)
  2092.     {
  2093.         if (cur->recList[i] == rec)
  2094.         {
  2095.             cur->recList[i] = NULL;
  2096.             return;
  2097.         }
  2098.     }
  2099. }
  2100.  
  2101. // Add the BLOB to the Open BLOB list of its record.
  2102.  
  2103. Retcode addBlob(recdef *rec, blbdef *blb)
  2104. {
  2105.   // Add this BLOB definition to the Record object.
  2106.     int i;
  2107.     blbdef *newvec;
  2108.  
  2109.     for (i = 0; i < rec->handleCnt; i++)
  2110.     {
  2111.         if (rec->recblb[i].fldnbr == blb->fldnbr)  // BLOB field already has
  2112.         {                                          // a slot.
  2113.             rec->recblb[i] = *blb;
  2114.             return DBIERR_NONE;
  2115.         }
  2116.     }
  2117.  
  2118.     try
  2119.     {
  2120.         // One more handle.
  2121.         newvec = new blbdef[rec->handleCnt+1];
  2122.     }
  2123.     catch(xalloc)
  2124.     {
  2125.         return DBIERR_NOMEMORY;
  2126.     }
  2127.  
  2128.     for (i = 0; i < rec->handleCnt; i++)
  2129.     {
  2130.         newvec[i] = rec->recblb[i];
  2131.     }
  2132.  
  2133.     newvec[i] = *blb;
  2134.  
  2135.     if (rec->handleCnt)
  2136.     {
  2137.         delete [] rec->recblb;
  2138.         rec->recblb = NULL;
  2139.     }
  2140.  
  2141.     rec->handleCnt += 1;
  2142.     rec->recblb = newvec;
  2143.  
  2144.     return DBIERR_NONE;
  2145. }
  2146.  
  2147. // Convert value in source pointed to by srcPtr and leave
  2148. // the result in destPtr;
  2149.  
  2150. Retcode convertFld(void *srcPtr, PXFieldType srcType, int srcLen,
  2151.                    void *destPtr, PXFieldType destType, int destLen)
  2152. {
  2153.     char buf[31];
  2154.     BDate dt;
  2155.     long ld;
  2156.     double db;
  2157.     Retcode ret = DBIERR_NONE;
  2158.     BTime tTime;
  2159.     BTimeStamp tTimestamp;
  2160.  
  2161.     switch(destType)
  2162.     {
  2163.         case fldChar:
  2164.         case fldVarBytes:
  2165.         case fldCharIdapi:
  2166.             switch(srcType)
  2167.             {
  2168.                 case fldChar:
  2169.                 case fldVarBytes:
  2170.                 case fldCharIdapi:
  2171.                     if (srcPtr == destPtr)            // Nothing to copy.
  2172.                     {
  2173.                         return (ret);
  2174.                     }
  2175.                     break;
  2176.                 case fldShort:
  2177.                     srcLen = sprintf(buf,"%d",*((pINT16) srcPtr));
  2178.                     srcPtr = buf;
  2179.                     break;
  2180.                 case fldUInt16:
  2181.                     srcLen = sprintf(buf,"%u",*((pUINT16) srcPtr));
  2182.                     srcPtr = buf;
  2183.                     break;
  2184.                 case fldLong:
  2185.                     srcLen = sprintf(buf,"%ld",*((pINT32) srcPtr));
  2186.                     srcPtr = buf;
  2187.                     break;
  2188.                 case fldUInt32:
  2189.                     srcLen = sprintf(buf,"%lU",*((pUINT32) srcPtr));
  2190.                     srcPtr = buf;
  2191.                     break;
  2192.                 case fldDouble:
  2193.                     srcLen = sprintf(buf,"%G",*((pFLOAT) srcPtr));
  2194.                     srcPtr = buf;
  2195.                     break;
  2196.                 case fldBool:
  2197.                     if (*(pBOOL)srcPtr == 1)
  2198.                     {
  2199.                         srcLen = sprintf(buf,"%s", "TRUE");
  2200.                     }
  2201.                     else
  2202.                     {
  2203.                         srcLen = sprintf(buf,"%s", "TRUE");
  2204.                     }
  2205.                     srcPtr = buf;
  2206.                     break;
  2207.                 case fldDate:
  2208.                     dateToStr((BDate *) srcPtr, buf);
  2209.                     srcPtr = buf;
  2210.                     break;
  2211.                 case fldTime:
  2212.                     timeToStr((BTime *) srcPtr, buf);
  2213.                     srcPtr = buf;
  2214.                     break;
  2215.                 case fldTimeStamp:
  2216.                     timeStampToStr((BTimeStamp *) srcPtr, buf);
  2217.                     srcPtr = buf;
  2218.                     break;
  2219.                 case fldBlob:
  2220.                     // Nothing to copy.
  2221.                     if (srcPtr == destPtr)
  2222.                     {
  2223.                         return ret;
  2224.                     }
  2225.                     break;
  2226.                 case fldBcd:
  2227.                 case fldFloatIEEE:
  2228.                     ret = PXERR_TYPEMISMATCH;
  2229.                     break;
  2230.                 default:
  2231.                     return (PXERR_INVFIELDTYPE);
  2232.             }
  2233.             if (srcLen > destLen && strlen((char *) srcPtr) > destLen)
  2234.             {
  2235.                 ret = DBIERR_BUFFTOOSMALL;
  2236.                 strncpy((char *) destPtr, (char *) srcPtr, destLen);
  2237.             }
  2238.             else
  2239.             {
  2240.                 strcpy((char *) destPtr, (char *) srcPtr);
  2241.             }
  2242.             break;
  2243.  
  2244.         case fldShort:
  2245.             switch(srcType)
  2246.             {
  2247.                 case fldChar:
  2248.                 case fldVarBytes:
  2249.                 case fldCharIdapi:
  2250.                     if (sscanf((char *) srcPtr,"%lf",&db) < 1)
  2251.                     {
  2252.                         ret = PXERR_DATACONV;
  2253.                     }
  2254.                     if (db < SHRT_MIN || db > SHRT_MAX)
  2255.                     {
  2256.                         ret = DBIERR_OUTOFRANGE;
  2257.                     }
  2258.                     *((INT16 *) destPtr) = (INT16) db;
  2259.                     break;
  2260.                 case fldShort:
  2261.                     *((INT16 *) destPtr) = *((INT16 *) srcPtr);
  2262.                     break;
  2263.                 case fldUInt16:
  2264.                     if ((*((UINT16 *)srcPtr) > SHRT_MAX))
  2265.                     {
  2266.                         ret = DBIERR_OUTOFRANGE;
  2267.                     }
  2268.                     *((INT16 *) destPtr) = *((INT16 *) srcPtr);
  2269.                     break;
  2270.                 case fldLong:
  2271.                     ld = *((INT32 *) srcPtr);
  2272.                     if (ld < SHRT_MIN || ld > SHRT_MAX)
  2273.                     {
  2274.                         ret = DBIERR_OUTOFRANGE;
  2275.                     }
  2276.                     *((INT16 *) destPtr) = (INT16) ld;
  2277.                     break;
  2278.                 case fldUInt32:
  2279.                     ld = *((UINT32 *) srcPtr);
  2280.                     if (ld < SHRT_MIN || ld > SHRT_MAX)
  2281.                     {
  2282.                         ret = DBIERR_OUTOFRANGE;
  2283.                     }
  2284.                     *((UINT32 *) destPtr) = (UINT32) ld;
  2285.                     break;
  2286.                 case fldDouble:
  2287.                     db = *((FLOAT *) srcPtr);
  2288.                     if (db < SHRT_MIN || db > SHRT_MAX)
  2289.                     {
  2290.                         ret = DBIERR_OUTOFRANGE;
  2291.                     }
  2292.                     else
  2293.                     {
  2294.                         *((short *) destPtr) = (short) db;
  2295.                     }
  2296.                     break;
  2297.                 case fldDate:
  2298.                 case fldTime:
  2299.                 case fldTimeStamp:
  2300.                 case fldBcd:
  2301.                 case fldBlob:
  2302.                 case fldFloatIEEE:
  2303.                     ret = PXERR_TYPEMISMATCH;
  2304.                     break;
  2305.                 default:
  2306.                     ret = PXERR_INVFIELDTYPE;
  2307.                     break;
  2308.             }
  2309.             break;
  2310.  
  2311.         case fldUInt16:
  2312.             switch(srcType)
  2313.             {
  2314.                 case fldChar:
  2315.                 case fldVarBytes:
  2316.                 case fldCharIdapi:
  2317.                     if (sscanf((char *) srcPtr,"%lf",&db) < 1)
  2318.                     {
  2319.                         ret = PXERR_DATACONV;
  2320.                     }
  2321.                     if (db < 0 || db > USHRT_MAX)
  2322.                     {
  2323.                         ret = DBIERR_OUTOFRANGE;
  2324.                     }
  2325.                     *((UINT16*) destPtr) = (UINT16) db;
  2326.                     break;
  2327.                 case fldShort:
  2328.                     if ( (*( (INT16 *) srcPtr) ) < 0)
  2329.                     {
  2330.                         ret = DBIERR_OUTOFRANGE;
  2331.                     }
  2332.                     *((UINT16 *) destPtr) = *((INT16 *) srcPtr);
  2333.                     break;
  2334.                 case fldUInt16:
  2335.                     *((UINT16 *) destPtr) = *((UINT16 *) srcPtr);
  2336.                     break;
  2337.                 case fldLong:
  2338.                     ld = *((INT32 *) srcPtr);
  2339.                     if (ld < SHRT_MIN || ld > USHRT_MAX)
  2340.                     {
  2341.                         ret = DBIERR_OUTOFRANGE;
  2342.                     }
  2343.                     *((UINT16 *) destPtr) = (UINT16) ld;
  2344.                     break;
  2345.                 case fldUInt32:
  2346.                     ld = *((UINT32 *) srcPtr);
  2347.                     if (ld > USHRT_MAX)
  2348.                     {
  2349.                         ret = DBIERR_OUTOFRANGE;
  2350.                     }
  2351.                     *((UINT16 *) destPtr) = (UINT16) ld;
  2352.                     break;
  2353.                 case fldDouble:
  2354.                     db = *((FLOAT *) srcPtr);
  2355.                     if ((db < 0) || (db > USHRT_MAX))
  2356.                     {
  2357.                         ret = DBIERR_OUTOFRANGE;
  2358.                     }
  2359.                     else
  2360.                     {
  2361.                         *((UINT16 *) destPtr) = (UINT16) db;
  2362.                     }
  2363.                     break;
  2364.                 case fldDate:
  2365.                 case fldTime:
  2366.                 case fldTimeStamp:
  2367.                 case fldBcd:
  2368.                 case fldBlob:
  2369.                 case fldFloatIEEE:
  2370.                     ret = PXERR_TYPEMISMATCH;
  2371.                     break;
  2372.                 default:
  2373.                     ret = PXERR_INVFIELDTYPE;
  2374.                     break;
  2375.             }
  2376.             break;
  2377.  
  2378.         case fldDouble:
  2379.             switch(srcType)
  2380.             {
  2381.                 case fldChar:
  2382.                 case fldVarBytes:
  2383.                 case fldCharIdapi:
  2384.                     if (sscanf((CHAR *) srcPtr,"%lf",&db) < 1)
  2385.                     {
  2386.                         ret = PXERR_DATACONV;
  2387.                     }
  2388.                     *((FLOAT *) destPtr) = db;
  2389.                    break;
  2390.                 case fldShort:
  2391.                     *((FLOAT *) destPtr) = *((INT16 *) srcPtr);
  2392.                     break;
  2393.                 case fldUInt16:
  2394.                     *((FLOAT *) destPtr) = *((UINT16 *) srcPtr);
  2395.                     break;
  2396.                 case fldLong:
  2397.                     *((FLOAT *) destPtr) = *((INT32 *) srcPtr);
  2398.                     break;
  2399.                 case fldUInt32:
  2400.                     *((FLOAT *) destPtr) = *((UINT32 *) srcPtr);
  2401.                     break;
  2402.                 case fldDouble:
  2403.                     *((FLOAT *) destPtr) = *((FLOAT *) srcPtr);
  2404.                     break;
  2405.                 case fldDate:
  2406.                 case fldTime:
  2407.                 case fldTimeStamp:
  2408.                 case fldBcd:
  2409.                 case fldBlob:
  2410.                 case fldFloatIEEE:
  2411.                     ret = PXERR_TYPEMISMATCH;
  2412.                     break;
  2413.                 default:
  2414.                     ret = PXERR_INVFIELDTYPE;
  2415.                     break;
  2416.             }
  2417.             break;
  2418.  
  2419.         case fldLong:
  2420.             switch(srcType)
  2421.             {
  2422.                 case fldChar:
  2423.                 case fldVarBytes:
  2424.                 case fldCharIdapi:
  2425.                     if (sscanf((char *) srcPtr,"%lf",&db) < 1)
  2426.                     {
  2427.                         ret = PXERR_DATACONV;
  2428.                     }
  2429.                     if (db < LONG_MIN || db > LONG_MAX)
  2430.                     {
  2431.                         ret = DBIERR_OUTOFRANGE;
  2432.                     }
  2433.                     *((INT32 *) destPtr) = (INT32) db;
  2434.                     break;
  2435.                 case fldShort:
  2436.                    *((INT32 *) destPtr) = *((INT16 *) srcPtr);
  2437.                     break;
  2438.                 case fldUInt16:
  2439.                    *((INT32 *) destPtr) = *((INT16 *) srcPtr);
  2440.                     break;
  2441.                 case fldLong:
  2442.                     *((INT32 *) destPtr) = *((INT32 *) srcPtr);
  2443.                     break;
  2444.                 case fldUInt32:
  2445.                     *((INT32 *) destPtr) = *((UINT32 *) srcPtr);
  2446.                     break;
  2447.                 case fldDouble:
  2448.                     db = *((FLOAT *) srcPtr);
  2449.                     if (db < LONG_MIN || db > LONG_MAX)
  2450.                     {
  2451.                         ret = DBIERR_OUTOFRANGE;
  2452.                     }
  2453.                     else
  2454.                     {
  2455.                         *((INT32 *) destPtr) = (INT32) db;
  2456.                     }
  2457.                     break;
  2458.                 case fldDate:
  2459.                 case fldTime:
  2460.                 case fldTimeStamp:
  2461.                 case fldBcd:
  2462.                 case fldBlob:
  2463.                 case fldFloatIEEE:
  2464.                     ret = PXERR_TYPEMISMATCH;
  2465.                     break;
  2466.                 default:
  2467.                     ret = PXERR_INVFIELDTYPE;
  2468.                     break;
  2469.             }
  2470.             break;
  2471.  
  2472.         case fldUInt32:
  2473.             switch(srcType)
  2474.             {
  2475.                 case fldChar:
  2476.                 case fldVarBytes:
  2477.                 case fldCharIdapi:
  2478.                     if (sscanf((char *) srcPtr,"%lf",&db) < 1)
  2479.                     {
  2480.                         ret = PXERR_DATACONV;
  2481.                     }
  2482.                     if ((db < 0) || (db > ULONG_MAX))
  2483.                     {
  2484.                         ret = DBIERR_OUTOFRANGE;
  2485.                     }
  2486.                     *((UINT32 *) destPtr) = (UINT32) db;
  2487.                     break;
  2488.                 case fldShort:
  2489.                     if ((*((INT16 *) srcPtr) < 0))
  2490.                     {
  2491.                         ret = DBIERR_OUTOFRANGE;
  2492.                     }
  2493.                    *((UINT32 *) destPtr) = *((INT16 *) srcPtr);
  2494.                     break;
  2495.                 case fldUInt16:
  2496.                    *((UINT32 *) destPtr) = *((UINT16 *) srcPtr);
  2497.                     break;
  2498.                 case fldLong:
  2499.                     if ((*((INT32 *) srcPtr) < 0))
  2500.                     {
  2501.                         ret = DBIERR_OUTOFRANGE;
  2502.                     }
  2503.                     *((UINT32 *) destPtr) = *((INT32 *) srcPtr);
  2504.                     break;
  2505.                 case fldUInt32:
  2506.                     *((UINT32 *) destPtr) = *((UINT32 *) srcPtr);
  2507.                     break;
  2508.                 case fldDouble:
  2509.                     db = *((FLOAT *) srcPtr);
  2510.                     if (db < LONG_MIN || db > LONG_MAX)
  2511.                     {
  2512.                         ret = DBIERR_OUTOFRANGE;
  2513.                     }
  2514.                     else
  2515.                     {
  2516.                         *((UINT32 *) destPtr) = (INT32) db;
  2517.                     }
  2518.                     break;
  2519.                 case fldDate:
  2520.                 case fldTime:
  2521.                 case fldTimeStamp:
  2522.                 case fldBcd:
  2523.                 case fldBlob:
  2524.                 case fldFloatIEEE:
  2525.                     ret = PXERR_TYPEMISMATCH;
  2526.                     break;
  2527.                 default:
  2528.                     ret = PXERR_INVFIELDTYPE;
  2529.                     break;
  2530.             }
  2531.             break;
  2532.             
  2533.         case fldDate:
  2534.             switch(srcType)
  2535.             {
  2536.                 case fldChar:
  2537.                 case fldVarBytes:
  2538.                 case fldCharIdapi:
  2539.                     ret = strToDate((char *) srcPtr, &dt);
  2540.                                     *((BDate *) destPtr) = dt;
  2541.                     break;
  2542.                 case fldShort:
  2543.                 case fldUInt16:
  2544.                 case fldLong:
  2545.                 case fldUInt32:
  2546.                 case fldDouble:
  2547.                     ret = PXERR_TYPEMISMATCH;
  2548.                     break;
  2549.                 case fldDate:
  2550.                     *((BDate *) destPtr) = *((BDate *) srcPtr);
  2551.                     break;
  2552.                 case fldTimeStamp:
  2553.                     *((BDate *) destPtr) = (((BTimeStamp *)srcPtr)->BDay);
  2554.                     break;
  2555.                 case fldTime:
  2556.                 case fldBcd:
  2557.                 case fldBlob:
  2558.                 case fldFloatIEEE:
  2559.                     ret = PXERR_TYPEMISMATCH;
  2560.                     break;
  2561.                 default:
  2562.                     ret = PXERR_INVFIELDTYPE;
  2563.                     break;
  2564.              }
  2565.              break;
  2566.              
  2567.         case fldTime:
  2568.             switch(srcType)
  2569.             {
  2570.                 case fldChar:
  2571.                 case fldVarBytes:
  2572.                 case fldCharIdapi:
  2573.                     ret = strToTime((char *) srcPtr, &tTime);
  2574.                                     *((BTime *) destPtr) = tTime;
  2575.                     break;
  2576.                 case fldShort:
  2577.                 case fldUInt16:
  2578.                 case fldLong:
  2579.                 case fldUInt32:
  2580.                 case fldDouble:
  2581.                     ret = PXERR_TYPEMISMATCH;
  2582.                     break;
  2583.                 case fldTime:
  2584.                     *((BTime *) destPtr) = *((BTime *) srcPtr);
  2585.                     break;
  2586.                 case fldTimeStamp:
  2587.                     *((BTime *) destPtr) = (BTime(((BTimeStamp *)srcPtr)->BHour));
  2588.                     break;
  2589.                 case fldDate:
  2590.                 case fldBcd:
  2591.                 case fldBlob:
  2592.                 case fldFloatIEEE:
  2593.                     ret = PXERR_TYPEMISMATCH;
  2594.                     break;
  2595.                 default:
  2596.                     ret = PXERR_INVFIELDTYPE;
  2597.                     break;
  2598.             }
  2599.             break;
  2600.                     
  2601.         case fldTimeStamp:
  2602.             switch(srcType)
  2603.             {
  2604.                 case fldChar:
  2605.                 case fldVarBytes:
  2606.                 case fldCharIdapi:
  2607.                    ret = strToTimeStamp((char *) srcPtr, &tTimestamp);
  2608.                                         *((BTimeStamp *) destPtr) = tTimestamp;
  2609.                    break;
  2610.                 case fldShort:
  2611.                 case fldUInt16:
  2612.                 case fldLong:
  2613.                 case fldUInt32:
  2614.                 case fldDouble:
  2615.                     ret = PXERR_TYPEMISMATCH;
  2616.                     break;
  2617.                 case fldDate:
  2618.                 {
  2619.                     BTime temp = { 0, 0, 0};
  2620.                     (((BTimeStamp *) destPtr)->BDay) = *((BDate *)srcPtr);
  2621.                     (((BTimeStamp *) destPtr)->BHour) = temp;
  2622.                     break;
  2623.                 }
  2624.                 case fldTime:
  2625.                 {
  2626.                     BDate temp = { 0, 0, 0};
  2627.                     (((BTimeStamp *) destPtr)->BHour) = *((BTime *) srcPtr);
  2628.                     (((BTimeStamp *) destPtr)->BDay) = temp;
  2629.                     break;
  2630.                 }
  2631.                 case fldTimeStamp:
  2632.                     *((BTimeStamp *) destPtr) = (*(BTimeStamp *)srcPtr);
  2633.                     break;
  2634.                 case fldBcd:
  2635.                 case fldBlob:
  2636.                 case fldFloatIEEE:
  2637.                     ret = PXERR_TYPEMISMATCH;
  2638.                     break;
  2639.                 default:
  2640.                     ret = PXERR_INVFIELDTYPE;
  2641.                     break;
  2642.             }
  2643.             break;
  2644.  
  2645.         default:
  2646.             ret = PXERR_INVFIELDTYPE;
  2647.             break;
  2648.     }
  2649.     return ret;
  2650. }
  2651.  
  2652. // Format of string is: 'hh:mm:ss'
  2653. Retcode
  2654. strToTime (const char *str, BTime *dt)
  2655. {
  2656.     TIME dTime;
  2657.  
  2658.     while (!isdigit(*str))
  2659.     {
  2660.         if (*str != '\0')
  2661.         {
  2662.             return DBIERR_INVALIDTIME;
  2663.         }
  2664.         ++str;
  2665.     }
  2666.  
  2667.     //Have 1st digit
  2668.     //Hour:
  2669.     dt->hour = (*str - '0') * 10;
  2670.     ++str;
  2671.     dt->hour += (*str - '0');
  2672.     ++str;
  2673.     if (*str != ':')
  2674.     {
  2675.         return DBIERR_INVALIDTIME;
  2676.     }
  2677.  
  2678.     ++str;
  2679.  
  2680.     //Minute:
  2681.     dt->minute = (*str - '0') * 10;
  2682.     ++str;
  2683.     dt->minute += (*str - '0');
  2684.     ++str;
  2685.  
  2686.     if (*str != ':')
  2687.     {
  2688.         return DBIERR_INVALIDTIME;
  2689.     }
  2690.     ++str;
  2691.  
  2692.     //MilSec:
  2693.     dt->milSec = (*str - '0') * 10;
  2694.     ++str;
  2695.     dt->milSec += (*str - '0');
  2696.     dt->milSec *= 1000;
  2697.  
  2698.     return DbiTimeEncode((UINT16)dt->hour, (UINT16)dt->minute, dt->milSec,
  2699.                          &dTime);
  2700. }
  2701.  
  2702. #pragma argsused
  2703. // Format of string is: ' mm/dd/yyyy hh:mm:ss '
  2704. Retcode
  2705. strToTimeStamp (const char *str, BTimeStamp *dt)
  2706. {
  2707.     int            n;
  2708.     const char* ps = str;
  2709.  
  2710.     while (!isdigit(*ps))
  2711.     {
  2712.         if (*ps == '\0')
  2713.         {
  2714.             return DBIERR_INVALIDDATE;
  2715.         }
  2716.         ++ps;
  2717.     }
  2718.  
  2719.     //Have 1st digit in string
  2720.     n = strToDate(ps, &dt->BDay);
  2721.     if (n != DBIERR_NONE)
  2722.     {
  2723.         return n;
  2724.     }
  2725.     while (*ps != ' ')
  2726.     {
  2727.         if (*ps == '\0')
  2728.         {
  2729.             return DBIERR_INVALIDTIME;
  2730.         }
  2731.         ++ps;
  2732.     }
  2733.  
  2734.     //Have 1st blank after date, assume time follows
  2735.     return strToTime(ps, &dt->BHour);
  2736. }
  2737.  
  2738. //  Convert String to Date. The string must be in the format
  2739. //  MM/DD/YYYY. You may rewrite this function to handle a
  2740. //  variety of different Date formats.
  2741. Retcode
  2742. strToDate(const char *str, BDate *dt)
  2743. {
  2744.     int     i;
  2745.     DATE    Date;
  2746.  
  2747.     if (!isdigit(*str))
  2748.     {
  2749.         return DBIERR_INVALIDDATE;
  2750.     }
  2751.  
  2752.     dt->month = *str++ - '0';
  2753.     if (isdigit(*str))
  2754.     {
  2755.         dt->month = dt->month * 10 + (*str++ - '0');     // 2-digit month.
  2756.     }
  2757.  
  2758.     if (*str++ != '/')
  2759.     {
  2760.         return DBIERR_INVALIDDATE;
  2761.     }
  2762.  
  2763.     if (!isdigit(*str))
  2764.     {
  2765.         return DBIERR_INVALIDDATE;
  2766.     }
  2767.  
  2768.     dt->day = *str++ - '0';
  2769.     if (isdigit(*str))
  2770.     {
  2771.         dt->day = dt->day * 10 + (*str++ - '0');         // 2-digit day.
  2772.     }
  2773.  
  2774.     if (*str++ != '/')
  2775.     {
  2776.         return DBIERR_INVALIDDATE;
  2777.     }
  2778.  
  2779.     if (!isdigit(*str))
  2780.     {
  2781.         return DBIERR_INVALIDDATE;
  2782.     }
  2783.  
  2784.     i = *str++ - '0';
  2785.     if (!isdigit(*str))
  2786.     {
  2787.         return DBIERR_INVALIDDATE;
  2788.     }
  2789.  
  2790.     i = i * 10 + (*str++ - '0');
  2791.     if (!isdigit(*str ))
  2792.     {
  2793.         i += 1900;
  2794.     }
  2795.     else
  2796.     {
  2797.         if (!isdigit(*str))
  2798.         {
  2799.             return DBIERR_INVALIDDATE;
  2800.         }
  2801.         i = i * 10 + *str++ - '0';
  2802.  
  2803.         if (!isdigit(*str))
  2804.         {
  2805.             return DBIERR_INVALIDDATE;
  2806.         }
  2807.  
  2808.         i = i * 10 + (*str++ - '0');                     // 4-digit year.
  2809.  
  2810.         if (isdigit( *str ))
  2811.         {
  2812.             return DBIERR_INVALIDDATE;
  2813.         }
  2814.     }
  2815.  
  2816.     dt->year = i;
  2817.  
  2818.     return DbiDateEncode((UINT16)dt->month, (UINT16)dt->day, dt->year, &Date);
  2819. }
  2820.     
  2821. // Convert Date to String. The string will be output in the format
  2822. // MM/DD/YYYY. You may rewrite this function to handle a variety of
  2823. // different Date formats.
  2824.  
  2825. //=====================================================================
  2826. //  Code:   dateToStr (BDate Date, pCHAR szDate)
  2827. //
  2828. //  Input:  Date     - Date which needs to be formatted
  2829. //          szDate   - String to contain the formatted date
  2830. //
  2831. //  Return: Result returned from DbiDateDecode().
  2832. //
  2833. //  Description:
  2834. //          This function is used to format date fields according to the
  2835. //          settings in the IDAPI.CFG file.
  2836. //=====================================================================
  2837. Retcode
  2838. dateToStr (const BDate *Date, pCHAR szDate)
  2839. {
  2840.     DBIResult   rslt;       // Return Value from IDAPI
  2841.     FMTDate     fmtDate;    // Date Format
  2842.     UINT16      uDay;       // Day portion of date
  2843.     UINT16      uMonth;     // Month portion of date
  2844.     INT16       iYear;      // Year portion of date
  2845.                 
  2846.     // Get the formatting of the Date
  2847.     rslt = DbiGetDateFormat(&fmtDate);
  2848.     if (rslt != DBIERR_NONE)
  2849.     {
  2850.         return rslt;
  2851.     }
  2852.  
  2853.     uDay    = Date->day;
  2854.     uMonth  = Date->month;
  2855.     iYear   = Date->year;
  2856.  
  2857.     // Determine if date should be displayed year based
  2858.     if (!(fmtDate.bFourDigitYear) &&
  2859.         (fmtDate.bYearBiased))
  2860.     {
  2861.         iYear = iYear + 1900;
  2862.     }
  2863.  
  2864.     if (!(fmtDate.bFourDigitYear))
  2865.     {
  2866.         iYear = iYear - 1900;
  2867.     }
  2868.  
  2869.     // Make certain the seperator is not the
  2870.     // escape character.
  2871.     if (!strcmp(fmtDate.szDateSeparator, "\\"))
  2872.     {
  2873.         strcpy(fmtDate.szDateSeparator, "/");
  2874.     }
  2875.  
  2876.     // Format the date
  2877.     switch(fmtDate.iDateMode)
  2878.     {
  2879.         // MM/DD/YY - Month, Day, Year
  2880.         case 0:
  2881.             sprintf(szDate,
  2882.                     "%0*d%s%0*d%s%0*d",
  2883.                     1 + fmtDate.bMonthLeadingZero,
  2884.                     uMonth,
  2885.                     fmtDate.szDateSeparator,
  2886.                     1 + fmtDate.bDayLeadingZero,
  2887.                     uDay,
  2888.                     fmtDate.szDateSeparator,
  2889.                     2,
  2890.                     iYear);
  2891.             break;
  2892.         // DD/MM/YY - Day, Month, Year
  2893.         case 1:
  2894.             sprintf(szDate,
  2895.                     "%0*d%s%0*d%s%0*d",
  2896.                     1 + fmtDate.bDayLeadingZero,
  2897.                     uDay,
  2898.                     fmtDate.szDateSeparator,
  2899.                     1 + fmtDate.bMonthLeadingZero,
  2900.                     uMonth,
  2901.                     fmtDate.szDateSeparator,
  2902.                     2,
  2903.                     iYear);
  2904.             break;
  2905.         // YY/MM/DD - Year, Month, Day
  2906.         case 2:
  2907.             sprintf(szDate,
  2908.                     "%0*d%s%0*d%s%0*d",
  2909.                     2,
  2910.                     iYear,
  2911.                     fmtDate.szDateSeparator,
  2912.                     1 + fmtDate.bMonthLeadingZero,
  2913.                     uMonth,
  2914.                     fmtDate.szDateSeparator,
  2915.                     1 + fmtDate.bDayLeadingZero,
  2916.                     uDay);
  2917.             break;
  2918.     }
  2919.     return rslt;
  2920. }
  2921.  
  2922. //=====================================================================
  2923. //  Code:   timeToStr (BTime Time, pCHAR szTime)
  2924. //
  2925. //  Input:  Time     - Time which needs to be formatted
  2926. //          szTime   - String to contain the formatted time
  2927. //
  2928. //  Return: Result returned from DbiTimeDecode().
  2929. //
  2930. //  Description:
  2931. //          This function is used to format time fields according to
  2932. //          the settings in the IDAPI.CFG file.
  2933. //=====================================================================
  2934. Retcode
  2935. timeToStr (const BTime *Time, pCHAR szTime)
  2936. {
  2937.     DBIResult   rslt;       // Return value from IDAPI functions
  2938.     FMTTime     fmtTime;    // Time format
  2939.     UINT16      uHour;      // Hour portion of the time
  2940.     UINT16      uMinute;    // Minute portion of the time
  2941.     UINT16      uMilSec;    // Second portion (in ms) of the time
  2942.     UINT16      uIsAm;      // Is Time AM?
  2943.     CHAR        szTemp[10]; // Temp buffer, used for AM, PM string
  2944.  
  2945.     // Get the formatting of the Time
  2946.     rslt = DbiGetTimeFormat(&fmtTime);
  2947.     if (rslt != DBIERR_NONE)
  2948.     {
  2949.         return rslt;
  2950.     }
  2951.  
  2952.     uHour   = Time->hour;
  2953.     uMinute = Time->minute;
  2954.     uMilSec = Time->milSec;
  2955.  
  2956.     // Make certain the seperator is not the
  2957.     // escape character.
  2958.     if (fmtTime.cTimeSeparator == '\\')
  2959.     {
  2960.         fmtTime.cTimeSeparator  = '/';
  2961.     }
  2962.  
  2963.     // Check if time should be displayed in 12 or 24 hour format
  2964.     if (fmtTime.bTwelveHour)
  2965.     {
  2966.         // Temporary variable used to determine if the time is AM or PM
  2967.         uIsAm = uHour;
  2968.         uHour = uHour % 12;
  2969.         if (uHour == 0)
  2970.         {
  2971.             uHour = 12;
  2972.         }
  2973.         // If AM, set uIsAm to TRUE, else set uIsAm to 0
  2974.         if (uIsAm == uHour)
  2975.         {
  2976.             uIsAm = 1;
  2977.         }
  2978.         else
  2979.         {
  2980.             uIsAm = 0;
  2981.         }
  2982.     }
  2983.  
  2984.     // Format the hour and minute of the time
  2985.     sprintf(szTime, "%2u%c%02u",
  2986.              uHour,
  2987.              fmtTime.cTimeSeparator,
  2988.              uMinute);
  2989.  
  2990.     // Determine if seconds are to be displayed
  2991.     if (fmtTime.bSeconds)
  2992.     {
  2993.         sprintf(szTemp, "%c%02u",
  2994.                 fmtTime.cTimeSeparator,
  2995.                 (uMilSec / 1000));
  2996.  
  2997.         strcat(szTime, szTemp);
  2998.  
  2999.         // Determine if milliseconds are to be displayed
  3000.         if (fmtTime.bMilSeconds)
  3001.         {
  3002.             sprintf(szTemp, "%c%03u",
  3003.                     fmtTime.cTimeSeparator,
  3004.                     (uMilSec % 1000));
  3005.             strcat(szTime, szTemp);
  3006.         }
  3007.     }
  3008.  
  3009.     // Add a string to the time if the time is 12-hour
  3010.     if (fmtTime.bTwelveHour)
  3011.     {
  3012.         // Add a space to the format
  3013.         strcat(szTime, " ");
  3014.         // If AM
  3015.         if (uIsAm)
  3016.         {
  3017.             // Copy the AM string
  3018.             strcat(szTime, fmtTime.szAmString);
  3019.         }
  3020.         else // otherwise it's PM
  3021.         {
  3022.             // Copy the PM string
  3023.             strcat(szTime, fmtTime.szPmString);
  3024.         }
  3025.     }
  3026.  
  3027.     return rslt;
  3028. }
  3029.  
  3030. //=====================================================================
  3031. //  Code:   timeStampToStr (TIMESTAMPE TimeStamp, pCHAR szTime)
  3032. //
  3033. //  Input:  TIME     - Time which needs to be formatted
  3034. //          szTime   - String to contain the formatted time
  3035. //
  3036. //  Return: Result returned from DbiTimeStampDecode().
  3037. //
  3038. //  Description:
  3039. //          This function is used to format TimeStamp fields according
  3040. //          to the settings in the IDAPI.CFG file. It calls the
  3041. //          FormatDate and FormatTime functions which are defined
  3042. //          above.
  3043. //=====================================================================
  3044. DBIResult
  3045. timeStampToStr (const BTimeStamp *TimeStamp, pCHAR szTimeStamp)
  3046. {
  3047.     DBIResult   rslt;       // Return value from IDAPI functions
  3048.     CHAR        szDate[15]; // Date string
  3049.     CHAR        szTime[20]; // Time String
  3050.  
  3051.     rslt = dateToStr(&(TimeStamp->BDay), szDate);
  3052.  
  3053.     if (rslt != DBIERR_NONE)
  3054.     {
  3055.         return rslt;
  3056.     }
  3057.  
  3058.     // Get the Time format
  3059.     rslt = timeToStr(&(TimeStamp->BHour), szTime);
  3060.     if (rslt != DBIERR_NONE)
  3061.     {
  3062.         return rslt;
  3063.     }
  3064.  
  3065.     // Format the TimeStamp
  3066.     sprintf(szTimeStamp, "%s, %s", szTime, szDate);
  3067.  
  3068.     return rslt;
  3069. }
  3070.  
  3071. Retcode
  3072. BRecord::getField(FIELDNUMBER fldnbr, char *buf,
  3073.                   int bufLen )
  3074. {
  3075.     return getField( fldnbr, buf, bufLen, bLastNull);
  3076. }
  3077.  
  3078. Retcode
  3079. BRecord::getField(FIELDNUMBER fldnbr, void *buf,
  3080.                   int bufLen)
  3081. {
  3082.     return getField( fldnbr, buf, bufLen, bLastNull);
  3083. }
  3084.  
  3085. Retcode
  3086. BRecord::getField(FIELDNUMBER fldnbr, double& val)
  3087. {
  3088.     return getField( fldnbr, val, bLastNull);
  3089. }
  3090.  
  3091. Retcode
  3092. BRecord::getField(FIELDNUMBER fldnbr, INT16& val)
  3093. {
  3094.     return getField( fldnbr, val, bLastNull);
  3095. }
  3096.  
  3097. Retcode
  3098. BRecord::getField(FIELDNUMBER fldnbr, INT32& val)
  3099. {
  3100.     return getField( fldnbr, val, bLastNull);
  3101. }
  3102.  
  3103. Retcode
  3104. BRecord::getField(FIELDNUMBER fldnbr, UINT16& val)
  3105. {
  3106.     return getField( fldnbr, val, bLastNull);
  3107. }
  3108.  
  3109. Retcode
  3110. BRecord::getField(FIELDNUMBER fldnbr, UINT32& val)
  3111. {
  3112.     return getField( fldnbr, val, bLastNull);
  3113. }
  3114.  
  3115. Retcode
  3116. BRecord::getField(FIELDNUMBER fldnbr, FMTBcd& val)
  3117. {
  3118.     return getField( fldnbr, val, bLastNull);
  3119. }
  3120.  
  3121. Retcode
  3122. BRecord::getField(FIELDNUMBER fldnbr, BDate& val)
  3123. {
  3124.     return getField( fldnbr, val, bLastNull);
  3125. }
  3126.  
  3127. Retcode
  3128. BRecord::getField(FIELDNUMBER fldnbr, BTime& val)
  3129. {
  3130.     return getField( fldnbr, val, bLastNull);
  3131. }
  3132.  
  3133. Retcode
  3134. BRecord::getField(FIELDNUMBER fldnbr, BTimeStamp& val)
  3135. {
  3136.     return getField( fldnbr, val, bLastNull);
  3137. }
  3138.  
  3139. Retcode
  3140. BRecord::getField(const char *fldName, char *buf, int bufLen)
  3141. {
  3142.     return getField( (char*) fldName, buf, bufLen, bLastNull);
  3143. }
  3144.  
  3145. Retcode
  3146. BRecord::getField(const char *fldName, void *buf, int bufLen)
  3147. {
  3148.     return getField( (char*) fldName, buf, bufLen, bLastNull);
  3149. }
  3150.  
  3151. Retcode
  3152. BRecord::getField(const char *fldName, double& val)
  3153. {
  3154.     return getField( (char*) fldName, val, bLastNull);
  3155. }
  3156.  
  3157. Retcode
  3158. BRecord::getField(const char *fldName, INT16& val)
  3159. {
  3160.     return getField( (char*) fldName, val, bLastNull);
  3161. }
  3162.  
  3163. Retcode
  3164. BRecord::getField(const char *fldName, INT32& val)
  3165. {
  3166.     return getField( (char*) fldName, val, bLastNull);
  3167. }
  3168.  
  3169. Retcode
  3170. BRecord::getField(const char *fldName, UINT16& val)
  3171. {
  3172.     return getField( (char*) fldName, val, bLastNull);
  3173. }
  3174.  
  3175. Retcode
  3176. BRecord::getField(const char *fldName, UINT32& val)
  3177. {
  3178.     return getField((char*) fldName, val, bLastNull);
  3179. }
  3180.  
  3181. Retcode
  3182. BRecord::getField(const char *fldName, FMTBcd& val)
  3183. {
  3184.     return getField((char*) fldName, val, bLastNull);
  3185. }
  3186.  
  3187. Retcode
  3188. BRecord::getField(const char *fldName, BDate& val)
  3189. {
  3190.     return getField((char*) fldName, val, bLastNull);
  3191. }
  3192.  
  3193. Retcode
  3194. BRecord::getField(const char *fldName, BTime& val)
  3195. {
  3196.     return getField((char*) fldName, val, bLastNull);
  3197. }
  3198.  
  3199. Retcode
  3200. BRecord::getField(const char *fldName, BTimeStamp& val)
  3201. {
  3202.     return getField((char*)fldName, val, bLastNull);
  3203. }
  3204.  
  3205. Retcode
  3206. BRecord::openBlobRead(const char* psFldName,
  3207.                       BOOL bUsePrivateCopy)
  3208. {
  3209.     FIELDNUMBER hFld;
  3210.  
  3211.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3212.     {
  3213.         return (lastError);
  3214.     }
  3215.  
  3216.     return openBlobRead(hFld, bUsePrivateCopy);
  3217. }
  3218.  
  3219. Retcode
  3220. BRecord::openBlobWrite(const char* psFldName,
  3221.                        long nSize,
  3222.                        BOOL bCopyOld)
  3223. {
  3224.     FIELDNUMBER hFld;
  3225.     
  3226.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3227.     {
  3228.         return (lastError);
  3229.     }
  3230.  
  3231.     return openBlobWrite(hFld, nSize, bCopyOld);
  3232. }
  3233.  
  3234. Retcode
  3235. BRecord::getBlobHeader(const char* psFldName,
  3236.                        int nSize,
  3237.                        void* pvBuffer,
  3238.                        int& rnBytesRead)
  3239. {
  3240.     FIELDNUMBER hFld;
  3241.     
  3242.     if ((hFld = getFieldNumber(psFldName)) == 0 )
  3243.     {
  3244.         return (lastError);
  3245.     }
  3246.  
  3247.     return getBlobHeader(hFld, nSize, pvBuffer, rnBytesRead);
  3248. }
  3249.  
  3250. unsigned long
  3251. BRecord::getBlobSize(const char* psFldName)
  3252. {
  3253.     FIELDNUMBER hFld;
  3254.     //
  3255.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3256.     {
  3257.         return (lastError);
  3258.     }
  3259.  
  3260.     return getBlobSize(hFld);
  3261. }
  3262.  
  3263. Retcode
  3264. BRecord::getBlob(const char* psFldName,
  3265.                  unsigned int nSize,
  3266.                  long nOffset,
  3267.                  void far *pvBuffer)
  3268. {
  3269.     FIELDNUMBER hFld;
  3270.     
  3271.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3272.     {
  3273.         return (lastError);
  3274.     }
  3275.  
  3276.     return getBlob(hFld, nSize, nOffset, pvBuffer);
  3277. }
  3278.  
  3279. Retcode
  3280. BRecord::closeBlob(const char* psFldName,
  3281.                    BOOL bAccept)
  3282. {
  3283.     FIELDNUMBER hFld;
  3284.  
  3285.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3286.     {
  3287.         return (lastError);
  3288.     }
  3289.  
  3290.     return closeBlob(hFld, bAccept);
  3291. }
  3292.  
  3293. Retcode
  3294. BRecord::putBlob(const char* psFldName,
  3295.                  unsigned long nSize,
  3296.                  unsigned long nOffset,
  3297.                  void far *pvBuffer)
  3298. {
  3299.     FIELDNUMBER hFld;
  3300.  
  3301.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3302.     {
  3303.         return (lastError);
  3304.     }
  3305.  
  3306.     return putBlob(hFld, nSize, nOffset, pvBuffer);
  3307. }
  3308.  
  3309. Retcode
  3310. BRecord::dropBlob(const char* psFldName)
  3311. {
  3312.     FIELDNUMBER hFld;
  3313.  
  3314.     if ((hFld = getFieldNumber(psFldName)) == 0)
  3315.     {
  3316.         return (lastError);
  3317.     }
  3318.     return dropBlob(hFld);
  3319. }
  3320.  
  3321.