ChangeLogTag:19990831-02:37 GMT+1 Bruno Cantero <bruno@issnet.net>

This commit is contained in:
Bruno Cantero
1999-08-31 00:54:41 +00:00
parent cb4b88ddc2
commit 33a3b2def3
5 changed files with 523 additions and 186 deletions

View File

@@ -1,3 +1,10 @@
19990831-02:37 GMT+1 Bruno Cantero <bruno@issnet.net>
* include/rddapi.h
source/rdd/dbcmd.c
source/rdd/dbf1.c
tests/working/testdbf.prg
* Full support for memo fields.
19990830-19:00 GMT+1 Victor Szel <info@szelvesz.hu>
* source/filesys.c

View File

@@ -195,6 +195,7 @@ typedef struct
BYTE * bRecord; /* Buffer of the data */
BOOL fHasMemo; /* Work Area with Memo fields */
ULONG lRecNo; /* Current record */
ULONG lNextBlock; /* Next block for memos */
BOOL fExclusive; /* Share the file */
BOOL fReadOnly; /* Read only file */
BYTE bYear; /* Last update */
@@ -484,6 +485,7 @@ typedef struct _FIELD
USHORT uiDec; /* Decimal length */
USHORT uiArea; /* Area this field resides in */
void * sym; /* Symbol that represents the field */
void * memo; /* Pointer to memo data */
struct _FIELD *lpfNext; /* The next field in the list */
} FIELD;
@@ -712,7 +714,9 @@ typedef struct _RDDFUNCS
DBENTRYP_VP createMemFile;
#if 0
DBENTRYP_SVPB getValueFile;
#endif
DBENTRYP_VP openMemFile;
#if 0
DBENTRYP_SVP putValueFile;
#endif

View File

@@ -437,7 +437,7 @@ static RDDFUNCS defTable = { Bof,
( DBENTRYP_VL ) UnSupported,
( DBENTRYP_UL ) UnSupported,
( DBENTRYP_VP ) UnSupported,
/*( DBENTRYP_VP ) UnSupported,*/
( DBENTRYP_VP ) UnSupported,
UnSupported,
UnSupported
};
@@ -1245,176 +1245,176 @@ HARBOUR HB_DBUNLOCKALL( void )
HARBOUR HB_DBUSEAREA( void )
{
// char * szDriver, * szFileName, * szAlias;
// WORD wLen;
// LPRDDNODE pRddNode;
// LPAREANODE pAreaNode;
// USHORT uiSize, uiRddID;
// DBOPENINFO pInfo;
// PHB_FNAME pFileName;
// PHB_ITEM pFileExt;
//
// bNetError = FALSE;
//
// if( hb_parl( 1 ) )
// hb_rddSelectFirstAvailable();
// else if( pCurrArea ) /* If current WorkArea is in use then close it */
// {
// SELF_CLOSE( ( AREAP ) pCurrArea->pArea );
// SELF_RELEASE( ( AREAP ) pCurrArea->pArea );
//
// if( pWorkAreas == pCurrArea ) /* Empty list */
// pWorkAreas = 0;
// else
// {
// if( pCurrArea->pPrev )
// pCurrArea->pPrev->pNext = pCurrArea->pNext;
// if( pCurrArea->pNext )
// pCurrArea->pNext->pPrev = pCurrArea->pPrev;
// }
//
// hb_xfree( pCurrArea->pArea );
// hb_xfree( pCurrArea );
// pCurrArea = 0;
// }
//
// hb_rddCheck();
// szDriver = hb_parc( 2 );
// if( ( wLen = strlen( szDriver ) ) > 0 )
// hb_strUpper( szDriver, wLen );
// else
// szDriver = szDefDriver;
//
// uiRddID = 0;
// pRddNode = hb_rddFindNode( szDriver, &uiRddID );
// if( !pRddNode )
// {
// hb_errRT_DBCMD( EG_ARG, 1015, 0, "DBUSEAREA" );
// return;
// }
//
// szFileName = hb_parc( 3 );
// if( strlen( szFileName ) == 0 )
// {
// hb_errRT_DBCMD( EG_ARG, 1005, 0, "DBUSEAREA" );
// return;
// }
//
// pFileName = hb_fsFNameSplit( szFileName );
// szAlias = hb_parc( 4 );
// if( strlen( szAlias ) == 0 )
// szAlias = pFileName->szName;
//
// /* Create a new WorkArea node */
//
// pCurrArea = ( LPAREANODE ) hb_xgrab( sizeof( AREANODE ) );
//
// if( pRddNode->uiAreaSize == 0 ) /* Calculate the size of WorkArea */
// {
// uiSize = sizeof( AREA ); /* Default Size Area */
// pCurrArea->pArea = ( AREAP ) hb_xgrab( uiSize );
// memset( pCurrArea->pArea, 0, uiSize );
// ( ( AREAP ) pCurrArea->pArea )->lprfsHost = &pRddNode->pTable;
//
// /* Need more space? */
// SELF_STRUCTSIZE( ( AREAP ) pCurrArea->pArea, &uiSize );
// if( uiSize > sizeof( AREA ) ) /* Size of Area changed */
// pCurrArea->pArea = ( AREAP ) hb_xrealloc( pCurrArea->pArea, uiSize );
//
// pRddNode->uiAreaSize = uiSize; /* Update the size of WorkArea */
// }
// else
// {
// pCurrArea->pArea = ( AREAP ) hb_xgrab( pRddNode->uiAreaSize );
// memset( pCurrArea->pArea, 0, pRddNode->uiAreaSize );
// ( ( AREAP ) pCurrArea->pArea )->lprfsHost = &pRddNode->pTable;
// }
//
// ( ( AREAP ) pCurrArea->pArea )->rddID = uiRddID;
//
// pCurrArea->pPrev = 0;
// pCurrArea->pNext = 0;
//
// SELF_NEW( ( AREAP ) pCurrArea->pArea );
//
// szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 );
// strcpy( szFileName, hb_parc( 3 ) );
// if( !pFileName->szExtension )
// {
// pFileExt = hb_itemPutC( 0, "" );
// SELF_INFO( ( AREAP ) pCurrArea->pArea, DBI_TABLEEXT, pFileExt );
// strcat( szFileName, pFileExt->item.asString.value );
// hb_itemRelease( pFileExt );
// }
// pInfo.uiArea = uiCurrArea;
// pInfo.abName = ( BYTE * ) szFileName;
// pInfo.atomAlias = ( BYTE * ) szAlias;
// pInfo.fShared = ISLOG( 5 ) ? hb_parl( 5 ) : !hb_set.HB_SET_EXCLUSIVE;
// pInfo.fReadonly = ISLOG( 6 ) ? hb_parl( 6 ) : FALSE;
//
// if( SELF_OPEN( ( AREAP ) pCurrArea->pArea, &pInfo ) == FAILURE )
// {
// SELF_RELEASE( ( AREAP ) pCurrArea->pArea );
// hb_xfree( pCurrArea->pArea );
// hb_xfree( pCurrArea );
// hb_xfree( szFileName );
// hb_xfree( pFileName );
// pCurrArea = 0;
// return;
// }
//
// if( ( ( AREAP ) pCurrArea->pArea )->lpExtendInfo->fHasMemo )
// {
// pFileExt = hb_itemPutC( 0, "" );
// SELF_INFO( ( AREAP ) pCurrArea->pArea, DBI_MEMOEXT, pFileExt );
// szFileName[ 0 ] = 0;
// if( pFileName->szPath )
// strcat( szFileName, pFileName->szPath );
// strcat( szFileName, pFileName->szName );
// strcat( szFileName, pFileExt->item.asString.value );
// pInfo.abName = ( BYTE * ) szFileName;
// hb_itemRelease( pFileExt );
// if( SELF_OPENMEMFILE( ( AREAP ) pCurrArea->pArea, &pInfo ) == FAILURE )
// {
// SELF_CLOSE( ( AREAP ) pCurrArea->pArea );
// SELF_RELEASE( ( AREAP ) pCurrArea->pArea );
// hb_xfree( pCurrArea->pArea );
// hb_xfree( pCurrArea );
// hb_xfree( szFileName );
// hb_xfree( pFileName );
// pCurrArea = 0;
// return;
// }
// }
//
// hb_xfree( szFileName );
// hb_xfree( pFileName );
// ( ( AREAP ) pCurrArea->pArea )->uiArea = uiCurrArea;
//
// /* Insert the new WorkArea node */
//
// if( !pWorkAreas )
// {
// pWorkAreas = pCurrArea; /* The new WorkArea node is the first */
// return;
// }
//
// pAreaNode = pWorkAreas;
// while( pAreaNode->pNext )
// {
// if( ( ( AREAP ) pAreaNode->pArea )->uiArea > uiCurrArea )
// {
// /* Insert the new WorkArea node */
// pCurrArea->pPrev = pAreaNode->pPrev;
// pCurrArea->pNext = pAreaNode;
// pAreaNode->pPrev = pCurrArea;
// if( pCurrArea->pPrev )
// pCurrArea->pPrev->pNext = pCurrArea;
// }
// pAreaNode = pAreaNode->pNext;
// }
// pAreaNode->pNext = pCurrArea; /* Append the new WorkArea node */
// pCurrArea->pPrev = pAreaNode;
char * szDriver, * szFileName, * szAlias;
WORD wLen;
LPRDDNODE pRddNode;
LPAREANODE pAreaNode;
USHORT uiSize, uiRddID;
DBOPENINFO pInfo;
PHB_FNAME pFileName;
PHB_ITEM pFileExt;
bNetError = FALSE;
if( hb_parl( 1 ) )
hb_rddSelectFirstAvailable();
else if( pCurrArea ) /* If current WorkArea is in use then close it */
{
SELF_CLOSE( ( AREAP ) pCurrArea->pArea );
SELF_RELEASE( ( AREAP ) pCurrArea->pArea );
if( pWorkAreas == pCurrArea ) /* Empty list */
pWorkAreas = 0;
else
{
if( pCurrArea->pPrev )
pCurrArea->pPrev->pNext = pCurrArea->pNext;
if( pCurrArea->pNext )
pCurrArea->pNext->pPrev = pCurrArea->pPrev;
}
hb_xfree( pCurrArea->pArea );
hb_xfree( pCurrArea );
pCurrArea = 0;
}
hb_rddCheck();
szDriver = hb_parc( 2 );
if( ( wLen = strlen( szDriver ) ) > 0 )
hb_strUpper( szDriver, wLen );
else
szDriver = szDefDriver;
uiRddID = 0;
pRddNode = hb_rddFindNode( szDriver, &uiRddID );
if( !pRddNode )
{
hb_errRT_DBCMD( EG_ARG, 1015, 0, "DBUSEAREA" );
return;
}
szFileName = hb_parc( 3 );
if( strlen( szFileName ) == 0 )
{
hb_errRT_DBCMD( EG_ARG, 1005, 0, "DBUSEAREA" );
return;
}
pFileName = hb_fsFNameSplit( szFileName );
szAlias = hb_parc( 4 );
if( strlen( szAlias ) == 0 )
szAlias = pFileName->szName;
/* Create a new WorkArea node */
pCurrArea = ( LPAREANODE ) hb_xgrab( sizeof( AREANODE ) );
if( pRddNode->uiAreaSize == 0 ) /* Calculate the size of WorkArea */
{
uiSize = sizeof( AREA ); /* Default Size Area */
pCurrArea->pArea = ( AREAP ) hb_xgrab( uiSize );
memset( pCurrArea->pArea, 0, uiSize );
( ( AREAP ) pCurrArea->pArea )->lprfsHost = &pRddNode->pTable;
/* Need more space? */
SELF_STRUCTSIZE( ( AREAP ) pCurrArea->pArea, &uiSize );
if( uiSize > sizeof( AREA ) ) /* Size of Area changed */
pCurrArea->pArea = ( AREAP ) hb_xrealloc( pCurrArea->pArea, uiSize );
pRddNode->uiAreaSize = uiSize; /* Update the size of WorkArea */
}
else
{
pCurrArea->pArea = ( AREAP ) hb_xgrab( pRddNode->uiAreaSize );
memset( pCurrArea->pArea, 0, pRddNode->uiAreaSize );
( ( AREAP ) pCurrArea->pArea )->lprfsHost = &pRddNode->pTable;
}
( ( AREAP ) pCurrArea->pArea )->rddID = uiRddID;
pCurrArea->pPrev = 0;
pCurrArea->pNext = 0;
SELF_NEW( ( AREAP ) pCurrArea->pArea );
szFileName = ( char * ) hb_xgrab( _POSIX_PATH_MAX + 3 );
strcpy( szFileName, hb_parc( 3 ) );
if( !pFileName->szExtension )
{
pFileExt = hb_itemPutC( 0, "" );
SELF_INFO( ( AREAP ) pCurrArea->pArea, DBI_TABLEEXT, pFileExt );
strcat( szFileName, pFileExt->item.asString.value );
hb_itemRelease( pFileExt );
}
pInfo.uiArea = uiCurrArea;
pInfo.abName = ( BYTE * ) szFileName;
pInfo.atomAlias = ( BYTE * ) szAlias;
pInfo.fShared = ISLOG( 5 ) ? hb_parl( 5 ) : !hb_set.HB_SET_EXCLUSIVE;
pInfo.fReadonly = ISLOG( 6 ) ? hb_parl( 6 ) : FALSE;
if( SELF_OPEN( ( AREAP ) pCurrArea->pArea, &pInfo ) == FAILURE )
{
SELF_RELEASE( ( AREAP ) pCurrArea->pArea );
hb_xfree( pCurrArea->pArea );
hb_xfree( pCurrArea );
hb_xfree( szFileName );
hb_xfree( pFileName );
pCurrArea = 0;
return;
}
if( ( ( AREAP ) pCurrArea->pArea )->lpExtendInfo->fHasMemo )
{
pFileExt = hb_itemPutC( 0, "" );
SELF_INFO( ( AREAP ) pCurrArea->pArea, DBI_MEMOEXT, pFileExt );
szFileName[ 0 ] = 0;
if( pFileName->szPath )
strcat( szFileName, pFileName->szPath );
strcat( szFileName, pFileName->szName );
strcat( szFileName, pFileExt->item.asString.value );
pInfo.abName = ( BYTE * ) szFileName;
hb_itemRelease( pFileExt );
if( SELF_OPENMEMFILE( ( AREAP ) pCurrArea->pArea, &pInfo ) == FAILURE )
{
SELF_CLOSE( ( AREAP ) pCurrArea->pArea );
SELF_RELEASE( ( AREAP ) pCurrArea->pArea );
hb_xfree( pCurrArea->pArea );
hb_xfree( pCurrArea );
hb_xfree( szFileName );
hb_xfree( pFileName );
pCurrArea = 0;
return;
}
}
hb_xfree( szFileName );
hb_xfree( pFileName );
( ( AREAP ) pCurrArea->pArea )->uiArea = uiCurrArea;
/* Insert the new WorkArea node */
if( !pWorkAreas )
{
pWorkAreas = pCurrArea; /* The new WorkArea node is the first */
return;
}
pAreaNode = pWorkAreas;
while( pAreaNode->pNext )
{
if( ( ( AREAP ) pAreaNode->pArea )->uiArea > uiCurrArea )
{
/* Insert the new WorkArea node */
pCurrArea->pPrev = pAreaNode->pPrev;
pCurrArea->pNext = pAreaNode;
pAreaNode->pPrev = pCurrArea;
if( pCurrArea->pPrev )
pCurrArea->pPrev->pNext = pCurrArea;
}
pAreaNode = pAreaNode->pNext;
}
pAreaNode->pNext = pCurrArea; /* Append the new WorkArea node */
pCurrArea->pPrev = pAreaNode;
}
HARBOUR HB_DELETED( void )

View File

@@ -51,9 +51,10 @@ typedef struct
typedef DBFHEADER * LPDBFHEADER;
typedef struct
{
LONG lNextBlock;
ULONG lNextBlock;
} MEMOHEADER;
typedef MEMOHEADER * LPMEMOHEADER;
@@ -73,6 +74,16 @@ typedef struct
typedef DBFFIELD * LPDBFFIELD;
typedef struct _DBFMEMO
{
BOOL fChanged; /* Memo status */
BYTE * pData; /* Memo data */
USHORT uiLen; /* Len of data */
} DBFMEMO;
typedef DBFMEMO * LPDBFMEMO;
HARBOUR HB__DBF( void );
HARBOUR HB_DBF_GETFUNCTABLE( void );
@@ -88,6 +99,7 @@ HB_INIT_SYMBOLS_END( dbf1__InitSymbols )
#define LOCK_FILE 0x3FFFFFFFL
#define MEMO_BLOCK 512
static BOOL hb_nltoa( LONG lValue, char * szBuffer, USHORT uiLen )
{
LONG lAbsNumber;
@@ -190,9 +202,63 @@ static BOOL hb_dbfUpdateHeader( AREAP pArea, ULONG lRecCount )
return TRUE;
}
static BOOL hb_dbfWriteMemo( AREAP pArea, LPDBFMEMO pMemo, ULONG * lNewRecNo )
{
USHORT uiNumBlocks, uiBytesRead, uiRead, uiCount;
BYTE szBuffer[ MEMO_BLOCK ];
MEMOHEADER pMemoHeader;
uiNumBlocks = ( pMemo->uiLen + MEMO_BLOCK - 1 ) / MEMO_BLOCK;
if( * lNewRecNo > 0 )
{
uiBytesRead = 0;
hb_fsSeek( pArea->lpFileInfo->pNext->hFile, * lNewRecNo * MEMO_BLOCK, FS_SET );
do
{
uiBytesRead += MEMO_BLOCK;
uiRead = hb_fsRead( pArea->lpFileInfo->pNext->hFile, szBuffer, MEMO_BLOCK );
if( !uiRead )
return FALSE;
for( uiCount = 0; uiCount < uiRead; uiCount++ )
if( szBuffer[ uiCount ] == 0x1A )
break;
} while( uiCount >= MEMO_BLOCK && szBuffer[ uiCount ] != 0x1A );
if( uiBytesRead <= pMemo->uiLen ) /* Not room for data */
* lNewRecNo = 0;
}
if( * lNewRecNo == 0 ) /* Add an entry at eof */
{
hb_fsSeek( pArea->lpFileInfo->pNext->hFile, 0, FS_SET );
if( hb_fsRead( pArea->lpFileInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) ) != sizeof( MEMOHEADER ) )
return FALSE;
* lNewRecNo = pMemoHeader.lNextBlock;
pMemoHeader.lNextBlock = * lNewRecNo + uiNumBlocks;
hb_fsSeek( pArea->lpFileInfo->pNext->hFile, 0, FS_SET );
hb_fsWrite( pArea->lpFileInfo->pNext->hFile, ( BYTE * ) &pMemoHeader,
sizeof( MEMOHEADER ) );
}
hb_fsSeek( pArea->lpFileInfo->pNext->hFile, * lNewRecNo * MEMO_BLOCK, FS_SET );
if( hb_fsWrite( pArea->lpFileInfo->pNext->hFile, pMemo->pData,
pMemo->uiLen ) != pMemo->uiLen )
return FALSE;
szBuffer[ 0 ] = 0x1A;
if( hb_fsWrite( pArea->lpFileInfo->pNext->hFile, szBuffer, 1 ) != 1 )
return FALSE;
return TRUE;
}
static BOOL hb_dbfUpdateRecord( AREAP pArea, ULONG lRecNo )
{
ULONG lRecCount;
ULONG lRecCount, lNewRecNo;
USHORT uiCount, uiOffset;
LPFIELD pField;
BYTE * szText, szEndChar;
if( SELF_RECCOUNT( pArea, &lRecCount ) == FAILURE )
return FALSE;
@@ -203,6 +269,39 @@ static BOOL hb_dbfUpdateRecord( AREAP pArea, ULONG lRecNo )
( lRecNo - 1 ) * pArea->lpExtendInfo->uiRecordLen, FS_SET );
if( pArea->lpFileInfo->fAppend )
lRecCount = lRecNo;
if( pArea->lpExtendInfo->fHasMemo )
{
uiOffset = 1;
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
pField = pArea->lpFields + uiCount;
if( pField->uiType == 'C' )
uiOffset += pField->uiLen + ( ( USHORT ) pField->uiDec << 8 );
else
{
if( pField->uiType == 'M' && ( ( LPDBFMEMO ) pField->memo )->fChanged )
{
szText = pArea->lpExtendInfo->bRecord + 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_dbfWriteMemo( pArea, ( LPDBFMEMO ) pField->memo, &lNewRecNo ) )
return FALSE;
if( lNewRecNo != lRecNo )
hb_nltoa( lNewRecNo, ( char * ) szText, pField->uiLen );
* ( szText + pField->uiLen ) = szEndChar;
}
( ( LPDBFMEMO ) pField->memo )->fChanged = FALSE;
}
uiOffset += pField->uiLen;
}
}
}
if( hb_fsWrite( pArea->lpFileInfo->hFile, pArea->lpExtendInfo->bRecord,
pArea->lpExtendInfo->uiRecordLen ) != pArea->lpExtendInfo->uiRecordLen ||
!hb_dbfUpdateHeader( pArea, lRecCount ) )
@@ -212,8 +311,86 @@ static BOOL hb_dbfUpdateRecord( AREAP pArea, ULONG lRecNo )
return TRUE;
}
static void hb_dbfClearBuffer( AREAP pArea )
{
LPFIELD pField;
USHORT uiCount;
memset( pArea->lpExtendInfo->bRecord, ' ', pArea->lpExtendInfo->uiRecordLen );
if( pArea->lpExtendInfo->fHasMemo )
{
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
pField = pArea->lpFields + uiCount;
if( pField->memo )
{
if( ( ( LPDBFMEMO ) pField->memo )->pData )
{
hb_xfree( ( ( LPDBFMEMO ) pField->memo )->pData );
memset( pField->memo, 0, sizeof( DBFMEMO ) );
}
}
}
}
}
static void hb_dbfReadMemo( AREAP pArea, LPDBFMEMO pMemo, ULONG lMemoBlock )
{
USHORT uiBytesRead, uiMaxRead, uiRead;
BYTE * pData;
hb_fsSeek( pArea->lpFileInfo->pNext->hFile, lMemoBlock, FS_SET );
uiBytesRead = 0;
uiMaxRead = pMemo->uiLen;
for(;;)
{
if( uiMaxRead < MEMO_BLOCK )
{
pData = ( BYTE * ) hb_xgrab( uiBytesRead + MEMO_BLOCK + 1 );
if( pMemo->uiLen > 0 )
{
memcpy( pData, pMemo->pData, pMemo->uiLen );
hb_xfree( pMemo->pData );
}
pMemo->pData = pData;
pMemo->uiLen = uiBytesRead + MEMO_BLOCK + 1;
uiMaxRead = MEMO_BLOCK;
}
uiRead = hb_fsRead( pArea->lpFileInfo->pNext->hFile,
pMemo->pData + uiBytesRead, uiMaxRead );
if( !uiRead )
return;
for(; uiRead > 0; uiBytesRead++, uiRead-- )
{
if( pMemo->pData[ uiBytesRead ] == 0x1A )
{
if( uiBytesRead > 0 )
{
pData = ( BYTE * ) hb_xgrab( uiBytesRead + 1 );
memcpy( pData, pMemo->pData, uiBytesRead );
pData[ uiBytesRead ] = 0;
}
else
pData = 0;
hb_xfree( pMemo->pData );
pMemo->pData = pData;
pMemo->uiLen = uiBytesRead;
return;
}
}
uiMaxRead = 0;
}
}
static ERRCODE hb_dbfReadBuffer( AREAP pArea, ULONG lRecNo )
{
LPFIELD pField;
USHORT uiCount, uiOffset;
BYTE * szText, szEndChar;
ULONG lMemoBlock;
if( pArea->lpExtendInfo->fRecordChanged &&
!hb_dbfUpdateRecord( pArea, pArea->lpExtendInfo->lRecNo ) )
return FAILURE;
@@ -224,10 +401,43 @@ static ERRCODE hb_dbfReadBuffer( AREAP pArea, ULONG lRecNo )
hb_fsRead( pArea->lpFileInfo->hFile, pArea->lpExtendInfo->bRecord,
pArea->lpExtendInfo->uiRecordLen ) != pArea->lpExtendInfo->uiRecordLen )
{
hb_dbfClearBuffer( pArea );
memset( pArea->lpExtendInfo->bRecord, ' ', pArea->lpExtendInfo->uiRecordLen );
pArea->lpExtendInfo->bRecord[ pArea->lpExtendInfo->uiRecordLen ] = 0;
return FAILURE;
}
if( pArea->lpExtendInfo->fHasMemo && pArea->lpFileInfo->pNext )
{
pField = pArea->lpFields;
uiOffset = 1;
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
if( pField->uiType == 'C' )
uiOffset += pField->uiLen + ( ( USHORT ) pField->uiDec << 8 );
else
{
if( pField->uiType == 'M' )
{
szText = pArea->lpExtendInfo->bRecord + uiOffset;
szEndChar = * ( szText + pField->uiLen );
* ( szText + pField->uiLen ) = 0;
lMemoBlock = atol( ( char * ) szText ) * MEMO_BLOCK;
* ( szText + pField->uiLen ) = szEndChar;
if( lMemoBlock > 0 )
hb_dbfReadMemo( pArea, ( LPDBFMEMO ) pField->memo, lMemoBlock );
else if( ( ( LPDBFMEMO ) pField->memo )->pData )
{
hb_xfree( ( ( LPDBFMEMO ) pField->memo )->pData );
memset( pField->memo, 0, sizeof( DBFMEMO ) );
}
}
uiOffset += pField->uiLen;
}
pField = pField->lpfNext;
}
}
return SUCCESS;
}
@@ -399,6 +609,24 @@ static RDDFUNCS dbfSuper = { 0 };
* -- DBF METHODS --
*/
static ERRCODE AddField( AREAP pArea, LPDBFIELDINFO pFieldInfo )
{
LPFIELD pField;
if( SUPER_ADDFIELD( pArea, pFieldInfo ) == SUCCESS )
{
if( pArea->lpExtendInfo->fHasMemo )
{
pField = pArea->lpFields + pArea->uiFieldCount - 1;
pField->memo = ( void * ) hb_xgrab( sizeof( DBFMEMO ) );
memset( pField->memo, 0, sizeof( DBFMEMO ) );
}
return SUCCESS;
}
return FAILURE;
}
static ERRCODE Append( AREAP pArea, BOOL bUnLockAll )
{
ULONG lRecCount, lRecNo;
@@ -421,7 +649,7 @@ static ERRCODE Append( AREAP pArea, BOOL bUnLockAll )
lRecCount++;
lRecNo = lRecCount;
pArea->fEof = FALSE;
memset( pArea->lpExtendInfo->bRecord, ' ', pArea->lpExtendInfo->uiRecordLen );
hb_dbfClearBuffer( pArea );
pArea->lpExtendInfo->fRecordChanged = TRUE;
pArea->lpFileInfo->fAppend = TRUE;
if( !hb_dbfUpdateRecord( pArea, lRecNo ) )
@@ -598,6 +826,14 @@ static ERRCODE GetValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
else
hb_itemPutL( pItem, 0 );
break;
case 'M':
if( ( ( LPDBFMEMO ) pField->memo )->pData )
hb_itemPutCL( pItem, ( char * ) ( ( LPDBFMEMO ) pField->memo )->pData,
( ( LPDBFMEMO ) pField->memo )->uiLen );
else
hb_itemPutC( pItem, "" );
break;
}
return SUCCESS;
@@ -759,6 +995,37 @@ static ERRCODE Open( AREAP pArea, LPDBOPENINFO pOpenInfo )
return SELF_GOTOP( pArea );
}
static ERRCODE OpenMemFile( AREAP pArea, LPDBOPENINFO pOpenInfo )
{
LPFILEINFO lpMemInfo;
LPMEMOHEADER pMemoHeader;
USHORT uiFlags;
lpMemInfo = ( LPFILEINFO ) hb_xgrab( sizeof( FILEINFO ) );
memset( lpMemInfo, 0, sizeof( FILEINFO ) );
lpMemInfo->hFile = FS_ERROR;
pArea->lpFileInfo->pNext = lpMemInfo;
uiFlags = pOpenInfo->fReadonly ? FO_READ : FO_READWRITE;
uiFlags |= pOpenInfo->fShared ? FO_DENYNONE : FO_EXCLUSIVE;
lpMemInfo->hFile = hb_fsOpen( pOpenInfo->abName, uiFlags );
if( lpMemInfo->hFile == FS_ERROR )
return FAILURE;
pMemoHeader = ( LPMEMOHEADER ) hb_xgrab( MEMO_BLOCK + 1 );
if( hb_fsRead( lpMemInfo->hFile, ( BYTE * ) pMemoHeader,
MEMO_BLOCK + 1 ) != MEMO_BLOCK + 1 )
{
hb_xfree( pMemoHeader );
return FAILURE;
}
pArea->lpExtendInfo->lNextBlock = pMemoHeader->lNextBlock;
hb_xfree( pMemoHeader );
return SELF_GOTOP( pArea );
}
static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
{
LPFIELD pField;
@@ -856,6 +1123,35 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
bError = FALSE;
}
break;
case 'M':
if( pItem->type & IT_STRING )
{
uiCount = pItem->item.asString.length;
if( ( ( LPDBFMEMO ) pField->memo )->uiLen < uiCount )
{
if( ( ( LPDBFMEMO ) pField->memo )->pData )
hb_xfree( ( ( LPDBFMEMO ) pField->memo )->pData );
( ( LPDBFMEMO ) pField->memo )->pData = ( BYTE * ) hb_xgrab( uiCount + 1 );
}
( ( LPDBFMEMO ) pField->memo )->uiLen = uiCount;
if( uiCount > 0 )
{
memcpy( ( ( LPDBFMEMO ) pField->memo )->pData, pItem->item.asString.value, uiCount );
( ( LPDBFMEMO ) pField->memo )->pData[ uiCount ] = 0;
}
else
{
if( ( ( LPDBFMEMO ) pField->memo )->pData )
{
hb_xfree( ( ( LPDBFMEMO ) pField->memo )->pData );
memset( pField->memo, 0, sizeof( DBFMEMO ) );
}
}
( ( LPDBFMEMO ) pField->memo )->fChanged = TRUE;
bError = FALSE;
}
break;
}
if( bError )
@@ -975,7 +1271,7 @@ static ERRCODE ReadDBHeader( AREAP pArea )
}
hb_xfree( szBuffer );
pArea->lpExtendInfo->bRecord = ( BYTE * ) hb_xgrab( pArea->lpExtendInfo->uiRecordLen + 1 );
memset( pArea->lpExtendInfo->bRecord, ' ', pArea->lpExtendInfo->uiRecordLen );
hb_dbfClearBuffer( pArea );
pArea->lpExtendInfo->bRecord[ pArea->lpExtendInfo->uiRecordLen ] = 0;
return SUCCESS;
}
@@ -1025,6 +1321,27 @@ static ERRCODE RecNo( AREAP pArea, PHB_ITEM pRecNo )
return SUCCESS;
}
static ERRCODE Release( AREAP pArea )
{
USHORT uiCount;
LPFIELD pField;
if( pArea->lpExtendInfo->fHasMemo )
{
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
pField = pArea->lpFields + uiCount;
if( pField->memo )
{
if( ( ( LPDBFMEMO ) pField->memo )->pData )
hb_xfree( ( ( LPDBFMEMO ) pField->memo )->pData );
hb_xfree( pField->memo );
}
}
}
return SUPER_RELEASE( pArea );
}
static ERRCODE SkipRaw( AREAP pArea, LONG lToSkip )
{
return SELF_GOTO( pArea, pArea->lpExtendInfo->lRecNo + lToSkip );
@@ -1144,7 +1461,7 @@ static RDDFUNCS dbfTable = { 0, /* Super Bof */
0, /* Super Skip */
0, /* Super SkipFilter */
SkipRaw,
0, /* Super AddField */
AddField,
Append,
0, /* Super CreateFields */
DeleteRec,
@@ -1167,7 +1484,7 @@ static RDDFUNCS dbfTable = { 0, /* Super Bof */
Info,
0, /* Super NewArea */
Open,
0, /* Super Release */
Release,
0, /* Super StructSize */
0, /* Super SysName */
0, /* Super Error */
@@ -1175,7 +1492,7 @@ static RDDFUNCS dbfTable = { 0, /* Super Bof */
Lock,
UnLock,
CreateMemFile,
/*0, */ /* Super OpenMemFile */
OpenMemFile,
ReadDBHeader,
WriteDBHeader
};

View File

@@ -8,14 +8,23 @@ function main()
{ "NUMERIC", "N", 8, 0 }, ;
{ "DOUBLE", "N", 8, 2 }, ;
{ "DATE", "D", 8, 0 }, ;
{ "LOGICAL", "L", 1, 0 } }
{ "LOGICAL", "L", 1, 0 }, ;
{ "MEMO1", "M", 10, 0 }, ;
{ "MEMO2", "M", 10, 0 } }
local aRdd := rddList()
QOut( "Registered RDD's:", LTrim( Str( Len( aRdd ) ) ), "=>" )
aEval( aRdd, { | cDriver | QQOut( "", cDriver ) } )
QOut()
QOut( "Creating a DBF file" )
dbCreate( "testdbf.dbf", aStruct )
dbCreate( "testdbf", aStruct )
dbUseArea(,, "testdbf" )
? "[" + FIELD->MEMO1 + "]"
? "[" + FIELD->MEMO2 + "]"
? "-"
FIELD->MEMO1 := "Hello world!"
FIELD->MEMO2 := "Harbour power"
? "[" + FIELD->MEMO1 + "]"
? "[" + FIELD->MEMO2 + "]"
dbAppend()
FIELD->MEMO1 := "111"
FIELD->MEMO2 := "222"
? "[" + FIELD->MEMO1 + "]"
? "[" + FIELD->MEMO2 + "]"
return nil