2001-02-23 21:40 GMT+3 Alexander Kresin <alex@belacy.belgorod.su>
This commit is contained in:
@@ -1,3 +1,22 @@
|
||||
2001-02-23 21:40 GMT+3 Alexander Kresin <alex@belacy.belgorod.su>
|
||||
* harbour/source/rdd/dbfntx/dbfntx1.c
|
||||
* building of indexes optimized
|
||||
2001-02-13 hh:mm GMT+1 Jose Gimenez (JFG) <jfgimenez@wanadoo.es>
|
||||
* source/rtl/filesys.c
|
||||
* hb_fsOpen
|
||||
* hb_fsCreate
|
||||
* hb_fsClose
|
||||
* hb_fsRead
|
||||
* hb_fsWrite
|
||||
* hb_fsReadLarge
|
||||
* hb_fsWriteLarge
|
||||
* hb_fsSeek
|
||||
* hb_fsTell
|
||||
+ added logic to use Win32 API calls
|
||||
|
||||
* tests/files.prg
|
||||
* tested up to 20,000 DBF files
|
||||
|
||||
2001-02-23 19:35 UTC+0300 Alex Shashkov <shashkov@ostu.ru>
|
||||
* harbour/source/rtl/filesys.c
|
||||
* harbour/source/rtl/math.c
|
||||
|
||||
@@ -65,12 +65,13 @@ HB_INIT_SYMBOLS_END( dbfntx1__InitSymbols )
|
||||
|
||||
static RDDFUNCS ntxSuper = { 0 };
|
||||
static USHORT maxPagesPerTag = 20;
|
||||
static int maxLevel = 0;
|
||||
|
||||
/* Internal functions */
|
||||
static LPKEYINFO hb_ntxKeyNew( LPKEYINFO pKeyFrom );
|
||||
static void hb_ntxKeyFree( LPKEYINFO pKey );
|
||||
static LONG hb_ntxTagKeyFind( LPTAGINFO pTag, LPKEYINFO pKey );
|
||||
static int hb_ntxTagFindCurrentKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKey, BOOL bExact, BOOL lSeek );
|
||||
static int hb_ntxTagFindCurrentKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKey, BOOL bExact, BOOL lSeek, int level );
|
||||
static USHORT hb_ntxPageFindCurrentKey( LPPAGEINFO pPage, ULONG ulRecno );
|
||||
static void hb_ntxGetCurrentKey( LPTAGINFO pTag, LPKEYINFO pKey );
|
||||
static BOOL hb_ntxFindNextKey( LPTAGINFO pTag );
|
||||
@@ -109,7 +110,7 @@ static LPPAGEINFO hb_ntxPageLoad( ULONG ulOffset );
|
||||
/* Load page from disk */
|
||||
static LPKEYINFO hb_ntxPageKeyDel( LPPAGEINFO pPage, SHORT pos, USHORT level );
|
||||
/* Delete key from page */
|
||||
static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level);
|
||||
static int hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level, BOOL isFreePlace );
|
||||
/* Add key to page */
|
||||
static ERRCODE hb_ntxPageKeyInsert( LPPAGEINFO pPage, PHB_ITEM pKey, int pos );
|
||||
/* Insert page in position pos */
|
||||
@@ -157,7 +158,7 @@ static LONG hb_ntxTagKeyFind( LPTAGINFO pTag, LPKEYINFO pKey )
|
||||
|
||||
pTag->CurKeyInfo->Tag = 0;
|
||||
pTag->TagBOF = pTag->TagEOF = FALSE;
|
||||
K = hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKey->Tag, pKey, FALSE, TRUE );
|
||||
K = hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKey->Tag, pKey, FALSE, TRUE, 1 );
|
||||
if( K == 0 )
|
||||
{
|
||||
if( pTag->pForItem == NULL )
|
||||
@@ -180,12 +181,17 @@ static LONG hb_ntxTagKeyFind( LPTAGINFO pTag, LPKEYINFO pKey )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hb_ntxTagFindCurrentKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKey, BOOL bExact, BOOL lSeek )
|
||||
static int hb_ntxTagFindCurrentKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKey, BOOL bExact, BOOL lSeek, int level )
|
||||
{
|
||||
int k = 1, kChild;
|
||||
LPKEYINFO p;
|
||||
LPPAGEINFO pChildPage;
|
||||
|
||||
if( level > maxLevel ) /* for debugging purposes only */
|
||||
{
|
||||
maxLevel = level;
|
||||
/* printf( "\n\rLevel: %d\n\r",maxLevel ); */
|
||||
}
|
||||
bExact = ( bExact || pPage->TagParent->KeyType != 'C' );
|
||||
pPage->CurKey = 0;
|
||||
if( pPage->uiKeys > 0 )
|
||||
@@ -230,11 +236,11 @@ static int hb_ntxTagFindCurrentKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKe
|
||||
{
|
||||
LONG blockPrev, blockNext;
|
||||
SHORT keyPrev, keyNext;
|
||||
blockPrev = pPage->TagParent->blockPrev;
|
||||
blockNext = pPage->TagParent->blockNext;
|
||||
keyPrev = pPage->TagParent->keyPrev;
|
||||
keyNext = pPage->TagParent->keyNext;
|
||||
|
||||
blockPrev = pPage->TagParent->blockPrev;
|
||||
blockNext = pPage->TagParent->blockNext;
|
||||
keyPrev = pPage->TagParent->keyPrev;
|
||||
keyNext = pPage->TagParent->keyNext;
|
||||
|
||||
if( pPage->CurKey > 0 )
|
||||
{
|
||||
pPage->TagParent->blockPrev = pPage->Page;
|
||||
@@ -246,15 +252,15 @@ static int hb_ntxTagFindCurrentKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKe
|
||||
pPage->TagParent->keyNext = pPage->CurKey;
|
||||
}
|
||||
pChildPage = hb_ntxPageLoad( p->Tag );
|
||||
kChild = hb_ntxTagFindCurrentKey( pChildPage, lBlock, pKey, bExact, lSeek );
|
||||
kChild = hb_ntxTagFindCurrentKey( pChildPage, lBlock, pKey, bExact, lSeek, level + 1 );
|
||||
if( k != 0 || kChild == 0 )
|
||||
k = kChild;
|
||||
if( k > 0 )
|
||||
{
|
||||
pPage->TagParent->blockPrev = blockPrev;
|
||||
pPage->TagParent->blockNext = blockNext;
|
||||
pPage->TagParent->keyPrev = keyPrev;
|
||||
pPage->TagParent->keyNext = keyNext;
|
||||
pPage->TagParent->blockPrev = blockPrev;
|
||||
pPage->TagParent->blockNext = blockNext;
|
||||
pPage->TagParent->keyPrev = keyPrev;
|
||||
pPage->TagParent->keyNext = keyNext;
|
||||
}
|
||||
}
|
||||
else if( k == 0 && lBlock != NTX_IGNORE_REC_NUM )
|
||||
@@ -318,7 +324,7 @@ static BOOL hb_ntxFindNextKey( LPTAGINFO pTag )
|
||||
hb_ntxGetCurrentKey( pTag,pKey );
|
||||
pKey->Tag = NTX_IGNORE_REC_NUM;
|
||||
pTag->blockNext = 0; pTag->keyNext = 0;
|
||||
seekRes = hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKey->Tag, pKey, FALSE, FALSE );
|
||||
seekRes = hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKey->Tag, pKey, FALSE, FALSE, 1 );
|
||||
hb_ntxKeyFree( pKey );
|
||||
if( seekRes )
|
||||
printf( "\n\rhb_ntxFindNextKey: Cannot find current key:" );
|
||||
@@ -425,7 +431,7 @@ static BOOL hb_ntxFindPrevKey( LPTAGINFO pTag )
|
||||
hb_ntxGetCurrentKey( pTag, pKey );
|
||||
pKey->Tag = NTX_IGNORE_REC_NUM;
|
||||
pTag->blockPrev = 0; pTag->keyPrev = 0;
|
||||
seekRes = hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKey->Tag, pKey, FALSE, FALSE );
|
||||
seekRes = hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKey->Tag, pKey, FALSE, FALSE, 1 );
|
||||
hb_ntxKeyFree( pKey );
|
||||
if( seekRes )
|
||||
printf( "\n\rhb_ntxFindPrevKey: Cannot find current key: |%ld %s|",pTag->Owner->Owner->ulRecNo,pKey->pItem->item.asString.value );
|
||||
@@ -768,7 +774,7 @@ static void hb_ntxPageSave( LPPAGEINFO pPage )
|
||||
static LPPAGEINFO hb_ntxPageLoad( ULONG ulOffset )
|
||||
{
|
||||
char buffer[NTXBLOCKSIZE];
|
||||
int i, uiCount;
|
||||
int i;
|
||||
NTXAREAP pArea;
|
||||
LPNTXINDEX pIndex;
|
||||
LPNTXBUFFER itemlist;
|
||||
@@ -800,8 +806,8 @@ static LPPAGEINFO hb_ntxPageLoad( ULONG ulOffset )
|
||||
}
|
||||
|
||||
hb_fsSeek( pIndex->DiskFile, ( ulOffset )? ulOffset:pIndex->CompoundTag->RootBlock, FS_SET );
|
||||
if( ( uiCount = hb_fsRead( pIndex->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE ) )
|
||||
!= NTXBLOCKSIZE )
|
||||
if( hb_fsRead( pIndex->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE )
|
||||
!= NTXBLOCKSIZE )
|
||||
return NULL;
|
||||
|
||||
if( !bReplace )
|
||||
@@ -1029,7 +1035,33 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev
|
||||
return FAILURE;
|
||||
if( pos > pPage->TagParent->MaxKeys )
|
||||
{
|
||||
/* printf( "\nntxPageAddPageKeyAdd - 1( %s %d %d )", hb_itemGetCPtr( pKey ),pPage->uiKeys,pPage->uiKeys/2 ); */
|
||||
/* printf( "\nntxPageAddPageKeyAdd - 1( %s %d )", hb_itemGetCPtr( pKey ),pPage->uiKeys ); */
|
||||
nBegin = pPage->uiKeys - 1;
|
||||
while( ( nBegin > 0 ) && ( pPage->pKeys[ nBegin ].Tag == 0 ) )
|
||||
nBegin--;
|
||||
if( nBegin < pPage->uiKeys - 1 )
|
||||
{
|
||||
nBegin ++;
|
||||
nNewPos = pPage->uiKeys - nBegin;
|
||||
memmove( pNewPage->pKeys, pPage->pKeys + nBegin, nNewPos * sizeof( KEYINFO ));
|
||||
pNewPage->uiKeys = nNewPos;
|
||||
pNewPage->pKeys[nNewPos+1].Tag = 0;
|
||||
pPage->pKeys[nBegin].Tag = pNewPage->Page;
|
||||
pPage->pKeys[nBegin].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pPage->pKeys[nBegin].pItem = hb_itemNew( pKey );
|
||||
pPage->uiKeys -= nNewPos-1;
|
||||
pPage->pKeys[nBegin+1].Tag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewPage->pKeys[0].Tag = 0;
|
||||
pNewPage->pKeys[0].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pNewPage->pKeys[0].pItem = hb_itemNew( pKey );
|
||||
pNewPage->pKeys[1].Tag = 0;
|
||||
pNewPage->uiKeys = 1;
|
||||
pPage->pKeys[pPage->uiKeys].Tag = pNewPage->Page;
|
||||
}
|
||||
/*
|
||||
nEnd = pPage->uiKeys/2;
|
||||
while( ( nEnd < pPage->uiKeys ) && ( pPage->pKeys[ nEnd ].Tag != 0 ) )
|
||||
nEnd++;
|
||||
@@ -1041,7 +1073,7 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev
|
||||
pPage->uiKeys = 1;
|
||||
pPage->pKeys[0].Tag = pNewPage->Page;
|
||||
pPage->pKeys[0].Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pPage->pKeys[0].pItem = hb_itemNew( pKey );
|
||||
pPage->pKeys[0].pItem = hb_itemNew( pKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1057,10 +1089,10 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev
|
||||
pPage->uiKeys ++;
|
||||
}
|
||||
pPage->pKeys[pPage->uiKeys].Tag = 0;
|
||||
*/
|
||||
/* printf( "\nntxPageAddPageKeyAdd - 2( %s %d )", hb_itemGetCPtr( pKey ),pPage->uiKeys ); */
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
nBegin = pos;
|
||||
nCount = 0;
|
||||
@@ -1110,24 +1142,6 @@ static ERRCODE hb_ntxPageKeyInsert( LPPAGEINFO pPage, PHB_ITEM pKey, int pos )
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
static ERRCODE hb_ntxPageKeyDel( LPPAGEINFO pPage, SHORT pos )
|
||||
{
|
||||
hb_itemRelease( pPage->pKeys[pos].pItem );
|
||||
memmove( pPage->pKeys + pos , pPage->pKeys + pos + 1,
|
||||
( pPage->uiKeys - pos + 1) * sizeof( KEYINFO ) );
|
||||
pPage->uiKeys--;
|
||||
pPage->Changed = TRUE;
|
||||
if( !pPage->uiKeys )
|
||||
{
|
||||
pPage->pKeys->Tag = pPage->TagParent->Owner->NextAvail;
|
||||
pPage->TagParent->Owner->NextAvail = pPage->Page;
|
||||
hb_ntxHeaderSave( pPage->TagParent->Owner );
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
static LPKEYINFO hb_ntxPageKeyDel( LPPAGEINFO pPage, SHORT pos, USHORT level )
|
||||
{
|
||||
|
||||
@@ -1175,9 +1189,10 @@ static LPKEYINFO hb_ntxPageKeyDel( LPPAGEINFO pPage, SHORT pos, USHORT level )
|
||||
|
||||
}
|
||||
|
||||
static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
static int hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level, BOOL isFreePlace )
|
||||
{
|
||||
int i = -1, cmp = -1, nBegin;
|
||||
LONG Tag;
|
||||
LPPAGEINFO pLoadedPage;
|
||||
|
||||
/* printf( "\nntxPageKeyAdd - 0 ( %d / %d )",level,pPage->TagParent->uiPages ); */
|
||||
@@ -1187,7 +1202,7 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
pPage->Changed = TRUE;
|
||||
pPage->pKeys->Xtra = pPage->TagParent->Owner->Owner->ulRecNo;
|
||||
pPage->pKeys->pItem = hb_itemNew( pKey );
|
||||
return SUCCESS;
|
||||
return 1;
|
||||
}
|
||||
if( pPage->uiKeys > 3 )
|
||||
{
|
||||
@@ -1212,16 +1227,23 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
if( pLoadedPage == NULL )
|
||||
{
|
||||
/* TODO : Error recovery ??? */
|
||||
return FAILURE;
|
||||
return -1;
|
||||
}
|
||||
if( hb_ntxPageKeyAdd( pLoadedPage, pKey, level+1,
|
||||
pPage->uiKeys < pPage->TagParent->MaxKeys ) == 0 )
|
||||
{
|
||||
Tag = pPage->pKeys[i].Tag;
|
||||
pPage->pKeys[i].Tag = 0;
|
||||
hb_ntxPageKeyInsert( pPage, pKey, i );
|
||||
pPage->pKeys[i].Tag = Tag;
|
||||
}
|
||||
hb_ntxPageKeyAdd( pLoadedPage, pKey, level+1 );
|
||||
hb_ntxPageRelease( pLoadedPage );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_ntxPageKeyInsert( pPage, pKey, i );
|
||||
}
|
||||
return SUCCESS;
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
if( i == pPage->uiKeys )
|
||||
@@ -1229,27 +1251,37 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level)
|
||||
cmp = hb_ntxItemCompare( pPage->pKeys[ i ].pItem , pKey, TRUE );
|
||||
}
|
||||
/* printf( "\nntxPageKeyAdd - 1" ); */
|
||||
if( pPage->uiKeys == pPage->TagParent->MaxKeys )
|
||||
{
|
||||
hb_ntxPageAddPageKeyAdd( pPage, pKey, level, pPage->uiKeys+1 );
|
||||
}
|
||||
else if( pPage->pKeys[i].Tag != 0 )
|
||||
if( pPage->pKeys[i].Tag != 0 )
|
||||
{
|
||||
pLoadedPage = hb_ntxPageLoad( pPage->pKeys[i].Tag );
|
||||
if( pLoadedPage == NULL )
|
||||
{
|
||||
/* TODO : Error recovery ??? */
|
||||
|
||||
return FAILURE;
|
||||
return -1;
|
||||
}
|
||||
if( hb_ntxPageKeyAdd( pLoadedPage, pKey, level+1,
|
||||
pPage->uiKeys < pPage->TagParent->MaxKeys ) == 0 )
|
||||
{
|
||||
Tag = pPage->pKeys[i].Tag;
|
||||
pPage->pKeys[i].Tag = 0;
|
||||
hb_ntxPageKeyInsert( pPage, pKey, i );
|
||||
pPage->pKeys[i].Tag = Tag;
|
||||
}
|
||||
hb_ntxPageKeyAdd( pLoadedPage, pKey, level+1 );
|
||||
hb_ntxPageRelease( pLoadedPage );
|
||||
}
|
||||
else if( pPage->uiKeys == pPage->TagParent->MaxKeys )
|
||||
{
|
||||
if( isFreePlace )
|
||||
return 0;
|
||||
else
|
||||
hb_ntxPageAddPageKeyAdd( pPage, pKey, level, pPage->uiKeys+1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
hb_ntxPageKeyInsert( pPage, pKey, i );
|
||||
}
|
||||
return SUCCESS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ERRCODE hb_ntxTagKeyAdd( LPTAGINFO pTag, PHB_ITEM pKey)
|
||||
@@ -1260,7 +1292,7 @@ static ERRCODE hb_ntxTagKeyAdd( LPTAGINFO pTag, PHB_ITEM pKey)
|
||||
{
|
||||
/* TODO :
|
||||
Add next keys */
|
||||
return hb_ntxPageKeyAdd( pTag->RootPage, pKey, 0);
|
||||
return hb_ntxPageKeyAdd( pTag->RootPage, pKey, 0, FALSE );
|
||||
|
||||
}
|
||||
else
|
||||
@@ -1765,7 +1797,7 @@ static ERRCODE ntxAppend( NTXAREAP pArea, BOOL bUnLockAll )
|
||||
hb_ntxGetCurrentKey( pTag, pTag->CurKeyInfo );
|
||||
if( pArea->fShared )
|
||||
while( !hb_fsLock( lpIndex->DiskFile, 0, 512, FL_LOCK ) );
|
||||
hb_ntxPageKeyAdd( hb_ntxPageLoad( 0 ), pTag->CurKeyInfo->pItem, 0);
|
||||
hb_ntxPageKeyAdd( hb_ntxPageLoad( 0 ), pTag->CurKeyInfo->pItem, 0, FALSE );
|
||||
if( pArea->fShared )
|
||||
{
|
||||
hb_ntxPageFree( pTag->RootPage,TRUE );
|
||||
@@ -1823,7 +1855,7 @@ static ERRCODE ntxPutValue( NTXAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
|
||||
pKeyOld->Tag = NTX_IGNORE_REC_NUM;
|
||||
if( pArea->fShared )
|
||||
while( !hb_fsLock( lpIndex->DiskFile, 0, 512, FL_LOCK ) );
|
||||
if( hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKeyOld->Tag, pKeyOld, FALSE, FALSE ) )
|
||||
if( hb_ntxTagFindCurrentKey( hb_ntxPageLoad( 0 ), pKeyOld->Tag, pKeyOld, FALSE, FALSE, 1 ) )
|
||||
{
|
||||
printf( "\n\rntxPutValue: Cannot find current key:" );
|
||||
lpIndex = lpIndex->pNext;
|
||||
@@ -1832,7 +1864,7 @@ static ERRCODE ntxPutValue( NTXAREAP pArea, USHORT uiIndex, PHB_ITEM pItem )
|
||||
pPage = hb_ntxPageLoad( pTag->CurKeyInfo->Tag );
|
||||
pPage->CurKey = hb_ntxPageFindCurrentKey( pPage,pTag->CurKeyInfo->Xtra ) - 1;
|
||||
hb_ntxPageKeyDel( pPage, pPage->CurKey, 1 );
|
||||
hb_ntxPageKeyAdd( hb_ntxPageLoad( 0 ), pKey->pItem, 0);
|
||||
hb_ntxPageKeyAdd( hb_ntxPageLoad( 0 ), pKey->pItem, 0, FALSE );
|
||||
if( pArea->fShared )
|
||||
{
|
||||
hb_ntxPageFree( pTag->RootPage,TRUE );
|
||||
|
||||
@@ -54,6 +54,12 @@
|
||||
* and David G. Holm <dholm@jsd-llc.com>
|
||||
* hb_fsEof()
|
||||
*
|
||||
* Copyright 2001 Jose Gimenez (JFG) <jfgimenez@wanadoo.es>
|
||||
* <tecnico.sireinsa@ctv.es>
|
||||
* Added __WIN32__ check for any compiler to use the Win32
|
||||
* API calls to allow openning an unlimited number of files
|
||||
* simultaneously.
|
||||
*
|
||||
* See doc/license.txt for licensing terms.
|
||||
*
|
||||
*/
|
||||
@@ -120,6 +126,7 @@
|
||||
#if defined(__BORLANDC__)
|
||||
#include <dir.h>
|
||||
#include <dos.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
@@ -343,7 +350,41 @@ FHANDLE hb_fsOpen( BYTE * pFilename, USHORT uiFlags )
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_fsOpen(%p, %hu)", pFilename, uiFlags));
|
||||
|
||||
#if defined(HAVE_POSIX_IO) && ! defined(__IBMCPP__)
|
||||
#if defined(__WIN32__)
|
||||
|
||||
{
|
||||
DWORD dwFlags = 0;
|
||||
DWORD dwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
|
||||
// read & write flags
|
||||
if( uiFlags & FO_WRITE )
|
||||
dwFlags |= GENERIC_WRITE;
|
||||
|
||||
if( uiFlags & FO_READWRITE )
|
||||
dwFlags |= GENERIC_READ;
|
||||
|
||||
// shared flags
|
||||
if( ( uiFlags & FO_DENYREAD ) == FO_DENYREAD )
|
||||
dwShare = FILE_SHARE_WRITE;
|
||||
|
||||
else if( uiFlags & FO_DENYWRITE )
|
||||
dwShare = FILE_SHARE_READ;
|
||||
|
||||
else if( uiFlags & FO_EXCLUSIVE )
|
||||
dwShare = 0;
|
||||
|
||||
errno = 0;
|
||||
|
||||
hFileHandle = ( FHANDLE ) CreateFile( ( char * ) pFilename, dwFlags,
|
||||
dwShare, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
|
||||
if( hFileHandle == ( FHANDLE ) INVALID_HANDLE_VALUE )
|
||||
errno = GetLastError();
|
||||
|
||||
s_uiErrorLast = errno;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_POSIX_IO) && ! defined(__IBMCPP__)
|
||||
|
||||
errno = 0;
|
||||
hFileHandle = open( ( char * ) pFilename, convert_open_flags( uiFlags ) );
|
||||
@@ -413,7 +454,33 @@ FHANDLE hb_fsCreate( BYTE * pFilename, USHORT uiFlags )
|
||||
|
||||
s_uiErrorLast = 0;
|
||||
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
#if defined(__WIN32__)
|
||||
|
||||
{
|
||||
DWORD dwFlags = FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
if( uiFlags & FC_READONLY )
|
||||
dwFlags |= FILE_ATTRIBUTE_READONLY;
|
||||
|
||||
if( uiFlags & FC_HIDDEN )
|
||||
dwFlags |= FILE_ATTRIBUTE_HIDDEN;
|
||||
|
||||
if( uiFlags & FC_SYSTEM )
|
||||
dwFlags |= FILE_ATTRIBUTE_SYSTEM;
|
||||
|
||||
errno = 0;
|
||||
|
||||
hFileHandle = ( FHANDLE ) CreateFile( ( char * ) pFilename,
|
||||
GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||
dwFlags, NULL );
|
||||
|
||||
if( hFileHandle == ( FHANDLE ) INVALID_HANDLE_VALUE )
|
||||
errno = GetLastError();
|
||||
|
||||
s_uiErrorLast = errno;
|
||||
}
|
||||
|
||||
#elif defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
convert_create_flags( uiFlags, &oflag, &pmode );
|
||||
@@ -443,7 +510,13 @@ void hb_fsClose( FHANDLE hFileHandle )
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
close( hFileHandle );
|
||||
|
||||
#if defined(__WIN32__)
|
||||
CloseHandle( ( HANDLE ) hFileHandle );
|
||||
#else
|
||||
close( hFileHandle );
|
||||
#endif
|
||||
|
||||
s_uiErrorLast = errno;
|
||||
|
||||
#else
|
||||
@@ -518,7 +591,19 @@ USHORT hb_fsRead( FHANDLE hFileHandle, BYTE * pBuff, USHORT uiCount )
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
uiRead = read( hFileHandle, pBuff, uiCount );
|
||||
|
||||
#if defined(__WIN32__)
|
||||
{
|
||||
DWORD dwRead = 0;
|
||||
|
||||
ReadFile( ( HANDLE ) hFileHandle, pBuff, uiCount, &dwRead, NULL );
|
||||
uiRead = ( USHORT ) dwRead;
|
||||
errno = GetLastError();
|
||||
}
|
||||
#else
|
||||
uiRead = read( hFileHandle, pBuff, uiCount );
|
||||
#endif
|
||||
|
||||
s_uiErrorLast = errno;
|
||||
if( uiRead == ( USHORT ) -1 )
|
||||
uiRead = 0;
|
||||
@@ -542,18 +627,31 @@ USHORT hb_fsWrite( FHANDLE hFileHandle, BYTE * pBuff, USHORT uiCount )
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
if( uiCount )
|
||||
{
|
||||
uiWritten = write( hFileHandle, pBuff, uiCount );
|
||||
if( uiWritten == ( USHORT ) -1 )
|
||||
|
||||
#if defined(__WIN32__)
|
||||
{
|
||||
DWORD dwWritten = 0;
|
||||
|
||||
WriteFile( ( HANDLE ) hFileHandle, pBuff, uiCount, &dwWritten, NULL );
|
||||
uiWritten = ( USHORT ) dwWritten;
|
||||
errno = GetLastError();
|
||||
}
|
||||
#else
|
||||
|
||||
if( uiCount )
|
||||
{
|
||||
uiWritten = write( hFileHandle, pBuff, uiCount );
|
||||
if( uiWritten == ( USHORT ) -1 )
|
||||
uiWritten = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiWritten = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiWritten = 0;
|
||||
ftruncate( hFileHandle, lseek( hFileHandle, 0L, SEEK_CUR ) );
|
||||
}
|
||||
s_uiErrorLast = errno;
|
||||
ftruncate( hFileHandle, lseek( hFileHandle, 0L, SEEK_CUR ) );
|
||||
}
|
||||
s_uiErrorLast = errno;
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -574,7 +672,11 @@ ULONG hb_fsReadLarge( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount )
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
#if defined(HB_FS_LARGE_OPTIMIZED)
|
||||
|
||||
#if defined(__WIN32__)
|
||||
ReadFile( ( HANDLE ) hFileHandle, pBuff, ulCount, &ulRead, NULL );
|
||||
errno = GetLastError();
|
||||
#elif defined(HB_FS_LARGE_OPTIMIZED)
|
||||
ulRead = read( hFileHandle, pBuff, ulCount );
|
||||
#else
|
||||
{
|
||||
@@ -631,48 +733,55 @@ ULONG hb_fsWriteLarge( FHANDLE hFileHandle, BYTE * pBuff, ULONG ulCount )
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
if( ulCount )
|
||||
#if defined(HB_FS_LARGE_OPTIMIZED)
|
||||
ulWritten = write( hFileHandle, pBuff, ulCount );
|
||||
|
||||
#if defined(__WIN32__)
|
||||
WriteFile( ( HANDLE ) hFileHandle, pBuff, ulCount, &ulWritten, NULL );
|
||||
errno = GetLastError();
|
||||
#else
|
||||
{
|
||||
ULONG ulLeftToWrite = ulCount;
|
||||
USHORT uiToWrite;
|
||||
USHORT uiWritten;
|
||||
BYTE * pPtr = pBuff;
|
||||
|
||||
ulWritten = 0;
|
||||
|
||||
while( ulLeftToWrite )
|
||||
if( ulCount )
|
||||
#if defined(HB_FS_LARGE_OPTIMIZED)
|
||||
ulWritten = write( hFileHandle, pBuff, ulCount );
|
||||
#else
|
||||
{
|
||||
/* Determine how much to write this time */
|
||||
if( ulLeftToWrite > ( ULONG ) INT_MAX )
|
||||
{
|
||||
uiToWrite = INT_MAX;
|
||||
ulLeftToWrite -= ( ULONG ) uiToWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiToWrite = ( USHORT ) ulLeftToWrite;
|
||||
ulLeftToWrite = 0L;
|
||||
}
|
||||
uiWritten = write( hFileHandle, pPtr, uiToWrite );
|
||||
/* -1 on bad hFileHandle
|
||||
0 on disk full
|
||||
*/
|
||||
if( uiWritten == ( USHORT ) -1 || uiWritten == 0 )
|
||||
break;
|
||||
ULONG ulLeftToWrite = ulCount;
|
||||
USHORT uiToWrite;
|
||||
USHORT uiWritten;
|
||||
BYTE * pPtr = pBuff;
|
||||
|
||||
ulWritten += ( ULONG ) uiWritten;
|
||||
pPtr += uiWritten;
|
||||
ulWritten = 0;
|
||||
|
||||
while( ulLeftToWrite )
|
||||
{
|
||||
/* Determine how much to write this time */
|
||||
if( ulLeftToWrite > ( ULONG ) INT_MAX )
|
||||
{
|
||||
uiToWrite = INT_MAX;
|
||||
ulLeftToWrite -= ( ULONG ) uiToWrite;
|
||||
}
|
||||
else
|
||||
{
|
||||
uiToWrite = ( USHORT ) ulLeftToWrite;
|
||||
ulLeftToWrite = 0L;
|
||||
}
|
||||
uiWritten = write( hFileHandle, pPtr, uiToWrite );
|
||||
/* -1 on bad hFileHandle
|
||||
0 on disk full
|
||||
*/
|
||||
if( uiWritten == ( USHORT ) -1 || uiWritten == 0 )
|
||||
break;
|
||||
|
||||
ulWritten += ( ULONG ) uiWritten;
|
||||
pPtr += uiWritten;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
ulWritten = 0;
|
||||
ftruncate( hFileHandle, lseek( hFileHandle, 0L, SEEK_CUR ) );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
ulWritten = 0;
|
||||
ftruncate( hFileHandle, lseek( hFileHandle, 0L, SEEK_CUR ) );
|
||||
}
|
||||
|
||||
s_uiErrorLast = errno;
|
||||
|
||||
#else
|
||||
@@ -701,7 +810,7 @@ ULONG hb_fsSeek( FHANDLE hFileHandle, LONG lOffset, USHORT uiFlags )
|
||||
|
||||
{
|
||||
APIRET ret = DosSetFilePtr( hFileHandle, 0, SEEK_CUR, &ulPos );
|
||||
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
ulPos = 0;
|
||||
@@ -713,7 +822,11 @@ ULONG hb_fsSeek( FHANDLE hFileHandle, LONG lOffset, USHORT uiFlags )
|
||||
|
||||
/* get current offset */
|
||||
errno = 0;
|
||||
ulPos = lseek( hFileHandle, 0, SEEK_CUR );
|
||||
#if defined(__WIN32__)
|
||||
ulPos = SetFilePointer( ( HANDLE ) hFileHandle, 0, NULL, FILE_CURRENT );
|
||||
#else
|
||||
ulPos = lseek( hFileHandle, 0, SEEK_CUR );
|
||||
#endif
|
||||
if( errno != 0 )
|
||||
{
|
||||
ulPos = 0;
|
||||
@@ -737,7 +850,7 @@ ULONG hb_fsSeek( FHANDLE hFileHandle, LONG lOffset, USHORT uiFlags )
|
||||
|
||||
{
|
||||
APIRET ret = DosSetFilePtr( hFileHandle, lOffset, Flags, &ulPos );
|
||||
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
ulPos = 0;
|
||||
@@ -748,7 +861,11 @@ ULONG hb_fsSeek( FHANDLE hFileHandle, LONG lOffset, USHORT uiFlags )
|
||||
#elif defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
ulPos = lseek( hFileHandle, lOffset, Flags );
|
||||
#if defined(__WIN32__)
|
||||
ulPos = SetFilePointer( ( HANDLE ) hFileHandle, lOffset, NULL, Flags );
|
||||
#else
|
||||
ulPos = lseek( hFileHandle, lOffset, Flags );
|
||||
#endif
|
||||
if( errno != 0 )
|
||||
ulPos = 0;
|
||||
s_uiErrorLast = errno;
|
||||
@@ -777,7 +894,11 @@ ULONG hb_fsTell( FHANDLE hFileHandle )
|
||||
#if defined(HB_FS_FILE_IO)
|
||||
|
||||
errno = 0;
|
||||
ulPos = lseek( hFileHandle, 0L, SEEK_CUR );
|
||||
#if defined(__WIN32__)
|
||||
ulPos = SetFilePointer( ( HANDLE ) hFileHandle, 0, NULL, FILE_CURRENT );
|
||||
#else
|
||||
ulPos = lseek( hFileHandle, 0L, SEEK_CUR );
|
||||
#endif
|
||||
s_uiErrorLast = errno;
|
||||
|
||||
#else
|
||||
|
||||
78
harbour/tests/files.prg
Normal file
78
harbour/tests/files.prg
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
// This test was written by Jose Gimenez (JFG) <jfgimenez@wanadoo.es>
|
||||
// <tecnico.sireinsa@ctv.es>
|
||||
// and is placed into the public domain.
|
||||
|
||||
// Number of files to build/open
|
||||
#define NFILES 1000
|
||||
|
||||
// use only *one* at a time
|
||||
// dejar solo una de las dos lineas siguientes:
|
||||
#define CON_DBFCDX
|
||||
//#define CON_ADS
|
||||
|
||||
#ifdef CON_ADS
|
||||
#include "ads.ch"
|
||||
REQUEST _ADS
|
||||
#endif
|
||||
|
||||
STATIC aCampos := { {"Codigo", "C", 6, 0}, {"Nombre", "C", 35, 0} }
|
||||
|
||||
PROCEDURE FILES()
|
||||
|
||||
Local n := 0, h:=Array(NFILES)
|
||||
|
||||
#ifdef CON_ADS
|
||||
|
||||
rddRegister( "ADS", 1 )
|
||||
rddsetdefault( "ADS" )
|
||||
SET SERVER LOCAL
|
||||
SET FILETYPE TO CDX
|
||||
SET CHARTYPE TO OEM
|
||||
SET AXS LOCKING ON
|
||||
AdsRightsCheck(.F.)
|
||||
|
||||
#endif
|
||||
|
||||
CLS
|
||||
AFill( h, 0 )
|
||||
DO WHILE n < NFILES
|
||||
n++
|
||||
@10,0 SAY "Building files.... "+Str( n )
|
||||
DbCreate( "File" + LTrim( Str( n ) ), aCampos )
|
||||
USE ( "File" + LTrim( Str( n ) ) ) NEW
|
||||
|
||||
#ifdef CON_ADS
|
||||
INDEX ON CODIGO TAG CODIGO TO ( "File" + LTrim( Str( n ) ) )
|
||||
#endif
|
||||
|
||||
CLOSE DATA
|
||||
ENDDO
|
||||
|
||||
n := 0
|
||||
|
||||
DO WHILE n < NFILES
|
||||
n++
|
||||
@12,0 SAY "Opening files.... "+Str( n )
|
||||
USE ( "File" + LTrim( Str( n ) ) ) NEW
|
||||
|
||||
#ifdef CON_ADS
|
||||
SET ORDER TO TAG CODIGO
|
||||
#endif
|
||||
|
||||
ENDDO
|
||||
|
||||
CLOSE DATA
|
||||
|
||||
n := 0
|
||||
|
||||
DO WHILE n < NFILES
|
||||
n++
|
||||
@14,0 SAY "Deleting files.... "+Str( n )
|
||||
FErase ( "File" + LTrim( Str( n ) ) + ".Dbf" )
|
||||
ENDDO
|
||||
|
||||
RETURN NIL
|
||||
Reference in New Issue
Block a user