Files
harbour-core/harbour/source/rdd/dbfcdx/dbfcdx1.c
2000-03-21 11:51:27 +00:00

945 lines
28 KiB
C

/*
* $Id$
*/
/*
* Harbour Project source code:
* DBFCDX RDD
*
* Copyright 1999 Bruno Cantero <bruno@issnet.net>
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
#define SUPERTABLE ( &cdxSuper )
#include <time.h>
#include "hbapi.h"
#include "hbinit.h"
#include "hbapiitm.h"
#include "hbapirdd.h"
#include "rddsys.ch"
#include "hbapierr.h"
#include "hbapilng.h"
typedef struct _DBFHEADER
{
BYTE bVersion;
BYTE bYear;
BYTE bMonth;
BYTE bDay;
ULONG ulRecords;
USHORT uiHeaderLen;
USHORT uiRecordLen;
BYTE bReserved1[ 16 ];
BYTE bHasTag;
BYTE bReserved2[ 3 ];
} DBFHEADER;
typedef DBFHEADER * LPDBFHEADER;
typedef struct _DBFFIELD
{
BYTE bName[ 11 ];
BYTE bType;
BYTE bReserved1[ 4 ];
BYTE bLen;
BYTE bDec;
BYTE bReserved2[ 13 ];
BYTE bHasTag;
} DBFFIELD;
typedef DBFFIELD * LPDBFFIELD;
typedef struct
{
ULONG lNextBlock;
ULONG lBlockSize;
} MEMOHEADER;
typedef MEMOHEADER * LPMEMOHEADER;
typedef struct _DBFMEMO
{
BOOL fChanged; /* Memo status */
BYTE * pData; /* Memo data */
USHORT uiLen; /* Len of data */
} DBFMEMO;
typedef DBFMEMO * LPDBFMEMO;
HB_FUNC( _DBFCDX );
HB_FUNC( DBFCDX_GETFUNCTABLE );
HB_INIT_SYMBOLS_BEGIN( dbfcdx1__InitSymbols )
{ "_DBFCDX", HB_FS_PUBLIC, HB_FUNCNAME( _DBFCDX ), NULL },
{ "DBFCDX_GETFUNCTABLE", HB_FS_PUBLIC, HB_FUNCNAME( DBFCDX_GETFUNCTABLE ), NULL }
HB_INIT_SYMBOLS_END( dbfcdx1__InitSymbols )
#if ! defined(__GNUC__) && ! defined(_MSC_VER)
#pragma startup dbfcdx1__InitSymbols
#endif
#define LOCK_START 0x40000000L
#define LOCK_APPEND 0x7FFFFFFEL
#define LOCK_FILE 0x3FFFFFFFL
#define MEMO_BLOCK 64
#define CDX_MAX_KEY 240
static RDDFUNCS cdxSuper = { 0 };
static BOOL hb_nltoa( LONG lValue, char * szBuffer, USHORT uiLen )
{
LONG lAbsNumber;
int iCount, iPos;
HB_TRACE(HB_TR_DEBUG, ("hb_nltoa(%ld, %p, %hu)", lValue, szBuffer, uiLen));
lAbsNumber = ( lValue > 0 ) ? lValue : - lValue;
iCount = iPos = uiLen;
while( iCount-- > 0 )
{
szBuffer[ iCount ] = ( '0' + lAbsNumber % 10 );
lAbsNumber /= 10;
}
if( lAbsNumber > 0 )
{
memset( szBuffer, ' ', uiLen );
return FALSE;
}
uiLen--;
for( iCount = 0; iCount < uiLen; iCount++ )
if( szBuffer[ iCount ] == '0' )
szBuffer[ iCount ] = ' ';
else
break;
if( lValue < 0 )
{
if( szBuffer[ 0 ] != ' ' )
{
memset( szBuffer, ' ', iPos );
return FALSE;
}
for( iCount = uiLen; iCount >= 0; iCount-- )
{
if( szBuffer[ iCount ] == ' ' )
{
szBuffer[ iCount ] = '-';
break;
}
}
}
return TRUE;
}
static ULONG hb_cdxSwapBytes( ULONG ulValue )
{
BYTE * pValue, pByte;
HB_TRACE(HB_TR_DEBUG, ("hb_cdxSwapBytes(%lu)", ulValue));
pValue = ( BYTE * ) &ulValue;
pByte = pValue[ 0 ];
pValue[ 0 ] = pValue[ 3 ];
pValue[ 3 ] = pByte;
pByte = pValue[ 1 ];
pValue[ 1 ] = pValue[ 2 ];
pValue[ 2 ] = pByte;
return ulValue;
}
static void hb_cdxReadMemo( AREAP pArea, LPDBFMEMO pMemo, ULONG lMemoBlock )
{
ULONG ulSpaceUsed;
MEMOHEADER pMemoHeader;
HB_TRACE(HB_TR_DEBUG, ("hb_cdxReadMemo(%p, %p, %lu)", pArea, pMemo, lMemoBlock));
hb_fsSeek( pArea->lpDataInfo->pNext->hFile, lMemoBlock * MEMO_BLOCK, FS_SET );
hb_fsRead( pArea->lpDataInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) );
ulSpaceUsed = hb_cdxSwapBytes( pMemoHeader.lBlockSize );
if( pMemo->uiLen != ulSpaceUsed )
{
if( pMemo->uiLen > 0 )
pMemo->pData = ( BYTE * ) hb_xrealloc( pMemo->pData, ulSpaceUsed + 1 );
else
pMemo->pData = ( BYTE * ) hb_xgrab( ulSpaceUsed + 1 );
pMemo->uiLen = ( USHORT ) ulSpaceUsed;
}
hb_fsRead( pArea->lpDataInfo->pNext->hFile, pMemo->pData, pMemo->uiLen );
}
static BOOL hb_cdxWriteMemo( AREAP pArea, LPDBFMEMO pMemo, ULONG * lNewRecNo )
{
USHORT uiNumBlocks;
MEMOHEADER pMemoHeader;
BYTE * pBuffer;
HB_TRACE(HB_TR_DEBUG, ("hb_cdxWriteMemo(%p, %p, %p)", pArea, pMemo, lNewRecNo));
if( !pArea->lpExtendInfo->fExclusive && !pArea->lpDataInfo->fFileLocked &&
!hb_fsLock( pArea->lpDataInfo->pNext->hFile, LOCK_APPEND - 1, 1, FL_LOCK ) )
return FALSE;
uiNumBlocks = 1 + ( pMemo->uiLen + sizeof( MEMOHEADER ) ) / MEMO_BLOCK;
if( * lNewRecNo > 0 )
{
hb_fsSeek( pArea->lpDataInfo->pNext->hFile, * lNewRecNo * MEMO_BLOCK, FS_SET );
hb_fsRead( pArea->lpDataInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) );
if( pMemo->uiLen > hb_cdxSwapBytes( pMemoHeader.lBlockSize ) )
* lNewRecNo = 0; /* Not room for data */
}
if( * lNewRecNo == 0 ) /* Add an entry at eof */
{
hb_fsSeek( pArea->lpDataInfo->pNext->hFile, 0, FS_SET );
hb_fsRead( pArea->lpDataInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) );
* lNewRecNo = hb_cdxSwapBytes( pMemoHeader.lNextBlock );
pMemoHeader.lNextBlock = hb_cdxSwapBytes( * lNewRecNo + uiNumBlocks );
hb_fsSeek( pArea->lpDataInfo->pNext->hFile, 0, FS_SET );
hb_fsWrite( pArea->lpDataInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) );
}
hb_fsSeek( pArea->lpDataInfo->pNext->hFile, * lNewRecNo * MEMO_BLOCK, FS_SET );
pMemoHeader.lNextBlock = hb_cdxSwapBytes( 1 );
pMemoHeader.lBlockSize = hb_cdxSwapBytes( pMemo->uiLen );
hb_fsWrite( pArea->lpDataInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) );
if( hb_fsWrite( pArea->lpDataInfo->pNext->hFile, pMemo->pData,
pMemo->uiLen ) != pMemo->uiLen )
{
if( !pArea->lpExtendInfo->fExclusive && !pArea->lpDataInfo->fFileLocked )
hb_fsLock( pArea->lpDataInfo->pNext->hFile, LOCK_APPEND - 1, 1, FL_UNLOCK );
return FALSE;
}
uiNumBlocks = ( pMemo->uiLen + sizeof( MEMOHEADER ) ) % MEMO_BLOCK;
if( uiNumBlocks > 0 )
{
pBuffer = ( BYTE * ) hb_xgrab( MEMO_BLOCK );
memset( pBuffer, 0, MEMO_BLOCK );
hb_fsWrite( pArea->lpDataInfo->pNext->hFile, pBuffer, MEMO_BLOCK - uiNumBlocks );
hb_xfree( pBuffer);
}
if( !pArea->lpExtendInfo->fExclusive && !pArea->lpDataInfo->fFileLocked )
hb_fsLock( pArea->lpDataInfo->pNext->hFile, LOCK_APPEND - 1, 1, FL_UNLOCK );
return TRUE;
}
/*
* -- CDX METHODS --
*/
#define cdxBof NULL
#define cdxEof NULL
#define cdxFound NULL
#define cdxGoBottom NULL
#define cdxGoTo NULL
#define cdxGoToId NULL
#define cdxGoTop NULL
#define cdxSkip NULL
#define cdxSkipFilter NULL
#define cdxSkipRaw NULL
#define cdxAddField NULL
#define cdxAppend NULL
#define cdxCreateFields NULL
#define cdxDeleteRec NULL
#define cdxDeleted NULL
#define cdxFieldCount NULL
#define cdxFieldDisplay NULL
#define cdxFieldInfo NULL
#define cdxFieldName NULL
#define cdxFlush NULL
#define cdxGetRec NULL
#define cdxGetValue NULL
#define cdxGetVarLen NULL
#define cdxGoCold NULL
#define cdxGoHot NULL
#define cdxPutRec NULL
#define cdxPutValue NULL
#define cdxRecAll NULL
#define cdxRecCount NULL
#define cdxRecInfo NULL
#define cdxRecNo NULL
#define cdxSetFieldsExtent NULL
#define cdxAlias NULL
#define cdxClose NULL
#define cdxCreate NULL
#define cdxNewArea NULL
#define cdxOpen NULL
#define cdxRelease NULL
#define cdxStructSize NULL
#define cdxSysName NULL
#define cdxEval NULL
#define cdxPack NULL
#define cdxZap NULL
#define cdxOrderCondition NULL
#define cdxClearFilter NULL
#define cdxClearLocate NULL
#define cdxClearScope NULL
#define cdxCountScope NULL
#define cdxFilterText NULL
#define cdxScopeInfo NULL
#define cdxSetFilter NULL
#define cdxSetLocate NULL
#define cdxSetScope NULL
#define cdxSkipScope NULL
#define cdxCompile NULL
#define cdxError NULL
#define cdxEvalBlock NULL
#define cdxRawLock NULL
#define cdxLock NULL
#define cdxUnLock NULL
#define cdxCloseMemFile NULL
#define cdxReadDBHeader NULL
#define cdxWhoCares NULL
static ERRCODE cdxCreateMemFile( AREAP pArea, LPDBOPENINFO pCreateInfo )
{
LPFILEINFO lpMemInfo;
LPMEMOHEADER pMemoHeader;
BOOL bError;
PHB_ITEM pError = NULL;
HB_TRACE(HB_TR_DEBUG, ("cdxCreateMemFile(%p, %p)", pArea, pCreateInfo));
lpMemInfo = pArea->lpDataInfo->pNext;
do
{
lpMemInfo->hFile = hb_fsCreate( pCreateInfo->abName, FC_NORMAL );
if( lpMemInfo->hFile == FS_ERROR )
{
if( !pError )
{
pError = hb_errNew();
hb_errPutGenCode( pError, EG_CREATE );
hb_errPutSubCode( pError, 1005 );
hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_CREATE ) );
hb_errPutFileName( pError, ( char * ) pCreateInfo->abName );
hb_errPutFlags( pError, EF_CANRETRY );
}
bError = ( SELF_ERROR( pArea, pError ) == E_RETRY );
}
else
bError = FALSE;
} while( bError );
if( pError )
hb_errRelease( pError );
if( lpMemInfo->hFile == FS_ERROR )
return FAILURE;
pMemoHeader = ( LPMEMOHEADER ) hb_xgrab( 512 );
memset( pMemoHeader, 0, 512 );
pMemoHeader->lNextBlock = hb_cdxSwapBytes( 512 / MEMO_BLOCK );
pMemoHeader->lBlockSize = hb_cdxSwapBytes( MEMO_BLOCK );
bError = ( hb_fsWrite( lpMemInfo->hFile, ( BYTE * ) pMemoHeader, 512 ) != 512 );
hb_xfree( pMemoHeader );
hb_fsClose( lpMemInfo->hFile );
lpMemInfo->hFile = FS_ERROR;
if( bError )
return FAILURE;
else
return SUCCESS;
}
static ERRCODE cdxGetValueFile( AREAP pArea, USHORT uiIndex, void * pFile )
{
ULONG lRecNo, lNewRecNo;
BYTE * szText, szEndChar;
LPFIELD pField;
HB_TRACE(HB_TR_DEBUG, ("cdxGetValueFile(%p, %hu, %p)", pArea, uiIndex, pFile));
HB_SYMBOL_UNUSED( pFile );
if( uiIndex > pArea->uiFieldCount )
return FAILURE;
pField = pArea->lpFields + uiIndex - 1;
szText = pArea->lpExtendInfo->bRecord + pField->uiOffset;
if( !( ( LPDBFMEMO ) pField->memo )->pData )
memset( szText, ' ', pField->uiLen );
else
{
szEndChar = * ( szText + pField->uiLen );
* ( szText + pField->uiLen ) = 0;
lRecNo = atol( ( char * ) szText );
lNewRecNo = lRecNo;
if( !hb_cdxWriteMemo( pArea, ( LPDBFMEMO ) pField->memo, &lNewRecNo ) )
return FAILURE;
if( lNewRecNo != lRecNo )
hb_nltoa( lNewRecNo, ( char * ) szText, pField->uiLen );
* ( szText + pField->uiLen ) = szEndChar;
}
( ( LPDBFMEMO ) pField->memo )->fChanged = FALSE;
return SUCCESS;
}
static ERRCODE cdxInfo( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
{
HB_TRACE(HB_TR_DEBUG, ("cdxInfo(%p, %hu, %p)", pArea, uiIndex, pItem));
if( uiIndex == DBI_MEMOEXT )
{
hb_itemPutC( pItem, ".fpt" );
return SUCCESS;
}
return SUPER_INFO( pArea, uiIndex, pItem );
}
static ERRCODE cdxOpenMemFile( AREAP pArea, LPDBOPENINFO pOpenInfo )
{
LPFILEINFO lpMemInfo;
LPMEMOHEADER pMemoHeader;
USHORT uiFlags;
PHB_ITEM pError = NULL;
BOOL bRetry;
HB_TRACE(HB_TR_DEBUG, ("cdxOpenMemFile(%p, %p)", pArea, pOpenInfo));
lpMemInfo = pArea->lpDataInfo->pNext;
uiFlags = pOpenInfo->fReadonly ? FO_READ : FO_READWRITE;
uiFlags |= pOpenInfo->fShared ? FO_DENYNONE : FO_EXCLUSIVE;
do
{
lpMemInfo->hFile = hb_fsOpen( pOpenInfo->abName, uiFlags );
if( lpMemInfo->hFile == FS_ERROR )
{
if( !pError )
{
pError = hb_errNew();
hb_errPutGenCode( pError, EG_OPEN );
hb_errPutSubCode( pError, 1002 );
hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_OPEN ) );
hb_errPutFileName( pError, ( char * ) pOpenInfo->abName );
hb_errPutFlags( pError, EF_CANRETRY );
}
bRetry = ( SELF_ERROR( pArea, pError ) == E_RETRY );
}
else
bRetry = FALSE;
} while( bRetry );
if( pError )
hb_errRelease( pError );
if( lpMemInfo->hFile == FS_ERROR )
return FAILURE;
pMemoHeader = ( LPMEMOHEADER ) hb_xgrab( 512 );
if( hb_fsRead( lpMemInfo->hFile, ( BYTE * ) pMemoHeader, 512 ) != 512 )
{
hb_xfree( pMemoHeader );
return FAILURE;
}
hb_xfree( pMemoHeader );
return SUCCESS;
}
static ERRCODE cdxOrderCreate( AREAP pArea, LPDBORDERCREATEINFO pOrderInfo )
{
PHB_ITEM pExpr, pResult, pError;
HB_MACRO_PTR pMacro;
USHORT uiType, uiLen = 0;
char * szFileName;
PHB_FNAME pFileName;
DBORDERINFO pExtInfo;
HB_TRACE(HB_TR_DEBUG, ("cdxOrderCreate(%p, %p)", pArea, pOrderInfo));
if( SELF_GOCOLD( pArea ) == FAILURE )
return FAILURE;
/* If we have a codeblock for the expression, use it */
if( pOrderInfo->itmCobExpr )
pExpr = pOrderInfo->itmCobExpr;
else /* Otherwise, try compiling the key expression string */
{
if( SELF_COMPILE( pArea, ( BYTE * ) hb_itemGetCPtr( pOrderInfo->abExpr ) ) == FAILURE )
return FAILURE;
pExpr = pArea->valResult;
pArea->valResult = NULL;
}
/* Get a blank record before testing expression */
SELF_GOBOTTOM( pArea );
SELF_SKIP( pArea, 1 );
if( hb_itemType( pExpr ) == IT_BLOCK )
{
if( SELF_EVALBLOCK( pArea, pExpr ) == FAILURE )
return FAILURE;
pResult = pArea->valResult;
pArea->valResult = NULL;
}
else
{
pMacro = ( HB_MACRO_PTR ) hb_itemGetPtr( pExpr );
hb_macroRun( pMacro );
hb_macroDelete( pMacro );
pResult = pExpr;
hb_itemCopy( pResult, &hb_stack.Return );
}
uiType = hb_itemType( pResult );
switch( uiType )
{
case IT_INTEGER:
case IT_LONG:
case IT_DOUBLE:
uiLen = 10;
break;
case IT_DATE:
uiLen = 8;
break;
case IT_LOGICAL:
uiLen = 1;
break;
case IT_STRING:
uiLen = ( hb_itemGetCLen( pResult ) > CDX_MAX_KEY ) ? CDX_MAX_KEY :
( USHORT ) hb_itemGetCLen( pResult );
break;
}
hb_itemRelease( pResult );
/* Make sure uiLen is not 0 */
if( !uiLen )
{
pError = hb_errNew();
hb_errPutGenCode( pError, EG_DATAWIDTH );
hb_errPutSubCode( pError, 1026 );
hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_DATAWIDTH ) );
SELF_ERROR( pArea, pError );
hb_errRelease( pError );
return FAILURE;
}
/* Check conditional expression */
pExpr = NULL;
if( pArea->lpdbOrdCondInfo )
{
/* If we have a codeblock for the conditional expression, use it */
if( pArea->lpdbOrdCondInfo->itmCobFor )
pExpr = pArea->lpdbOrdCondInfo->itmCobFor;
else /* Otherwise, try compiling the conditional expression string */
{
if( SELF_COMPILE( pArea, pArea->lpdbOrdCondInfo->abFor ) == FAILURE )
return FAILURE;
pExpr = pArea->valResult;
pArea->valResult = NULL;
}
}
/* Test conditional expression */
if( pExpr )
{
if( hb_itemType( pExpr ) == IT_BLOCK )
{
if( SELF_EVALBLOCK( pArea, pExpr ) == FAILURE )
return FAILURE;
pResult = pArea->valResult;
}
else
{
pMacro = ( HB_MACRO_PTR ) hb_itemGetPtr( pExpr );
hb_macroRun( pMacro );
hb_macroDelete( pMacro );
pResult = pExpr;
hb_itemCopy( pResult, &hb_stack.Return );
}
uiType = hb_itemType( pResult );
hb_itemRelease( pResult );
if( uiType != IT_LOGICAL )
return FAILURE;
}
/* Check file name */
szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 );
szFileName[ 0 ] = '\0';
if( strlen( ( char * ) pOrderInfo->abBagName ) == 0 )
{
pFileName = hb_fsFNameSplit( pArea->lpDataInfo->szFileName );
if( pFileName->szDrive )
strcat( szFileName, pFileName->szDrive );
if( pFileName->szPath )
strcat( szFileName, pFileName->szPath );
strcat( szFileName, pFileName->szName );
pExtInfo.itmResult = hb_itemPutC( NULL, "" );
SELF_ORDINFO( pArea, DBOI_BAGEXT, &pExtInfo );
strcat( szFileName, hb_itemGetCPtr( pExtInfo.itmResult ) );
hb_itemRelease( pExtInfo.itmResult );
}
else
{
strcpy( szFileName, ( char * ) pOrderInfo->abBagName );
pFileName = hb_fsFNameSplit( szFileName );
if( !pFileName->szExtension )
{
pExtInfo.itmResult = hb_itemPutC( NULL, "" );
SELF_ORDINFO( pArea, DBOI_BAGEXT, &pExtInfo );
strcat( szFileName, hb_itemGetCPtr( pExtInfo.itmResult ) );
hb_itemRelease( pExtInfo.itmResult );
}
}
hb_xfree( pFileName );
/* TODO:
open szFileName
if error
create szFileName
create new tag index
else
find tag index
if not found
create new tag index
else
overwrite tag index
go top
while not eof
add key
skip
*/
hb_xfree( szFileName );
/* Clear pArea->lpdbOrdCondInfo */
SELF_ORDSETCOND( pArea, NULL );
return SELF_GOTOP( pArea );
}
static ERRCODE cdxOrderDestroy( AREAP pArea, LPDBORDERINFO pOrderInfo )
{
HB_TRACE(HB_TR_DEBUG, ("cdxOrderDestroy(%p, %p)", pArea, pOrderInfo));
HB_SYMBOL_UNUSED( pArea );
HB_SYMBOL_UNUSED( pOrderInfo );
return SUCCESS;
}
static ERRCODE cdxOrderInfo( AREAP pArea, USHORT uiIndex, LPDBORDERINFO pInfo )
{
HB_TRACE(HB_TR_DEBUG, ("cdxOrderInfo(%p, %hu, %p)", pArea, uiIndex, pInfo));
HB_SYMBOL_UNUSED( pArea );
switch( uiIndex )
{
case DBOI_BAGEXT:
hb_itemPutC( pInfo->itmResult, ".cdx" );
break;
}
return SUCCESS;
}
static ERRCODE cdxOrderListAdd( AREAP pArea, LPDBORDERINFO pOrderInfo )
{
HB_TRACE(HB_TR_DEBUG, ("cdxOrderListAdd(%p, %p)", pArea, pOrderInfo));
HB_SYMBOL_UNUSED( pArea );
HB_SYMBOL_UNUSED( pOrderInfo );
return SUCCESS;
}
static ERRCODE cdxOrderListClear( AREAP pArea )
{
HB_TRACE(HB_TR_DEBUG, ("cdxOrderListClear(%p)", pArea));
HB_SYMBOL_UNUSED( pArea );
return SUCCESS;
}
static ERRCODE cdxOrderListFocus( AREAP pArea, LPDBORDERINFO pOrderInfo )
{
HB_TRACE(HB_TR_DEBUG, ("cdxOrderListFocus(%p, %p)", pArea, pOrderInfo));
HB_SYMBOL_UNUSED( pArea );
HB_SYMBOL_UNUSED( pOrderInfo );
return SUCCESS;
}
static ERRCODE cdxOrderListRebuild( AREAP pArea )
{
HB_TRACE(HB_TR_DEBUG, ("cdxOrderListRebuild(%p)", pArea));
HB_SYMBOL_UNUSED( pArea );
return SUCCESS;
}
static ERRCODE cdxPutValueFile( AREAP pArea, USHORT uiIndex, void * pFile )
{
LPFIELD pField;
BYTE * szText, szEndChar;
ULONG lMemoBlock;
HB_TRACE(HB_TR_DEBUG, ("cdxPutValueFile(%p, %hu, %p)", pArea, uiIndex, pFile));
HB_SYMBOL_UNUSED( pFile );
if( uiIndex > pArea->uiFieldCount )
return FAILURE;
pField = pArea->lpFields + uiIndex - 1;;
szText = pArea->lpExtendInfo->bRecord + pField->uiOffset;
szEndChar = * ( szText + pField->uiLen );
* ( szText + pField->uiLen ) = 0;
lMemoBlock = atol( ( char * ) szText ) * MEMO_BLOCK;
* ( szText + pField->uiLen ) = szEndChar;
if( lMemoBlock > 0 )
hb_cdxReadMemo( pArea, ( LPDBFMEMO ) pField->memo, lMemoBlock );
else if( ( ( LPDBFMEMO ) pField->memo )->pData )
{
hb_xfree( ( ( LPDBFMEMO ) pField->memo )->pData );
memset( pField->memo, 0, sizeof( DBFMEMO ) );
}
return SUCCESS;
}
static ERRCODE cdxSeek( AREAP pArea, BOOL bSoftSeek, PHB_ITEM pKey, BOOL bFindLast )
{
HB_TRACE(HB_TR_DEBUG, ("cdxSeek(%p, %d, %p, %d)", pArea, bSoftSeek, pKey, bFindLast));
HB_SYMBOL_UNUSED( pArea );
HB_SYMBOL_UNUSED( bSoftSeek );
HB_SYMBOL_UNUSED( pKey );
HB_SYMBOL_UNUSED( bFindLast );
return SUCCESS;
}
static ERRCODE cdxWriteDBHeader( AREAP pArea )
{
DBFHEADER pHeader;
DBFFIELD pDBField;
USHORT uiCount;
LPFIELD pField;
time_t t;
struct tm * pTime;
HB_TRACE(HB_TR_DEBUG, ("cdxWriteDBHeader(%p)", pArea));
memset( &pHeader, 0, sizeof( DBFHEADER ) );
pHeader.uiRecordLen = 1;
pHeader.bVersion = 0x03;
pField = pArea->lpFields;
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
switch( pField->uiType )
{
case 'C':
case 'N':
pHeader.uiRecordLen += pField->uiLen;
break;
case 'M':
pHeader.uiRecordLen += 10;
pHeader.bVersion = 0xF5;
pArea->lpExtendInfo->fHasMemo = TRUE;
break;
case 'D':
pHeader.uiRecordLen += 8;
break;
case 'L':
pHeader.uiRecordLen += 1;
break;
}
pField++;
}
time( &t );
pTime = localtime( &t );
pHeader.bYear = ( BYTE ) pTime->tm_year;
pHeader.bMonth = ( BYTE ) pTime->tm_mon + 1;
pHeader.bDay = ( BYTE ) pTime->tm_mday;
pHeader.uiHeaderLen = ( USHORT ) ( 32 * ( pArea->uiFieldCount + 1 ) + 1 );
pHeader.bHasTag = 0;
pHeader.ulRecords = 0;
if( hb_fsWrite( pArea->lpDataInfo->hFile, ( BYTE * ) &pHeader,
sizeof( DBFHEADER ) ) != sizeof( DBFHEADER ) )
return FAILURE;
pField = pArea->lpFields;
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
memset( &pDBField, 0, sizeof( DBFFIELD ) );
strncpy( ( char * ) pDBField.bName, ( ( PHB_DYNS ) pField->sym )->pSymbol->szName,
sizeof( pDBField.bName ) );
pDBField.bType = ( BYTE ) pField->uiType;
switch( pDBField.bType )
{
case 'C':
pDBField.bLen = pField->uiLen & 0xFF;
pDBField.bDec = pField->uiLen >> 8;
break;
case 'M':
pDBField.bLen = 10;
pDBField.bDec = 0;
break;
case 'D':
pDBField.bLen = 8;
pDBField.bDec = 0;
break;
case 'L':
pDBField.bLen = 1;
pDBField.bDec = 0;
break;
case 'N':
pDBField.bLen = ( BYTE ) pField->uiLen;
pDBField.bDec = ( BYTE ) pField->uiDec;
break;
}
if( hb_fsWrite( pArea->lpDataInfo->hFile, ( BYTE * ) &pDBField,
sizeof( DBFFIELD ) ) != sizeof( DBFFIELD ) )
return FAILURE;
pField++;
}
if( hb_fsWrite( pArea->lpDataInfo->hFile, ( BYTE * ) "\15\32", 2 ) != 2 )
return FAILURE;
return SUCCESS;
}
static RDDFUNCS cdxTable = { cdxBof,
cdxEof,
cdxFound,
cdxGoBottom,
cdxGoTo,
cdxGoToId,
cdxGoTop,
cdxSeek,
cdxSkip,
cdxSkipFilter,
cdxSkipRaw,
cdxAddField,
cdxAppend,
cdxCreateFields,
cdxDeleteRec,
cdxDeleted,
cdxFieldCount,
cdxFieldDisplay,
cdxFieldInfo,
cdxFieldName,
cdxFlush,
cdxGetRec,
cdxGetValue,
cdxGetVarLen,
cdxGoCold,
cdxGoHot,
cdxPutRec,
cdxPutValue,
cdxRecAll,
cdxRecCount,
cdxRecInfo,
cdxRecNo,
cdxSetFieldsExtent,
cdxAlias,
cdxClose,
cdxCreate,
cdxInfo,
cdxNewArea,
cdxOpen,
cdxRelease,
cdxStructSize,
cdxSysName,
cdxEval,
cdxPack,
cdxZap,
cdxOrderListAdd,
cdxOrderListClear,
cdxOrderListFocus,
cdxOrderListRebuild,
cdxOrderCondition,
cdxOrderCreate,
cdxOrderDestroy,
cdxOrderInfo,
cdxClearFilter,
cdxClearLocate,
cdxClearScope,
cdxCountScope,
cdxFilterText,
cdxScopeInfo,
cdxSetFilter,
cdxSetLocate,
cdxSetScope,
cdxSkipScope,
cdxCompile,
cdxError,
cdxEvalBlock,
cdxRawLock,
cdxLock,
cdxUnLock,
cdxCloseMemFile,
cdxCreateMemFile,
cdxGetValueFile,
cdxOpenMemFile,
cdxPutValueFile,
cdxReadDBHeader,
cdxWriteDBHeader,
cdxWhoCares
};
HB_FUNC( _DBFCDX )
{
}
HB_FUNC( DBFCDX_GETFUNCTABLE )
{
RDDFUNCS * pTable;
USHORT * uiCount;
uiCount = ( USHORT * ) hb_parnl( 1 );
* uiCount = RDDFUNCSCOUNT;
pTable = ( RDDFUNCS * ) hb_parnl( 2 );
if( pTable )
hb_retni( hb_rddInherit( pTable, &cdxTable, &cdxSuper, ( BYTE * ) "DBF" ) );
else
hb_retni( FAILURE );
}