2009-04-28 19:45 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/ChangeLog
    * removed TOVERIFY note - Viktor checked it.

  * harbour/contrib/hbct/ctwin.c
    ! redraw windows after each WCENTER() call

  * harbour/contrib/rddads/ads1.c
    + added support for ADS_VARCHAR_FOX and ADS_VARBINARY_FOX fields
      in ADS_VFP tables

  * harbour/include/dbinfo.ch
  * harbour/include/hbrdddbf.h
  * harbour/include/hbrddcdx.h
  * harbour/include/hbrddnsx.h
  * harbour/include/hbrddntx.h
  * harbour/source/rdd/dbf1.c
  * harbour/source/rdd/workarea.c
    + added support for VFP tables with VARCHAR and VARBINARY fields
    + added support for VFP tables with NULLABLE fields
    + added new dbFieldInfo() action to check if given field is NULL, f.e.:
         ? dbFieldInfo( DBS_ISNULL, FieldPos( <cFieldName> ) )
      The above modifications were not tested with real VFP files. I do
      not have VFP. VFP users should make some real life tests with tables
      created by VFP.
This commit is contained in:
Przemyslaw Czerpak
2009-04-28 17:37:49 +00:00
parent c8e85f3c48
commit e12013d2ff
10 changed files with 331 additions and 106 deletions

View File

@@ -8,6 +8,32 @@
2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
*/
2009-04-28 19:45 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/ChangeLog
* removed TOVERIFY note - Viktor checked it.
* harbour/contrib/hbct/ctwin.c
! redraw windows after each WCENTER() call
* harbour/contrib/rddads/ads1.c
+ added support for ADS_VARCHAR_FOX and ADS_VARBINARY_FOX fields
in ADS_VFP tables
* harbour/include/dbinfo.ch
* harbour/include/hbrdddbf.h
* harbour/include/hbrddcdx.h
* harbour/include/hbrddnsx.h
* harbour/include/hbrddntx.h
* harbour/source/rdd/dbf1.c
* harbour/source/rdd/workarea.c
+ added support for VFP tables with VARCHAR and VARBINARY fields
+ added support for VFP tables with NULLABLE fields
+ added new dbFieldInfo() action to check if given field is NULL, f.e.:
? dbFieldInfo( DBS_ISNULL, FieldPos( <cFieldName> ) )
The above modifications were not tested with real VFP files. I do
not have VFP. VFP users should make some real life tests with tables
created by VFP.
2009-04-27 19:17 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/contrib/rddads/ads1.c
! fixed very bad bug in code compiled for ADS_LIB_VERSION < 600
@@ -21,11 +47,6 @@
timestamp values read from index keys are rounded to whole seconds
or setting scopes to data values on timestamp indexes does not work
like in native RDDs or in ADT tables.
TOVERIFY: please check in which ACE version Ads[SG]etMilliseconds()
functions were added and if necessary add
#if ADS_LIB_VERSION >= ???
protection. I do not have older ACE headers and I cannot
make it myself.
To ADS users: please make some real life tests and report problems
if any.

View File

@@ -801,6 +801,8 @@ static int hb_ctw_CenterWindow( PHB_GTCTW pCTW, int iWindow, BOOL fCenter )
if( pWnd )
{
int iRow = pWnd->iFirstRow, iCol = pWnd->iFirstCol;
if( fCenter )
{
int iHeight = pCTW->iBoardBottom - pCTW->iBoardTop + 1,
@@ -825,6 +827,11 @@ static int hb_ctw_CenterWindow( PHB_GTCTW pCTW, int iWindow, BOOL fCenter )
if( pWnd->iFirstCol < pCTW->iBoardLeft )
pWnd->iFirstCol = pCTW->iBoardLeft;
}
if( !pWnd->fHidden &&
( iRow != pWnd->iFirstRow || iCol != pWnd->iFirstCol ) )
hb_ctw_RemapAllWindows( pCTW, 0 );
return iWindow;
}
}

View File

@@ -1575,10 +1575,32 @@ static HB_ERRCODE adsCreateFields( ADSAREAP pArea, PHB_ITEM pStruct )
break;
case 'V':
dbFieldInfo.uiType = HB_FT_MEMO;
dbFieldInfo.uiTypeExtended = ADS_VARCHAR;
#if ADS_LIB_VERSION >= 900
if( pArea->iFileType == ADS_VFP )
{
dbFieldInfo.uiType = HB_FT_VARLENGTH;
dbFieldInfo.uiTypeExtended = ADS_VARCHAR_FOX;
}
else
#endif
{
dbFieldInfo.uiType = HB_FT_MEMO;
dbFieldInfo.uiTypeExtended = ADS_VARCHAR;
}
break;
#if ADS_LIB_VERSION >= 900
case 'Q':
if( pArea->iFileType == ADS_VFP )
{
dbFieldInfo.uiType = HB_FT_VARLENGTH;
dbFieldInfo.uiTypeExtended = ADS_VARBINARY_FOX;
break;
}
else
return HB_FAILURE;
#endif
case 'R':
if( pArea->iFileType == ADS_ADT && iNameLen >= 4 &&
!hb_strnicmp( szFieldType, "rowversion", iNameLen ) )
@@ -1675,21 +1697,6 @@ static HB_ERRCODE adsCreateFields( ADSAREAP pArea, PHB_ITEM pStruct )
dbFieldInfo.uiLen = 4;
}
}
/*
#if ADS_LIB_VERSION >= 900
else if( pArea->iFileType == ADS_VFP &&
( iNameLen >= 4 &&
hb_strnicmp( szFieldType, "timestamp", iNameLen ) == 0 ) )
{
if( iNameLen > 4 )
{
dbFieldInfo.uiType = HB_FT_DAYTIME;
dbFieldInfo.uiTypeExtended = ADS_TIMESTAMP;
dbFieldInfo.uiLen = 8;
}
}
#endif
*/
else
return HB_FAILURE;
break;
@@ -1838,6 +1845,15 @@ static HB_ERRCODE adsFieldInfo( AREAP pArea, USHORT uiIndex, USHORT uiType, PHB_
hb_itemPutC( pItem, "RAW" );
break;
case HB_FT_VARLENGTH:
#if ADS_LIB_VERSION >= 900
if( pField->uiTypeExtended == ADS_VARCHAR_FOX )
hb_itemPutC( pItem, "V" );
#endif
else
hb_itemPutC( pItem, "Q" );
break;
case HB_FT_BLOB:
hb_itemPutC( pItem, "BINARY" );
break;
@@ -1993,26 +2009,38 @@ static HB_ERRCODE adsGetValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
switch( pField->uiType )
{
case HB_FT_STRING:
case HB_FT_VARLENGTH:
u32Length = pArea->maxFieldLen;
if( !pArea->fPositioned )
{
memset( pBuffer, ' ', pField->uiLen );
u32Length = pField->uiType == HB_FT_STRING ? pField->uiLen : 0;
memset( pBuffer, ' ', u32Length );
}
#ifdef ADS_USE_OEM_TRANSLATION
#if ADS_LIB_VERSION >= 900
else if( hb_ads_bOEM && pField->uiTypeExtended != ADS_VARBINARY_FOX )
#else
else if( hb_ads_bOEM )
#endif
{
#if ADS_LIB_VERSION >= 600
AdsGetFieldRaw( pArea->hTable, ADSFIELD( uiIndex ), pBuffer, &u32Length );
AdsGetFieldRaw( pArea->hTable, ADSFIELD( uiIndex ), pBuffer, &u32Length ) == AE_NO_CURRENT_RECORD )
{
u32Length = pField->uiType == HB_FT_STRING ? pField->uiLen : 0;
memset( pBuffer, ' ', u32Length );
hb_adsUpdateAreaFlags( pArea );
}
#else
if( AdsGetField( pArea->hTable, ADSFIELD( uiIndex ), pBuffer, &u32Length, ADS_NONE ) == AE_NO_CURRENT_RECORD )
{
memset( pBuffer, ' ', pField->uiLen );
u32Length = pField->uiType == HB_FT_STRING ? pField->uiLen : 0;
memset( pBuffer, ' ', u32Length );
hb_adsUpdateAreaFlags( pArea );
}
else
{
char * pBufOem = hb_adsAnsiToOem( ( char * ) pBuffer, pField->uiLen );
memcpy( pBuffer, pBufOem, pField->uiLen );
char * pBufOem = hb_adsAnsiToOem( ( char * ) pBuffer, u32Length );
memcpy( pBuffer, pBufOem, u32Length );
hb_adsOemAnsiFree( pBufOem );
}
#endif
@@ -2020,12 +2048,13 @@ static HB_ERRCODE adsGetValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
#endif
else if( AdsGetField( pArea->hTable, ADSFIELD( uiIndex ), pBuffer, &u32Length, ADS_NONE ) == AE_NO_CURRENT_RECORD )
{
memset( pBuffer, ' ', pField->uiLen );
u32Length = pField->uiType == HB_FT_STRING ? pField->uiLen : 0;
memset( pBuffer, ' ', u32Length );
/* It should not happen - sth desynchronize WA with ADS,
update area flags, Druzus */
hb_adsUpdateAreaFlags( pArea );
}
hb_itemPutCL( pItem, ( char * ) pBuffer, pField->uiLen );
hb_itemPutCL( pItem, ( char * ) pBuffer, u32Length );
break;
case HB_FT_TIME:
@@ -2352,6 +2381,7 @@ static HB_ERRCODE adsPutValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
switch( pField->uiType )
{
case HB_FT_STRING:
case HB_FT_VARLENGTH:
if( HB_IS_STRING( pItem ) )
{
bTypeError = FALSE;
@@ -2688,6 +2718,14 @@ static HB_ERRCODE adsCreate( ADSAREAP pArea, LPDBOPENINFO pCreateInfo )
else
cType = "C";
break;
case HB_FT_VARLENGTH:
#if ADS_LIB_VERSION >= 900
if( pField->uiTypeExtended == ADS_VARBINARY_FOX )
cType = "VarB";
else
#endif
cType = "VarC";
break;
case HB_FT_MEMO:
cType = pField->uiTypeExtended == ADS_VARCHAR ? "VarC" : "M";
break;
@@ -3011,7 +3049,7 @@ static HB_ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo )
USHORT uiFields = 0, uiCount;
UNSIGNED8 szName[ ADS_MAX_FIELD_NAME + 1 ];
/* See adsGettValue() for why we don't use pArea->uiMaxFieldNameLength here */
UNSIGNED16 pusBufLen, pusType, pusDecimals;
UNSIGNED16 usBufLen, usType, usDecimals;
DBFIELDINFO dbFieldInfo;
char szAlias[ HB_RDD_MAX_ALIAS_LEN + 1 ], * szFile;
BOOL fDictionary = FALSE;
@@ -3019,15 +3057,15 @@ static HB_ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo )
HB_TRACE(HB_TR_DEBUG, ("adsOpen(%p)", pArea));
hConnection = HB_ADS_DEFCONNECTION( pOpenInfo->ulConnection );
u32RetVal = AdsGetHandleType( hConnection, &pusType);
u32RetVal = AdsGetHandleType( hConnection, &usType);
if( u32RetVal == AE_SUCCESS )
{
#if ADS_LIB_VERSION >= 600 /* ADS_*_CONNECTION was added in >= 6.00 */
#if ADS_LIB_VERSION < 900 /* ADS_SYS_ADMIN_CONNECTION was removed in >= 9.00 */
fDictionary = ( pusType == ADS_DATABASE_CONNECTION
|| pusType == ADS_SYS_ADMIN_CONNECTION );
fDictionary = ( usType == ADS_DATABASE_CONNECTION
|| usType == ADS_SYS_ADMIN_CONNECTION );
#else
fDictionary = ( pusType == ADS_DATABASE_CONNECTION );
fDictionary = ( usType == ADS_DATABASE_CONNECTION );
#endif
#endif
}
@@ -3140,12 +3178,12 @@ static HB_ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo )
for( uiCount = 1; uiCount <= uiFields; uiCount++ )
{
pusBufLen = ADS_MAX_FIELD_NAME;
AdsGetFieldName( pArea->hTable, uiCount, szName, &pusBufLen );
usBufLen = ADS_MAX_FIELD_NAME;
AdsGetFieldName( pArea->hTable, uiCount, szName, &usBufLen );
dbFieldInfo.atomName = szName;
* ( dbFieldInfo.atomName + pusBufLen ) = '\0';
AdsGetFieldType( pArea->hTable, szName, &pusType );
* ( dbFieldInfo.atomName + usBufLen ) = '\0';
AdsGetFieldType( pArea->hTable, szName, &usType );
AdsGetFieldLength( pArea->hTable, szName, &u32Length );
dbFieldInfo.uiLen = ( USHORT ) u32Length;
dbFieldInfo.uiDec = 0;
@@ -3154,9 +3192,8 @@ static HB_ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo )
{
pArea->maxFieldLen = u32Length;
}
dbFieldInfo.uiTypeExtended = pusType;
switch( pusType )
dbFieldInfo.uiTypeExtended = usType;
switch( usType )
{
case ADS_STRING:
dbFieldInfo.uiTypeExtended = 0;
@@ -3177,27 +3214,27 @@ static HB_ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo )
case ADS_NUMERIC:
dbFieldInfo.uiTypeExtended = 0;
dbFieldInfo.uiType = HB_FT_LONG;
AdsGetFieldDecimals( pArea->hTable, szName, &pusDecimals );
dbFieldInfo.uiDec = ( USHORT ) pusDecimals;
AdsGetFieldDecimals( pArea->hTable, szName, &usDecimals );
dbFieldInfo.uiDec = ( USHORT ) usDecimals;
break;
case ADS_DOUBLE: /* uiLen of extended types is set in following switch */
dbFieldInfo.uiType = HB_FT_DOUBLE;
AdsGetFieldDecimals( pArea->hTable, szName, &pusDecimals );
dbFieldInfo.uiDec = ( USHORT ) pusDecimals;
AdsGetFieldDecimals( pArea->hTable, szName, &usDecimals );
dbFieldInfo.uiDec = ( USHORT ) usDecimals;
break;
case ADS_CURDOUBLE:
dbFieldInfo.uiType = HB_FT_CURDOUBLE;
AdsGetFieldDecimals( pArea->hTable, szName, &pusDecimals );
dbFieldInfo.uiDec = ( USHORT ) pusDecimals;
AdsGetFieldDecimals( pArea->hTable, szName, &usDecimals );
dbFieldInfo.uiDec = ( USHORT ) usDecimals;
break;
#ifdef ADS_MONEY /* Not defined below 7.00 */
case ADS_MONEY:
dbFieldInfo.uiType = HB_FT_CURRENCY;
AdsGetFieldDecimals( pArea->hTable, szName, &pusDecimals );
dbFieldInfo.uiDec = ( USHORT ) pusDecimals;
AdsGetFieldDecimals( pArea->hTable, szName, &usDecimals );
dbFieldInfo.uiDec = ( USHORT ) usDecimals;
break;
#endif
@@ -3237,6 +3274,13 @@ static HB_ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo )
dbFieldInfo.uiType = HB_FT_DATE;
break;
#if ADS_LIB_VERSION >= 900
case ADS_VARCHAR_FOX:
case ADS_VARBINARY_FOX:
dbFieldInfo.uiType = HB_FT_VARLENGTH;
break;
#endif
case ADS_MEMO:
dbFieldInfo.uiTypeExtended = 0;
case ADS_VARCHAR:

View File

@@ -323,6 +323,7 @@
#define DBI_USER 1000 /* User-defined DBI_ constants */
/* extended dbFieldInfo() actions */
#define DBS_ISNULL 101
#define DBS_BLOB_GET 201 /* This is internal definition */
#define DBS_BLOB_LEN 202
#define DBS_BLOB_OFFSET 203

View File

@@ -494,12 +494,15 @@ typedef struct _CDXAREA
USHORT uiNewBlockSize; /* Size of new memo block */
USHORT uiMemoVersion; /* MEMO file version */
USHORT uiDirtyRead; /* Index dirty read bit filed */
USHORT uiNullOffset; /* Offset to _NullFlags filed */
USHORT uiNullCount; /* Number of null flags */
BYTE bTableType; /* DBF type */
BYTE bMemoType; /* MEMO type used in DBF memo fields */
BYTE bLockType; /* Type of locking shemes */
BYTE bCryptType; /* Type of used encryption */
DBFHEADER dbfHeader; /* DBF header buffer */
USHORT * pFieldOffset; /* Pointer to field offset array */
PHB_DBFFIELDBITS pFieldBits; /* Pointer to extended DBF field info array */
BYTE * pRecord; /* Buffer of record data */
ULONG ulRecCount; /* Total records */
ULONG ulRecNo; /* Current record */

View File

@@ -148,10 +148,13 @@ typedef struct _DBFDATA
BOOL fStruct;
BOOL fStrictStruct;
BOOL fMultiTag;
} DBFDATA;
typedef DBFDATA * LPDBFDATA;
} DBFDATA, * LPDBFDATA;
typedef struct _HB_DBFFIELDBITS
{
USHORT uiNullBit;
USHORT uiLengthBit;
} HB_DBFFIELDBITS, * PHB_DBFFIELDBITS;
/*
@@ -206,12 +209,15 @@ typedef struct _DBFAREA
USHORT uiNewBlockSize; /* Size of new memo block */
USHORT uiMemoVersion; /* MEMO file version */
USHORT uiDirtyRead; /* Index dirty read bit filed */
USHORT uiNullOffset; /* Offset to _NullFlags filed */
USHORT uiNullCount; /* Number of null flags */
BYTE bTableType; /* DBF type */
BYTE bMemoType; /* MEMO type used in DBF memo fields */
BYTE bLockType; /* Type of locking shemes */
BYTE bCryptType; /* Type of used encryption */
DBFHEADER dbfHeader; /* DBF header buffer */
USHORT * pFieldOffset; /* Pointer to field offset array */
PHB_DBFFIELDBITS pFieldBits; /* Pointer to extended DBF field info array */
BYTE * pRecord; /* Buffer of record data */
ULONG ulRecCount; /* Total records */
ULONG ulRecNo; /* Current record */
@@ -276,7 +282,7 @@ static HB_ERRCODE hb_dbfDeleteRec( DBFAREAP pArea );
static HB_ERRCODE hb_dbfDeleted( DBFAREAP pArea, BOOL * pDeleted );
#define hb_dbfFieldCount NULL
#define hb_dbfFieldDisplay NULL
#define hb_dbfFieldInfo NULL
static HB_ERRCODE hb_dbfFieldInfo( DBFAREAP pArea, USHORT uiIndex, USHORT uiType, PHB_ITEM pItem );
#define hb_dbfFieldName NULL
static HB_ERRCODE hb_dbfFlush( DBFAREAP pArea );
static HB_ERRCODE hb_dbfGetRec( DBFAREAP pArea, BYTE ** pBuffer );

View File

@@ -583,12 +583,15 @@ typedef struct _NSXAREA
USHORT uiNewBlockSize; /* Size of new memo block */
USHORT uiMemoVersion; /* MEMO file version */
USHORT uiDirtyRead; /* Index dirty read bit filed */
USHORT uiNullOffset; /* Offset to _NullFlags filed */
USHORT uiNullCount; /* Number of null flags */
BYTE bTableType; /* DBF type */
BYTE bMemoType; /* MEMO type used in DBF memo fields */
BYTE bLockType; /* Type of locking shemes */
BYTE bCryptType; /* Type of used encryption */
DBFHEADER dbfHeader; /* DBF header buffer */
USHORT * pFieldOffset; /* Pointer to field offset array */
PHB_DBFFIELDBITS pFieldBits; /* Pointer to extended DBF field info array */
BYTE * pRecord; /* Buffer of record data */
ULONG ulRecCount; /* Total records */
ULONG ulRecNo; /* Current record */

View File

@@ -380,12 +380,15 @@ typedef struct _NTXAREA
USHORT uiNewBlockSize; /* Size of new memo block */
USHORT uiMemoVersion; /* MEMO file version */
USHORT uiDirtyRead; /* Index dirty read bit filed */
USHORT uiNullOffset; /* Offset to _NullFlags filed */
USHORT uiNullCount; /* Number of null flags */
BYTE bTableType; /* DBF type */
BYTE bMemoType; /* MEMO type used in DBF memo fields */
BYTE bLockType; /* Type of locking shemes */
BYTE bCryptType; /* Type of used encryption */
DBFHEADER dbfHeader; /* DBF header buffer */
USHORT * pFieldOffset; /* Pointer to field offset array */
PHB_DBFFIELDBITS pFieldBits; /* Pointer to extended DBF field info array */
BYTE * pRecord; /* Buffer of record data */
ULONG ulRecCount; /* Total records */
ULONG ulRecNo; /* Current record */

View File

@@ -272,7 +272,7 @@ static void hb_dbfUpdateStampFields( DBFAREAP pArea )
static void hb_dbfSetBlankRecord( DBFAREAP pArea, int iType )
{
BYTE *pPtr = pArea->pRecord, bFill = ' ', bNext;
BYTE * pPtr = pArea->pRecord, bFill = ' ', bNext;
ULONG ulSize = 1; /* 1 byte ' ' for DELETE flag */
USHORT uiCount;
LPFIELD pField;
@@ -406,9 +406,47 @@ static void hb_dbfSetBlankRecord( DBFAREAP pArea, int iType )
}
memset( pPtr, bFill, ulSize );
ulSize = pArea->pRecord - pPtr - ulSize;
ulSize += pPtr - pArea->pRecord;
if( ulSize < ( ULONG ) pArea->uiRecordLen )
memset( pPtr, '\0', ( ULONG ) pArea->uiRecordLen - ulSize );
memset( pArea->pRecord + ulSize, '\0', ( ULONG ) pArea->uiRecordLen - ulSize );
/* set varlength and nullable bits in _NullFlags */
if( pArea->uiNullCount )
{
memset( pArea->pRecord + pArea->uiNullOffset, 0xff, pArea->uiNullCount >> 3 );
uiCount = pArea->uiNullCount & 0x07;
if( uiCount )
pArea->pRecord[ pArea->uiNullOffset + ( pArea->uiNullCount >> 3 ) ] = ( 1 << uiCount ) - 1;
}
}
static void hb_dbfAllocNullFlag( DBFAREAP pArea, USHORT uiField, BOOL fLength )
{
if( !pArea->pFieldBits )
{
ULONG ulSize = sizeof( HB_DBFFIELDBITS ) * pArea->uiFieldExtent;
pArea->pFieldBits = memset( hb_xgrab( ulSize ), 0, ulSize );
}
if( fLength )
pArea->pFieldBits[ uiField ].uiLengthBit = pArea->uiNullCount++;
else
pArea->pFieldBits[ uiField ].uiNullBit = pArea->uiNullCount++;
}
static BOOL hb_dbfGetNullFlag( DBFAREAP pArea, USHORT uiBit )
{
return ( pArea->pRecord[ pArea->uiNullOffset + ( uiBit >> 3 ) ] &
( 1 << ( uiBit & 0x07 ) ) ) != 0;
}
static void hb_dbfSetNullFlag( DBFAREAP pArea, USHORT uiBit )
{
pArea->pRecord[ pArea->uiNullOffset + ( uiBit >> 3 ) ] |= 1 << ( uiBit & 0x07 );
}
static void hb_dbfClearNullFlag( DBFAREAP pArea, USHORT uiBit )
{
pArea->pRecord[ pArea->uiNullOffset + ( uiBit >> 3 ) ] &= ~( 1 << ( uiBit & 0x07 ) );
}
/*
@@ -1858,7 +1896,7 @@ static HB_ERRCODE hb_dbfGetValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem
{
case HB_FT_STRING:
#ifndef HB_CDP_SUPPORT_OFF
if( pArea->cdPage != hb_vmCDP() )
if( ( pField->uiFlags & HB_FF_BINARY ) == 0 && pArea->cdPage != hb_vmCDP() )
{
char * pVal = ( char * ) hb_xgrab( pField->uiLen + 1 );
memcpy( pVal, pArea->pRecord + pArea->pFieldOffset[ uiIndex ], pField->uiLen );
@@ -1874,6 +1912,19 @@ static HB_ERRCODE hb_dbfGetValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem
}
break;
case HB_FT_VARLENGTH:
{
USHORT uiLen = pField->uiLen;
if( hb_dbfGetNullFlag( pArea, pArea->pFieldBits[ uiIndex ].uiLengthBit ) )
{
uiLen = ( UCHAR ) pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + uiLen - 1 ];
/* protection against corrupted files */
if( uiLen > pField->uiLen )
uiLen = pField->uiLen;
}
hb_itemPutCL( pItem, ( char * ) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], uiLen );
break;
}
case HB_FT_LOGICAL:
hb_itemPutL( pItem, pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] ] == 'T' ||
pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] ] == 't' ||
@@ -2298,19 +2349,31 @@ static HB_ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem
memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ],
hb_itemGetCPtr( pItem ), uiSize );
#ifndef HB_CDP_SUPPORT_OFF
hb_cdpnTranslate( (char *) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_vmCDP(), pArea->cdPage, uiSize );
if( ( pField->uiFlags & HB_FF_BINARY ) == 0 )
hb_cdpnTranslate( ( char * ) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_vmCDP(), pArea->cdPage, uiSize );
#endif
memset( pArea->pRecord + pArea->pFieldOffset[ uiIndex ] + uiSize,
' ', pField->uiLen - uiSize );
}
else if( pField->uiType == HB_FT_DAYTIME )
else if( pField->uiType == HB_FT_VARLENGTH )
{
LONG lJulian, lMillisec;
BYTE * ptr = pArea->pRecord + pArea->pFieldOffset[ uiIndex ];
hb_timeStampStrGetDT( hb_itemGetCPtr( pItem ), &lJulian, &lMillisec );
HB_PUT_LE_UINT32( ptr, lJulian );
ptr += 4;
HB_PUT_LE_UINT32( ptr, lMillisec );
uiSize = ( USHORT ) hb_itemGetCLen( pItem );
if( uiSize >= pField->uiLen )
{
uiSize = pField->uiLen;
hb_dbfClearNullFlag( pArea, pArea->pFieldBits[ uiIndex ].uiLengthBit );
}
else
{
pArea->pRecord[ pArea->pFieldOffset[ uiIndex ] + pField->uiLen - 1 ] = ( BYTE ) uiSize;
hb_dbfSetNullFlag( pArea, pArea->pFieldBits[ uiIndex ].uiLengthBit );
}
memcpy( pArea->pRecord + pArea->pFieldOffset[ uiIndex ],
hb_itemGetCPtr( pItem ), uiSize );
#ifndef HB_CDP_SUPPORT_OFF
if( ( pField->uiFlags & HB_FF_BINARY ) == 0 )
hb_cdpnTranslate( ( char * ) pArea->pRecord + pArea->pFieldOffset[ uiIndex ], hb_vmCDP(), pArea->cdPage, uiSize );
#endif
}
else
uiError = EDBF_DATATYPE;
@@ -2510,6 +2573,11 @@ static HB_ERRCODE hb_dbfPutValue( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem
hb_itemRelease( pError );
return uiError == E_DEFAULT ? HB_SUCCESS : HB_FAILURE;
}
else if( pArea->bTableType == DB_DBF_VFP &&
( pField->uiFlags & HB_FF_NULLABLE ) != 0 )
{
hb_dbfClearNullFlag( pArea, pArea->pFieldBits[ uiIndex ].uiNullBit );
}
return HB_SUCCESS;
}
@@ -2695,6 +2763,13 @@ static HB_ERRCODE hb_dbfClose( DBFAREAP pArea )
pArea->pFieldOffset = NULL;
}
/* Free field bits array */
if( pArea->pFieldBits )
{
hb_xfree( pArea->pFieldBits );
pArea->pFieldBits = NULL;
}
/* Free buffer */
if( pArea->pRecord )
{
@@ -2778,18 +2853,6 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
fRawBlob = SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_BLOB_SUPPORT, pCreateInfo->ulConnection, pItem ) == HB_SUCCESS &&
hb_itemGetL( pItem );
if( pArea->bTableType == 0 )
{
pItem = hb_itemPutNI( pItem, 0 );
if( SELF_INFO( ( AREAP ) pArea, DBI_TABLETYPE, pItem ) != HB_SUCCESS )
{
hb_itemRelease( pItem );
pArea->lpdbOpenInfo = NULL;
return HB_FAILURE;
}
pArea->bTableType = hb_itemGetNI( pItem );
}
if( pArea->bLockType == 0 )
{
pItem = hb_itemPutNI( pItem, 0 );
@@ -2887,12 +2950,12 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
pArea->szDataFileName = hb_strdup( ( char * ) szFileName );
ulSize = pArea->uiFieldCount * sizeof( DBFFIELD ) +
ulSize = ( ULONG ) pArea->uiFieldCount * sizeof( DBFFIELD ) +
( pArea->bTableType == DB_DBF_VFP ? 1 : 2 );
if( pArea->uiFieldCount )
{
pBuffer = ( BYTE * ) hb_xgrab( ulSize + 1 );
memset( pBuffer, 0, ulSize );
pBuffer = ( BYTE * ) hb_xgrab( ulSize + sizeof( DBFFIELD ) + 1 );
memset( pBuffer, 0, ulSize + sizeof( DBFFIELD ) + 1 );
}
else
{
@@ -2904,7 +2967,7 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
/* Size for deleted flag */
pArea->uiRecordLen = 1;
pArea->uiNullCount = 0;
for( uiCount = 0; uiCount < pArea->uiFieldCount; uiCount++ )
{
LPFIELD pField = pArea->lpFields + uiCount;
@@ -2914,6 +2977,7 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
/* field offset */
if( pArea->bTableType == DB_DBF_VFP )
HB_PUT_LE_UINT16( pThisField->bReserved1, pArea->uiRecordLen );
pThisField->bFieldFlags = ( BYTE ) pField->uiFlags;
switch( pField->uiType )
{
@@ -2970,23 +3034,24 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
break;
case HB_FT_ANY:
pThisField->bType = 'V';
if( pField->uiLen < 3 || pField->uiLen == 5 )
{
pField->uiLen = 6;
}
pThisField->bLen = ( BYTE ) pField->uiLen;
pThisField->bDec = ( BYTE ) ( pField->uiLen >> 8 );
pArea->uiRecordLen += pField->uiLen;
if( pThisField->bLen >= 6 )
{
pArea->uiMemoVersion = DB_MEMOVER_SIX;
pArea->fHasMemo = TRUE;
}
/*
if( pArea->bTableType == DB_DBF_VFP )
fError = TRUE;
*/
else
{
pThisField->bType = 'V';
if( pField->uiLen < 3 || pField->uiLen == 5 )
{
pField->uiLen = 6;
}
pThisField->bLen = ( BYTE ) pField->uiLen;
pThisField->bDec = ( BYTE ) ( pField->uiLen >> 8 );
pArea->uiRecordLen += pField->uiLen;
if( pThisField->bLen >= 6 )
{
pArea->uiMemoVersion = DB_MEMOVER_SIX;
pArea->fHasMemo = TRUE;
}
}
break;
case HB_FT_DATE:
@@ -3037,6 +3102,20 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
pArea->uiRecordLen += pField->uiLen;
break;
case HB_FT_VARLENGTH:
if( pField->uiLen > 255 )
pField->uiLen = 255;
else if( pField->uiLen == 0 )
pField->uiLen = 1;
if( pArea->bTableType == DB_DBF_VFP && ( pField->uiFlags & HB_FF_BINARY ) == 0 )
pThisField->bType = 'V';
else
pThisField->bType = 'Q';
pThisField->bLen = ( BYTE ) pField->uiLen;
pArea->uiRecordLen += pField->uiLen;
hb_dbfAllocNullFlag( pArea, uiCount, TRUE );
break;
case HB_FT_TIME:
pThisField->bType = 'T';
pField->uiLen = 4;
@@ -3100,6 +3179,20 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo )
}
pThisField++;
}
if( pArea->uiNullCount )
{
hb_strncpy( ( char * ) pThisField->bName, "_NullFlags", sizeof( pThisField->bName ) - 1 );
HB_PUT_LE_UINT16( pThisField->bReserved1, pArea->uiRecordLen );
pThisField->bType = '0';
pThisField->bFieldFlags = HB_FF_HIDDEN;
uiCount = ( pArea->uiNullCount + 7 ) >> 3;
pThisField->bLen = ( BYTE ) uiCount;
pThisField->bDec = ( BYTE ) ( uiCount >> 8 );
pArea->uiRecordLen += uiCount;
ulSize += sizeof( DBFFIELD );
}
pArea->fShared = FALSE; /* pCreateInfo->fShared */
pArea->fReadonly = FALSE; /* pCreateInfo->fReadonly */
pArea->ulRecCount = 0;
@@ -3441,6 +3534,29 @@ static HB_ERRCODE hb_dbfInfo( DBFAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
return errCode;
}
static HB_ERRCODE hb_dbfFieldInfo( DBFAREAP pArea, USHORT uiIndex, USHORT uiType, PHB_ITEM pItem )
{
HB_TRACE(HB_TR_DEBUG, ("hb_dbfFieldInfo(%p, %hu, %hu, %p)", pArea, uiIndex, uiType, pItem));
if( uiIndex > pArea->uiFieldCount )
return HB_FAILURE;
switch( uiType )
{
case DBS_ISNULL:
{
LPFIELD pField = pArea->lpFields + uiIndex - 1;
hb_itemPutL( pItem,
pArea->bTableType == DB_DBF_VFP &&
( pField->uiFlags & HB_FF_NULLABLE ) != 0 &&
hb_dbfGetNullFlag( pArea, pArea->pFieldBits[ uiIndex ].uiNullBit ) );
return HB_SUCCESS;
}
default:
return SUPER_FIELDINFO( ( AREAP ) pArea, uiIndex, uiType, pItem );
}
}
/*
* Retrieve information about a raw
*/
@@ -3592,6 +3708,14 @@ static HB_ERRCODE hb_dbfNewArea( DBFAREAP pArea )
pArea->uiDirtyRead = HB_IDXREAD_DEFAULT;
/* Size for deleted records flag */
pArea->uiRecordLen = 1;
{
PHB_ITEM pItem = hb_itemPutNI( NULL, 0 );
if( SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_TABLETYPE, 0, pItem ) == HB_SUCCESS )
pArea->bTableType = hb_itemGetNI( pItem );
hb_itemRelease( pItem );
}
return HB_SUCCESS;
}
@@ -3862,6 +3986,7 @@ static HB_ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
/* Size for deleted flag */
pArea->uiRecordLen = 1;
pArea->uiNullCount = 0;
for( uiCount = 0; uiCount < uiFields + uiSkip; uiCount++ )
{
pField = ( LPDBFFIELD ) ( pBuffer + uiCount * sizeof( DBFFIELD ) );
@@ -3987,13 +4112,18 @@ static HB_ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
case 'Q':
dbFieldInfo.uiType = HB_FT_VARLENGTH;
dbFieldInfo.uiFlags |= HB_FF_BINARY;
if( pArea->bTableType == DB_DBF_VFP )
dbFieldInfo.uiFlags |= HB_FF_BINARY;
else
dbFieldInfo.uiFlags |= HB_FF_BINARY & pField->bFieldFlags;
hb_dbfAllocNullFlag( pArea, uiCount, TRUE );
break;
case 'V':
if( pArea->bTableType == DB_DBF_VFP )
{
dbFieldInfo.uiType = HB_FT_VARLENGTH;
hb_dbfAllocNullFlag( pArea, uiCount, TRUE );
}
else
{
@@ -4030,12 +4160,11 @@ static HB_ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
break;
case '0':
if( pArea->bTableType == DB_DBF_VFP && pField->bFieldFlags & 0x01 )
if( /* pArea->bTableType == DB_DBF_VFP && */
( pField->bFieldFlags & HB_FF_HIDDEN ) != 0 )
{
if( memcmp( dbFieldInfo.atomName, "_NullFlags", 10 ) == 0 )
{
/* TODO: NULLABLE and VARLENGTH support */
}
pArea->uiNullOffset = pArea->uiRecordLen;
pArea->uiRecordLen += dbFieldInfo.uiLen;
continue;
}
@@ -4045,9 +4174,16 @@ static HB_ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo )
break;
}
/* Add field */
if( errCode == HB_SUCCESS )
{
if( pArea->bTableType == DB_DBF_VFP &&
( pField->bFieldFlags & HB_FF_NULLABLE ) != 0 )
{
hb_dbfAllocNullFlag( pArea, uiCount, FALSE );
}
/* Add field */
errCode = SELF_ADDFIELD( ( AREAP ) pArea, &dbFieldInfo );
}
/* Exit if error */
if( errCode != HB_SUCCESS )
@@ -4311,12 +4447,12 @@ void hb_dbfTranslateRec( DBFAREAP pArea, BYTE * pBuffer, PHB_CODEPAGE cdp_src, P
for( uiIndex = 0, pField = pArea->lpFields; uiIndex < pArea->uiFieldCount; uiIndex++, pField++ )
{
if( pField->uiType == HB_FT_STRING && ( pField->uiFlags && HB_FF_BINARY ) == 0 )
if( ( pField->uiFlags && HB_FF_BINARY ) == 0 &&
( pField->uiType == HB_FT_STRING || pField->uiType == HB_FT_VARLENGTH ) )
{
hb_cdpnTranslate( ( char * ) pBuffer + pArea->pFieldOffset[ uiIndex ], cdp_src, cdp_dest, pField->uiLen );
}
}
}
#endif
@@ -5037,6 +5173,7 @@ static HB_ERRCODE hb_dbfReadDBHeader( DBFAREAP pArea )
case 0x31:
pArea->fAutoInc = TRUE;
case 0x30:
case 0x32:
pArea->bTableType = DB_DBF_VFP;
if( pArea->dbfHeader.bHasTags & 0x02 )
{

View File

@@ -263,7 +263,7 @@ static HB_ERRCODE hb_waAddField( AREAP pArea, LPDBFIELDINFO pFieldInfo )
pField->uiDec = pFieldInfo->uiDec;
pField->uiFlags = pFieldInfo->uiFlags;
pField->uiArea = pArea->uiArea;
pArea->uiFieldCount ++;
pArea->uiFieldCount++;
return HB_SUCCESS;
}
@@ -417,7 +417,7 @@ static HB_ERRCODE hb_waCreateFields( AREAP pArea, PHB_ITEM pStruct )
case 'Q':
pFieldInfo.uiType = HB_FT_VARLENGTH;
pFieldInfo.uiLen = uiLen > 255 ? 255 : uiLen;
pFieldInfo.uiLen = uiLen > 255 ? 255 : ( uiLen == 0 ? 1 : uiLen );
break;
case 'M':