/* xbmemo.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
Base memo class
*/
#include "xbase.h"
#ifdef XB_MEMO_SUPPORT
namespace xb{
/***********************************************************************/
//! @brief Class Constructor.
/*!
\param dbf Pointer to dbf construct.
\param sFileName Memo file name.
*/
xbMemo::xbMemo( xbDbf * dbf, xbString const &sFileName ) : xbFile( dbf->GetXbasePtr() ) {
this->dbf = dbf; /* pointer to the associated dbf class instance */
// xbase = dbf->GetXbasePtr(); /* pointer to the engine */
SetDirectory( dbf->GetDirectory());
SetFileName( sFileName );
mbb = NULL;
#ifdef XB_LOCKING_SUPPORT
bFileLocked = xbFalse;
#endif
}
/***********************************************************************/
//! @brief Class Destructor.
xbMemo::~xbMemo(){
if( mbb )
free( mbb );
}
/***********************************************************************/
//! @brief Calculate the last data block number.
/*!
\param ulLastDataBlock Output - Last used block number in the file.
\returns Return Codes
*/
xbInt16 xbMemo::CalcLastDataBlock( xbUInt32 & ulLastDataBlock ){
xbInt16 iRc = XB_NO_ERROR;
if(( iRc = xbFseek( 0, SEEK_END )) != XB_NO_ERROR )
return iRc;
ulLastDataBlock = (xbUInt32) xbFtell() / (xbUInt32) GetBlockSize();
return XB_NO_ERROR;
}
/***********************************************************************/
//! @brief Close the memo file.
/*!
\returns Return Codes
*/
xbInt16 xbMemo::CloseMemoFile(){
if( mbb ){
free( mbb );
mbb = NULL;
}
return xbFclose();
}
/***********************************************************************/
//! @brief Get memo file type.
/*!
\returns 3 - Version 3 memo file.
4 - Version 4 memo file.
*/
xbInt16 xbMemo::GetMemoFileType(){
return iMemoFileType;
}
/***********************************************************************/
//! @brief Get next block available from file header.
/*!
\param ulBlockNo Output - Next block number for appending data to memo file.
\returns Return Codes
*/
xbInt16 xbMemo::GetHdrNextBlock( xbUInt32 & ulBlockNo ){
xbInt16 iRc = XB_NO_ERROR;
xbInt16 iErrorStop = 0;
try{
if(( iRc = ReadDbtHeader( 0 )) != XB_NO_ERROR ){
iErrorStop = 10;
throw iRc;
}
ulBlockNo = ulHdrNextBlock;
}
catch (xbInt16 iRc ){
xbString sMsg;
sMsg.Sprintf( "xbmemo::GetNextAvailableBlock() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
xbase->WriteLogMessage( sMsg.Str() );
xbase->WriteLogMessage( GetErrorMessage( iRc ));
}
return iRc;
}
/***********************************************************************/
#ifdef XB_LOCKING_SUPPORT
//! @brief Lock memo file
/*!
\param iLockFunction XB_LOCK
XB_UNLOCK
\returns Return Codes
*/
xbInt16 xbMemo::LockMemo( xbInt16 iLockFunction ){
xbInt16 iRc = XB_NO_ERROR;
xbInt16 iErrorStop = 0;
try{
if( iLockFunction == XB_LOCK ){
if( bFileLocked ) // already locked
return XB_NO_ERROR;
if( dbf->GetLockFlavor() == LK_DBASE ){
iRc = xbLock( XB_LOCK, LK4026531838, 1 );
if( iRc != XB_NO_ERROR ){
if( iRc == XB_LOCK_FAILED )
return iRc;
else {
iErrorStop = 120;
throw iRc;
}
} else {
bFileLocked = xbTrue;
}
}
} else if( iLockFunction == XB_UNLOCK ){
if( !bFileLocked ) // already unlocked
return XB_NO_ERROR;
if( dbf->GetLockFlavor() == LK_DBASE ){
iRc = xbLock( XB_UNLOCK, LK4026531838, 1 );
if( iRc != XB_NO_ERROR ){
if( iRc == XB_LOCK_FAILED )
return iRc;
else {
iErrorStop = 140;
throw iRc;
}
} else {
bFileLocked = xbFalse;
}
}
} else {
iErrorStop = 300;
iRc = XB_INVALID_OPTION;
throw iRc;
}
}
catch (xbInt16 iRc ){
xbString sMsg;
sMsg.Sprintf( "xbmemo::LockMemoFile() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
xbase->WriteLogMessage( sMsg.Str() );
xbase->WriteLogMessage( GetErrorMessage( iRc ));
}
return iRc;
}
/***********************************************************************/
//! @brief Get memo file lock status.
/*!
\returns xbTrue - Memo file is locked.
xbFalse - Memo file is not locked.
*/
xbBool xbMemo::GetMemoLocked() const {
return bFileLocked;
}
#endif
/***********************************************************************/
//! @brief Update Next Node number in file header
/*!
\returns Return Codes
*/
xbInt16 xbMemo::UpdateHeadNextNode(){
xbInt16 iRc = XB_NO_ERROR;
xbInt16 iErrorStop = 0;
try{
char buf[4];
ePutUInt32( buf, ulHdrNextBlock );
if(( iRc = xbFseek( 0, SEEK_SET )) != XB_NO_ERROR ){
iErrorStop = 10;
throw iRc;
}
if(( iRc = xbFwrite( &buf, 4, 1 )) != XB_NO_ERROR ){
iErrorStop = 20;
throw iRc;
}
}
catch (xbInt16 iRc ){
xbString sMsg;
sMsg.Sprintf( "xbmemo::UpdateHeadeNextNode() Exception Caught. Error Stop = [%d] iRc = [%d]", iErrorStop, iRc );
xbase->WriteLogMessage( sMsg.Str() );
xbase->WriteLogMessage( GetErrorMessage( iRc ));
}
return iRc;
}
/***********************************************************************/
} /* namespace */
#endif /* XB_MEMO_SUPPORT */