summaryrefslogtreecommitdiff
path: root/src/core/xbmemo4.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/xbmemo4.cpp')
-rwxr-xr-xsrc/core/xbmemo4.cpp1335
1 files changed, 0 insertions, 1335 deletions
diff --git a/src/core/xbmemo4.cpp b/src/core/xbmemo4.cpp
deleted file mode 100755
index d02df99..0000000
--- a/src/core/xbmemo4.cpp
+++ /dev/null
@@ -1,1335 +0,0 @@
-/* xbmemo4.cpp
-
-XBase64 Software Library
-
-Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
-
-The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
-
-Email Contact:
-
- XDB-devel@lists.sourceforge.net
- XDB-users@lists.sourceforge.net
-
- This class is used for support dBASE V4 memo files
-
-*/
-
-#include "xbase.h"
-
-#ifdef XB_MEMO_SUPPORT
-#ifdef XB_DBF4_SUPPORT
-
-namespace xb{
-
-/***********************************************************************/
-//! @brief Class Constructor.
-/*!
- \param dbf Pointer to dbf instance.
- \param sFileName Memo file name.
-*/
-xbMemoDbt4::xbMemoDbt4( xbDbf * dbf, xbString const & sFileName ) : xbMemo( dbf, sFileName ){
- iMemoFileType = 4;
- SetBlockSize( dbf->GetCreateMemoBlockSize() );
-}
-
-/***********************************************************************/
-//! @brief Class Deconstructor.
-xbMemoDbt4::~xbMemoDbt4(){}
-
-/***********************************************************************/
-//! @brief Abort.
-/*!
- Abort any pending updates to the memo file.
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::Abort(){
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulBlockNo;
-
- try{
- xbUInt32 ulNodeCnt = llNewBlocks.GetNodeCnt();
- for( xbUInt32 l = 0; l < ulNodeCnt; l++ ){
- if(( rc = llNewBlocks.RemoveFromFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = FreeMemoBlockChain( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- llOldBlocks.Clear();
- }
-
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::Abort() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-
-/***********************************************************************/
-//! @brief Commit changes to memo file.
-/*!
- Commit any pending updates to the memo file.
- \returns XB_NO_ERROR.
-*/
-xbInt16 xbMemoDbt4::Commit(){
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulBlockNo;
-
- try{
- xbUInt32 ulNodeCnt = llOldBlocks.GetNodeCnt();
- for( xbUInt32 l = 0; l < ulNodeCnt; l++ ){
- if(( rc = llOldBlocks.RemoveFromFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = FreeMemoBlockChain( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- llNewBlocks.Clear();
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::Commit() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Create memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::CreateMemoFile(){
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- char cBuf[4];
-
- try{
- if(( rc = xbFopen( "w+b", dbf->GetShareMode() )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- ulHdrNextBlock = 1L;
- ePutUInt32( cBuf, ulHdrNextBlock );
- if(( rc = xbFwrite( cBuf, 4, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 110;
- xbFclose();
- throw rc;
- }
- for(int i = 0; i < 4; i++ )
- xbFputc( 0x00 );
- GetFileNamePart( sDbfFileNameWoExt );
- sDbfFileNameWoExt.PadRight( ' ', 8 ); // need at least eight bytes of name
- sDbfFileNameWoExt = sDbfFileNameWoExt.Mid( 1, 8 ); // need no more than eight bytes of name
- for( int i = 1; i < 9; i++ )
- xbFputc( sDbfFileNameWoExt[i] );
-
- for(int i = 0; i < 4; i++ )
- xbFputc( 0x00 );
-
- ePutInt16( cBuf, GetBlockSize());
- if(( rc = xbFwrite( cBuf, 2, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 120;
- xbFclose();
- throw rc;
- }
- for( xbUInt32 i = 0; i < (GetBlockSize() - 22); i++ )
- xbFputc( 0x00 );
- if(( mbb = (void *) malloc( GetBlockSize())) == NULL ){
- rc = XB_NO_MEMORY;
- iErrorStop = 130;
- return XB_NO_MEMORY;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::CreateMemoFile() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- xbFclose();
- }
- return rc;
-}
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Dump memo file header.
-/*!
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbMemoDbt4::DumpMemoFreeChain()
-{
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulCurBlock, ulLastDataBlock;
-
- try{
- if(( rc = ReadDbtHeader(1)) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
-
- ulCurBlock = ulHdrNextBlock;
- std::cout << "**********************************" << std::endl;
- std::cout << "Head Node Next Block = " << ulCurBlock << std::endl;;
- std::cout << "Total blocks in file = " << ulLastDataBlock << std::endl;
-
- while( ulCurBlock < ulLastDataBlock ){
- if(( rc = ReadBlockHeader( ulCurBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- std::cout << "**********************************" << std::endl;
- std::cout << "This Free Block = [" << ulCurBlock << "] contains [" << ulFreeBlockCnt << "] block(s)" << std::endl;
- std::cout << "Next Free Block = [" << ulNextFreeBlock << "]" << std::endl;
- ulCurBlock = ulNextFreeBlock;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::UpdateMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return XB_NO_ERROR;
-}
-
-//! @brief Dump memo internals.
-/*!
- \returns XB_NO_ERROR
-*/
-
-xbInt16 xbMemoDbt4::DumpMemoInternals() {
-
- xbLinkListNode<xbUInt32> *llPtr;
- xbInt16 iNodeCnt;
-
- llPtr = llOldBlocks.GetHeadNode();
- iNodeCnt = llOldBlocks.GetNodeCnt();
-
- std::cout << "Link List Old Blocks - " << iNodeCnt << " nodes" << std::endl;
- for( xbInt16 i = 0; i < iNodeCnt; i++ ){
- std::cout << llPtr->GetKey() << ",";
- llPtr = llPtr->GetNextNode();
- }
- std::cout << std::endl;
-
- llPtr = llNewBlocks.GetHeadNode();
- iNodeCnt = llNewBlocks.GetNodeCnt();
- std::cout << "Link List New Blocks - " << iNodeCnt << " nodes" << std::endl;
- for( xbInt16 i = 0; i < iNodeCnt; i++ ){
- std::cout << llPtr->GetKey() << ",";
- llPtr = llPtr->GetNextNode();
- }
- std::cout << std::endl;
-
- return XB_NO_ERROR;
-}
-#endif // XB_DEBUG_SUPPORT
-
-/***********************************************************************/
-//! @brief Dump memo file header.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::DumpMemoHeader(){
-
- xbInt16 rc = XB_NO_ERROR;
- xbUInt32 ulLastDataBlock;
- CalcLastDataBlock( ulLastDataBlock );
-
- if(( rc = ReadDbtHeader( 1 )) != XB_NO_ERROR )
- return rc;
- std::cout << "Version 4 Memo Header Info" << std::endl;
- std::cout << "Memo File Name = " << GetFqFileName() << std::endl;
- std::cout << "Hdr Next Avail Block = " << ulHdrNextBlock << std::endl;
- std::cout << "Block Size = " << GetBlockSize() << std::endl;
- std::cout << "Dbf File Name wo Ext = " << sDbfFileNameWoExt.Str() << std::endl;
- std::cout << "Last Data Block = " << ulLastDataBlock << std::endl;
- return rc;
-}
-
-/************************************************************************/
-//! @brief Find an empty set of blocks in the free block chain
-/*!
- This routine searches thruugh the free node chain in a dbase IV type
- memo file searching for a place to grab some free blocks for reuse
-
- \param ulBlocksNeeded The size to look in the chain for.
- \param ulLastDataBlock is the last data block in the file, enter 0
- for the routine to calculate it.
- \param ulLocation The location it finds.
- \param ulPreviousNode Block number of the node immediately previous to this node in the chain.<br>
- 0 if header node
- \param bFound Output xbFalse - Spot not found in chain.<br>
- xbTrue - Spot found in chain.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::FindBlockSetInChain( xbUInt32 ulBlocksNeeded,
- xbUInt32 &ulLastDataBlock, xbUInt32 &ulLocation, xbUInt32 &ulPrevNode, xbBool &bFound ){
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulCurNode;
-
- try{
- ulPrevNode = 0L;
- if( ulLastDataBlock == 0 ){
- /* Determine last good data block */
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- }
- if( ulHdrNextBlock < ulLastDataBlock ){
- ulCurNode = ulHdrNextBlock;
-
- if(( rc = ReadBlockHeader( ulHdrNextBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- while( ulBlocksNeeded > ulFreeBlockCnt && ulNextFreeBlock < ulLastDataBlock ){
- ulPrevNode = ulCurNode;
- ulCurNode = ulNextFreeBlock;
- if(( rc = ReadBlockHeader( ulNextFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- }
- if( ulBlocksNeeded <= ulFreeBlockCnt ){
- ulLocation = ulCurNode;
- // PreviousNode = lPrevNode;
- bFound = xbTrue;
- } else { // no data found and at end of chain
- ulPrevNode = ulCurNode;
- bFound = xbFalse;
- }
- } else {
- bFound = xbFalse;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::FindBlockSetInChain() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Free a block.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::FreeMemoBlockChain( xbUInt32 ulBlockNo ){
- xbUInt32 ulLastDataBlock;
- return FreeMemoBlockChain( ulBlockNo, ulLastDataBlock );
-}
-
-/***********************************************************************/
-//! @brief Free a block.
-/*!
- \param ulBlockNo The block number being deleted.
- \param ulLastDataBlock Output - Last free block number,prior to this block.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::FreeMemoBlockChain( xbUInt32 ulBlockNo, xbUInt32 &ulLastDataBlock )
-{
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulNoOfFreedBlocks;
- xbUInt32 ulLastFreeBlock = 0;
- xbUInt32 ulLastFreeBlockCnt = 0;
- xbUInt32 ulSaveNextFreeBlock;
-
- // iFieldNo - The field no m\bing deleted
- // iBlockNo - The block number being deleted
- // iNoOfFreeBlocks - The number of blocks being freed with this delete
- // iLastDataBlock - The next block number to allocate if more blocks needed
- // iHdrNextBlock - The head pointer in the main header block
- // iNextFreeBlock - The block that is immediately following the current free block to be added
- // iLastFreeBlock - Last free block number,prior to this block
- // iLastFreeBlockCnt - Last free block number of blocks
-
- try{
-
- if( ulBlockNo <= 0 ){
- iErrorStop = 100;
- rc =XB_INVALID_BLOCK_NO;
- throw rc;
- }
-
- /* Load the first block */
- if(( rc = ReadBlockHeader( ulBlockNo, 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
-
- if( (ulFieldLen) % GetBlockSize() )
- ulNoOfFreedBlocks = ((ulFieldLen) / GetBlockSize()) + 1L;
- else
- ulNoOfFreedBlocks = (ulFieldLen) / GetBlockSize();
-
- /* Determine last good data block */
- if(( rc = CalcLastDataBlock( ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
-
- if(( rc = ReadDbtHeader( 0 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
-
- // Not an empty node chain, position to correct location in chain
- ulNextFreeBlock = ulHdrNextBlock;
- while( ulBlockNo > ulNextFreeBlock && ulBlockNo < ulLastDataBlock ){
- ulLastFreeBlock = ulNextFreeBlock;
-
- if(( rc = ReadBlockHeader( ulNextFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 140;
- return rc;
- }
- ulLastFreeBlockCnt = ulFreeBlockCnt;
- }
-
- // One of two outcomes at this point
- // A) This block is combined with the next free block chain, and points to the free chain after the next free block
- // B) This block is not combined with the next free block chain, and points to the next block
- // (which could be the last block
-
- // should next block should be concatonated onto the end of this set?
- ulSaveNextFreeBlock = ulNextFreeBlock;
- if(( ulBlockNo + ulNoOfFreedBlocks ) == ulNextFreeBlock && ulNextFreeBlock < ulLastDataBlock ){
- if(( rc = ReadBlockHeader( ulNextFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- ulNoOfFreedBlocks += ulFreeBlockCnt;
- ulSaveNextFreeBlock = ulNextFreeBlock;
- }
-
- // if this is the first set of free blocks
- if( ulLastFreeBlock == 0 ){
- // 1 - write out the current block
- // 2 - update header block
- // 3 - write header block
- // 4 - update data field
-
- ePutUInt32( (char *) mbb, ulSaveNextFreeBlock );
- ePutUInt32( (char *) mbb+4, ulNoOfFreedBlocks );
- if(( rc = WriteBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
-
- ulHdrNextBlock = ulBlockNo;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- return XB_NO_ERROR;
- }
-
- /* determine if this block set should be added to the previous set */
- if(( ulLastFreeBlockCnt + ulLastFreeBlock ) == ulBlockNo ){
- if(( rc = ReadBlockHeader( ulLastFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw rc;
- }
- ulFreeBlockCnt += ulNoOfFreedBlocks;
-
- ePutUInt32( (char *) mbb, ulSaveNextFreeBlock );
- ePutUInt32( (char *) mbb+4, ulFreeBlockCnt );
- if(( rc = WriteBlock( ulLastFreeBlock, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw rc;
- }
- return XB_NO_ERROR;
- }
-
- /* insert into the chain */
- /* 1 - set the next bucket on the current node */
- /* 2 - write this node */
- /* 3 - go to the previous node */
- /* 4 - insert this nodes id into the previous node set */
- /* 5 - write previous node */
-
- ePutUInt32( (char *) mbb, ulSaveNextFreeBlock );
- ePutUInt32( (char *) mbb+4, ulNoOfFreedBlocks );
- if(( rc = WriteBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw rc;
- }
-
- if(( rc = ReadBlockHeader( ulLastFreeBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw rc;
- }
-
- ePutUInt32( (char *) mbb, ulBlockNo );
- if(( rc = WriteBlock( ulLastFreeBlock, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw rc;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::DeleteMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/************************************************************************/
-//! @brief Get a set of blocks from the free block chain.
-/*!
- This routine grabs a set of blocks out of the free block chain.
-
- \param ulBlocksNeeded The number of blocks requested.
- \param ulLocation
- \param ulPrevNode
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-
-xbInt16 xbMemoDbt4::GetBlockSetFromChain( xbUInt32 ulBlocksNeeded,
- xbUInt32 ulLocation, xbUInt32 ulPrevNode )
-{
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- xbUInt32 ulNextFreeBlock2;
- xbUInt32 ulNewFreeBlocks;
- xbUInt32 ulSaveNextFreeBlock;
-
- try{
- if(( rc = ReadBlockHeader( ulLocation, 2 )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( ulBlocksNeeded == ulFreeBlockCnt ){ // grab this whole set of blocks
- if( ulPrevNode == 0 ){ // first in the chain
- ulHdrNextBlock = ulNextFreeBlock;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- else // remove out of the middle or end
- {
- ulNextFreeBlock2 = ulNextFreeBlock;
- if(( rc = ReadBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- ulNextFreeBlock = ulNextFreeBlock2;
- if(( rc = WriteBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- }
- } else { // only take a portion of this set
- if( ulPrevNode == 0 ){ // first in the set
- ulHdrNextBlock = ulLocation + ulBlocksNeeded;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- ulFreeBlockCnt -= ulBlocksNeeded;
- if(( rc = WriteBlockHeader( ulHdrNextBlock, 2 )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- }
- else { // remove out of the middle or end
- ulNewFreeBlocks = ulFreeBlockCnt - ulBlocksNeeded;
- ulSaveNextFreeBlock = ulNextFreeBlock;
- ulNextFreeBlock2 = ulLocation + ulBlocksNeeded;
-
- if(( rc = ReadBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
- ulNextFreeBlock = ulNextFreeBlock2;
- if(( rc = WriteBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- ulFreeBlockCnt = ulNewFreeBlocks;
- ulNextFreeBlock = ulSaveNextFreeBlock;
- if(( rc = WriteBlockHeader( ulNextFreeBlock2, 2 )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw rc;
- }
- }
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetBlockSetFromChain() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Get a memo field for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param sMemoData Output - string containing memo field data.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::GetMemoField( xbInt16 iFieldNo, xbString & sMemoData ){
-
- xbUInt32 ulBlockNo;
- xbUInt32 ulMemoFieldLen;
- xbUInt32 ulMemoFieldDataLen;
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char *p = NULL;
-
- try{
- if(( rc = GetMemoFieldLen( iFieldNo, ulMemoFieldLen, ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( ulBlockNo == 0L || ulMemoFieldLen == 0L )
- sMemoData = "";
- else{
- ulMemoFieldDataLen = ulMemoFieldLen - 8;
-
- if(( p = (char *)calloc(1, ulMemoFieldDataLen+1)) == NULL ){
- iErrorStop = 110;
- rc = XB_NO_MEMORY;
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetMemoField() lBlockNo = %ld Data Len = [%ld]", ulBlockNo, ulMemoFieldDataLen + 1 );
- xbase->WriteLogMessage( sMsg.Str() );
- throw rc;
- }
-
- // go to the first block of the memo field, skip past the first 8 bytes
- if(( xbFseek( ( ulBlockNo * GetBlockSize() + 8 ), SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 120;
- rc = XB_SEEK_ERROR;
- throw rc;
- }
-
- // read the memo file data into buffer pointed to by "p"
- if(( rc = xbFread( p, ulMemoFieldDataLen, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- rc = XB_READ_ERROR;
- throw rc;
- }
- // null terminate the string
- char *p2;
- p2 = p + ulMemoFieldDataLen;
- *p2 = 0x00;
-
- // save it to the string
- sMemoData.Set( p, ulMemoFieldDataLen + 1 );
- free( p );
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- if( p )
- free( p );
- }
- return rc;
-}
-
-/***********************************************************************/
-//! @brief Get a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param ulMemoFieldLen Output - length of memo field data.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen ){
- xbUInt32 ulBlockNo;
- return GetMemoFieldLen( iFieldNo, ulMemoFieldLen, ulBlockNo );
-}
-
-/***********************************************************************/
-//! @brief Get a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to retrieve data for.
- \param ulMemoFieldLen Output - length of memo field data.
- \param ulBlockNo Output - Starting block number.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::GetMemoFieldLen( xbInt16 iFieldNo, xbUInt32 &ulMemoFieldLen, xbUInt32 &ulBlockNo ){
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
- char cFieldType;
-
- try{
-
- if(( rc = dbf->GetFieldType( iFieldNo, cFieldType )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if( cFieldType != 'M' ){
- iErrorStop = 110;
- rc = XB_INVALID_MEMO_FIELD;
- throw rc;
- }
- if(( rc = dbf->GetULongField( iFieldNo, ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- if( ulBlockNo < 1 ){
- ulMemoFieldLen = 0;
- return XB_NO_ERROR;
- }
- if(( rc = ReadBlockHeader( ulBlockNo, 1 )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- ulMemoFieldLen = ulFieldLen;
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::GetMemoFieldLen() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Open memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::OpenMemoFile() {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
-
- try{
- if(( rc = xbFopen( dbf->GetOpenMode(), dbf->GetShareMode())) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
- if(( rc = ReadDbtHeader( 1 )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- if(( mbb = (void *) malloc( GetBlockSize())) == NULL ){
- xbFclose();
- iErrorStop = 120;
- rc = XB_NO_MEMORY;
- throw rc;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::OpenMemoFile() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Pack memo file.
-/*!
- This routine frees up any unused blocks in the file resulting from field updates.
- Version 3 memo files do not reclaim unused space (Version 4 files do).
- This routine cleans up the unused space.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::PackMemo( void (*memoStatusFunc ) ( xbUInt32 ulItemNum, xbUInt32 ulNumItems )){
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- char * cBlock = NULL;
-
- #ifdef XB_LOCKING_SUPPORT
- xbBool bTableLocked = xbFalse;
- xbBool bMemoLocked = xbFalse;
- #endif
-
- try{
- #ifdef XB_LOCKING_SUPPORT
- if( dbf->GetAutoLock() && !dbf->GetTableLocked() ){
- if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- } else {
- bTableLocked = xbTrue;
- }
- if(( iRc = LockMemo( XB_LOCK )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- } else {
- bMemoLocked = xbTrue;
- }
- }
- #endif
-
- // create temp file
- xbString sTempMemoName;
- if(( iRc = CreateUniqueFileName( GetDirectory(), "dbt", sTempMemoName )) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
-
- xbMemoDbt4 *pMemo = new xbMemoDbt4( dbf, sTempMemoName );
- if(( iRc = pMemo->CreateMemoFile()) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw iRc;
- }
- // for dbase III, block size is always 512, don't need to reset it
- // for each record in dbf
- xbUInt32 ulRecCnt;
- if(( iRc = dbf->GetRecordCnt( ulRecCnt)) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw iRc;
- }
- xbInt32 lFldCnt = dbf->GetFieldCnt();
- char cFldType;
- xbString sMemoFldData;
-
- for( xbUInt32 ulI = 1; ulI <= ulRecCnt; ulI++ ){
- if(( iRc = dbf->GetRecord( ulI )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw iRc;
- }
-
- if( (void *) memoStatusFunc)
- (*memoStatusFunc)(ulI, ulRecCnt );
-
- // for each memo field
- for( xbInt32 lFc = 0; lFc < lFldCnt; lFc++ ){
- if(( iRc = dbf->GetFieldType( lFc, cFldType )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw iRc;
- }
- if( cFldType == 'M' ){
- // copy it to work field
- if(( iRc = dbf->GetMemoField( lFc, sMemoFldData )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw iRc;
- }
- // write it to new field
- if(( iRc = pMemo->UpdateMemoField( lFc, sMemoFldData )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw iRc;
- }
- }
- }
- }
-
- //copy target back to source
- xbUInt32 ulBlkSize = GetBlockSize();
- xbUInt64 ullFileSize;
- if(( iRc = pMemo->GetFileSize( ullFileSize )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw iRc;
- }
- // file size should be evenly divisible by block size
- xbUInt32 ulBlkCnt;
-
- if( ullFileSize % ulBlkSize ){
- iErrorStop = 200;
- throw iRc;
- } else {
- ulBlkCnt = (xbUInt32) (ullFileSize / ulBlkSize);
- }
- if(( iRc = xbTruncate( 0 )) != XB_NO_ERROR ){
- iErrorStop = 210;
- throw iRc;
- }
-
- if(( cBlock = (char *) malloc( ulBlkSize )) == NULL ){
- iErrorStop = 220;
- throw iRc;
- }
-
- // can't rename files in a multiuser, cross platform environment, causes issues
- // copy work table back to source table
-
- for( xbUInt32 ulBc = 0; ulBc < ulBlkCnt; ulBc++ ){
- if(( iRc = pMemo->ReadBlock( ulBc, ulBlkSize, cBlock )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw iRc;
- }
- if(( iRc = WriteBlock( ulBc, ulBlkSize, cBlock )) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw iRc;
- }
- }
-
- if(( xbFseek( 8, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 250;
- iRc = XB_SEEK_ERROR;
- throw iRc;
- }
-
- for( int i = 1; i < 9; i++ )
- xbFputc( sDbfFileNameWoExt[i] );
-
- //close and delete target
- if(( iRc = pMemo->xbFclose()) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw iRc;
- }
- if(( iRc = pMemo->xbRemove()) != XB_NO_ERROR ){
- iErrorStop = 270;
- throw iRc;
- }
- free( cBlock );
- delete pMemo;
-
- }
- catch (xbInt16 iRc ){
- free( cBlock );
-
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::PackMemo() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- #ifdef XB_LOCKING_SUPPORT
- if( bTableLocked )
- dbf->LockTable( XB_UNLOCK );
- if( bMemoLocked )
- LockMemo( XB_UNLOCK );
- #endif
- return iRc;
-}
-/***********************************************************************/
-//! @brief Read block header.
-/*!
- \param ulBlockNo Block to read
- \param iOption 1 - Read fields option 1
- 2 - Read fields option 2
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::ReadBlockHeader( xbUInt32 ulBlockNo, xbInt16 iOption ) {
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
-
- if(( rc = ReadBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 100;
- rc = XB_READ_ERROR;
- }
- if( iOption == 1 ){
- iField1 = eGetInt16((char *) mbb );
- iStartPos = eGetInt16((char *) mbb+2);
- ulFieldLen = eGetUInt32((char *) mbb+4);
- }
- else if( iOption == 2 ){
- ulNextFreeBlock = eGetUInt32((char *) mbb );
- ulFreeBlockCnt = eGetUInt32((char *) mbb+4 );
- }
- else{
- iErrorStop = 110;
- rc = XB_INVALID_OPTION;
- throw rc;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::ReadBlockHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Read dbt header file.
-/*!
- \param iOption 0 --> read only first four bytes<br>
- 1 --> read the entire thing
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::ReadDbtHeader( xbInt16 iOption ) {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iReadLen = 0;
- char *p;
- char MemoBlock[22];
-
- try{
- if( !FileIsOpen() ){
- iErrorStop = 100;
- rc = XB_NOT_OPEN;
- throw rc;
- }
- if( xbFseek( 0, SEEK_SET )){
- iErrorStop = 110;
- rc = XB_SEEK_ERROR;
- throw rc;
- }
- if( iOption )
- iReadLen = 22;
- else
- iReadLen = 4;
-
- if(( xbFread( &MemoBlock, (size_t) iReadLen, 1 )) != XB_NO_ERROR ){
- iErrorStop = 120;
- rc = XB_READ_ERROR;
- throw rc;
- }
-
- p = MemoBlock;
- ulHdrNextBlock = eGetUInt32( p );
- if( iOption == 0)
- return XB_NO_ERROR;
-
- p += 8;
- sDbfFileNameWoExt = "";
- for( int i = 0; i < 8; i++ )
- sDbfFileNameWoExt += *p++;
-
- p += 4;
- SetBlockSize( (xbUInt32) eGetInt16( p ));
-
- cVersion = MemoBlock[16];
-
- }
- catch (xbInt16 rc ){
-
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::ReadDbtHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-
-/***********************************************************************/
-#ifdef XB_DEBUG_SUPPORT
-//! @brief Read free block information from header.
-/*!
- This routing pulls any reusable block information for file header.
- Not used with version 3 memo files - stub.
-
- \param ulBlockNo
- \param ulNextBlock
- \param ulFreeBlockCnt
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::ReadFreeBlockHeader( xbUInt32 ulBlockNo, xbUInt32 &ulNextBlock, xbUInt32 &ulFreeBlockCount ){
-
- xbInt16 rc = XB_NO_ERROR;
- rc = ReadBlockHeader( ulBlockNo, 2 );
- ulNextBlock = ulNextFreeBlock;
- ulFreeBlockCount = ulFreeBlockCnt;
- return rc;
-}
-#endif
-/***********************************************************************/
-//! @brief Update header name.
-/*!
- \returns XB_NO_ERROR
-*/
-xbInt16 xbMemoDbt4::UpdateHeaderName() {
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- GetFileNamePart( sDbfFileNameWoExt );
- sDbfFileNameWoExt.PadRight( ' ', 8 ); // need at least eight bytes of name
- sDbfFileNameWoExt = sDbfFileNameWoExt.Mid( 1, 8 ); // need no more than eight bytes of name
-
- try{
- if(( rc = xbFseek( 8, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- for( int i = 1; i < 9; i++ ){
- if(( rc = xbFputc( sDbfFileNameWoExt[i] )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::UpdateHeaderName() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Update a memo field length for a given field number.
-/*!
- \param iFieldNo Field number to update data for.
- \param sMemoData Data to update memo field data with.
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::UpdateMemoField( xbInt16 iFieldNo, const xbString & sMemoData ) {
-
- xbInt16 iErrorStop = 0;
- xbInt16 rc = XB_NO_ERROR;
- xbUInt32 ulBlockNo;
-
- try{
-
- if(( rc = dbf->GetULongField( iFieldNo, ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 100;
- throw rc;
- }
-
- if( sMemoData == "" ){
- if( ulBlockNo == 0 ){
- /* if nothing to do, return */
- return XB_NO_ERROR;
- } else {
-
- // if this is in the new blocks link list already, then this is not the first update for this memo field
- // this would be second or third update on the field since the original change and not commited
- // Since it won't be needed in either a Commmit() or Abort(), can be freed immediately
- if( llNewBlocks.SearchFor( ulBlockNo ) > 0 ){
- if(( rc = FreeMemoBlockChain( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 110;
- throw rc;
- }
- if(( llNewBlocks.RemoveByVal( ulBlockNo )) < XB_NO_ERROR ){
- iErrorStop = 120;
- throw rc;
- }
- } else {
- // first revision, save what it was in case of Abort() command
- if(( llOldBlocks.InsertAtFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 130;
- throw rc;
- }
- }
- if(( rc = dbf->PutField( iFieldNo, "" )) != XB_NO_ERROR ){
- iErrorStop = 140;
- throw rc;
- }
- }
- } else {
- // free up the old space
- xbUInt32 ulLastDataBlock = 0L;
-
- if( ulBlockNo > 0 ){
- if( llNewBlocks.SearchFor( ulBlockNo ) > 0 ){
-
- if(( rc = FreeMemoBlockChain( ulBlockNo, ulLastDataBlock )) != XB_NO_ERROR ){
- iErrorStop = 150;
- throw rc;
- }
- } else {
- // first revision, save what it was in case of Abort() command
- if(( rc = llOldBlocks.InsertAtFront( ulBlockNo )) != XB_NO_ERROR ){
- iErrorStop = 160;
- throw rc;
- }
- }
- }
- // should next line be unsigned 32 bit int?
- xbUInt32 ulTotalLen = 8 + sMemoData.Len();
- xbUInt32 ulBlocksNeeded;
- if( ulTotalLen % GetBlockSize())
- ulBlocksNeeded = ulTotalLen / GetBlockSize() + 1;
- else
- ulBlocksNeeded = ulTotalLen / GetBlockSize();
-
- xbBool bUsedBlockFound;
- xbUInt32 ulHeadBlock;
- xbUInt32 ulPrevNode;
- if(( rc = FindBlockSetInChain( ulBlocksNeeded, ulLastDataBlock, ulHeadBlock, ulPrevNode, bUsedBlockFound )) != XB_NO_ERROR ){
- iErrorStop = 170;
- throw rc;
- }
- iField1 = -1;
- iStartPos = 8;
- ulFieldLen = sMemoData.Len() + 8;
-
- if( bUsedBlockFound ){
-
- if(( rc = GetBlockSetFromChain( ulBlocksNeeded, ulHeadBlock, ulPrevNode )) != XB_NO_ERROR ){
- iErrorStop = 180;
- throw rc;
- }
-
- if(( rc = WriteBlockHeader( ulHeadBlock, 1 )) != XB_NO_ERROR ){
- iErrorStop = 190;
- throw rc;
- }
-
- if(( rc = xbFwrite( sMemoData.Str(), sMemoData.Len(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 200;
- throw rc;
- }
- } else { // append to the end
-
- if(( rc = WriteBlockHeader( ulLastDataBlock, 1 )) != XB_NO_ERROR ){
- iErrorStop = 220;
- throw rc;
- }
-
- if(( rc = xbFwrite( sMemoData.Str(), sMemoData.Len(), 1 )) != XB_NO_ERROR ){
- iErrorStop = 230;
- throw rc;
- }
-
- if(( rc = xbFputc( 0x00, (xbInt32)((ulBlocksNeeded * GetBlockSize()) - (sMemoData.Len() + 8)))) != XB_NO_ERROR ){
- iErrorStop = 240;
- throw rc;
- }
-
- if( ulLastDataBlock == ulHdrNextBlock ){ // this is first node to be added to the node chain
- ulHdrNextBlock += ulBlocksNeeded;
- ulHeadBlock = ulLastDataBlock;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR ){
- iErrorStop = 250;
- throw rc;
- }
-
- } else { // adding memo data to the end of the file, but chain exists
-
- ulNextFreeBlock = ulLastDataBlock + ulBlocksNeeded;
- ulHeadBlock = ulLastDataBlock;
- if(( rc = WriteBlockHeader( ulPrevNode, 2 )) != XB_NO_ERROR ){
- iErrorStop = 260;
- throw rc;
- }
- }
- }
-
- if(( rc = llNewBlocks.InsertAtFront( ulHeadBlock )) != XB_NO_ERROR ){ // In case of Abort(), this block needs to be freed
- iErrorStop = 270;
- throw rc;
- }
- if(( rc = dbf->PutLongField( iFieldNo, (xbInt32) ulHeadBlock )) != XB_NO_ERROR ){
- iErrorStop = 280;
- throw rc;
- }
- }
- }
-
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::UpdateMemoField() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Write block header.
-/*!
- \param ulBlockNo Block to read
- \param iOption 1 - Read fields option 1
- 2 - Read fields option 2
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-
-xbInt16 xbMemoDbt4::WriteBlockHeader( xbUInt32 ulBlockNo, xbInt16 iOption ) {
-
- xbInt16 rc = XB_NO_ERROR;
- xbInt16 iErrorStop = 0;
-
- try{
- if( iOption == 1 ){
- ePutInt16 ((char *) mbb, iField1 );
- ePutInt16 ((char *) mbb+2, iStartPos );
- ePutUInt32((char *) mbb+4, ulFieldLen );
- }
- else if( iOption == 2 ){
- ePutUInt32((char *) mbb, ulNextFreeBlock );
- ePutUInt32((char *) mbb+4, ulFreeBlockCnt );
- }
- else{
- iErrorStop = 100;
- rc = XB_INVALID_OPTION;
- throw rc;
- }
-
- if(( rc = WriteBlock( ulBlockNo, 8, mbb )) != XB_NO_ERROR ){
- iErrorStop = 110;
- rc = XB_READ_ERROR;
- }
- }
- catch (xbInt16 rc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::WriteHeader() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, rc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( rc ));
- }
- return rc;
-}
-/***********************************************************************/
-//! @brief Empty the memo file.
-/*!
- \returns <a href="xbretcod_8h.html">Return Codes</a>
-*/
-xbInt16 xbMemoDbt4::Zap(){
-
- xbInt16 iRc = 0;
- xbInt16 iErrorStop = 0;
- char cBuf[4];
- try{
- ulHdrNextBlock = 1L;
- ePutUInt32( cBuf, ulHdrNextBlock );
-
- if(( iRc != xbFseek( 0, SEEK_SET )) != XB_NO_ERROR ){
- iErrorStop = 100;
- throw iRc;
- }
- if(( iRc != xbFwrite( cBuf, 4, 1 ))!= XB_NO_ERROR ){
- iErrorStop = 110;
- throw iRc;
- }
- if(( iRc != xbTruncate( GetBlockSize())) != XB_NO_ERROR ){
- iErrorStop = 120;
- throw iRc;
- }
- }
-
- catch (xbInt16 iRc ){
- xbString sMsg;
- sMsg.Sprintf( "xbMemoDbt4::Zap() Exception Caught. Error Stop = [%d] rc = [%d]", iErrorStop, iRc );
- xbase->WriteLogMessage( sMsg.Str() );
- xbase->WriteLogMessage( GetErrorMessage( iRc ));
- }
- return iRc;
-}/***********************************************************************/
-} /* namespace */
-#endif /* XB_DBF4_SUPPORT */
-#endif /* XB_MEMO_SUPPORT */
-