diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 7d60472f04..fa42ec1866 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,22 @@ +2001-02-23 21:40 GMT+3 Alexander Kresin + * harbour/source/rdd/dbfntx/dbfntx1.c + * building of indexes optimized +2001-02-13 hh:mm GMT+1 Jose Gimenez (JFG) + * 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 * harbour/source/rtl/filesys.c * harbour/source/rtl/math.c diff --git a/harbour/source/rdd/dbfntx/dbfntx1.c b/harbour/source/rdd/dbfntx/dbfntx1.c index be3e3f3402..5df6394942 100644 --- a/harbour/source/rdd/dbfntx/dbfntx1.c +++ b/harbour/source/rdd/dbfntx/dbfntx1.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 ); diff --git a/harbour/source/rtl/filesys.c b/harbour/source/rtl/filesys.c index 905889944a..42d74ee2d1 100644 --- a/harbour/source/rtl/filesys.c +++ b/harbour/source/rtl/filesys.c @@ -54,6 +54,12 @@ * and David G. Holm * hb_fsEof() * + * Copyright 2001 Jose Gimenez (JFG) + * + * 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 #include + #include #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 diff --git a/harbour/tests/files.prg b/harbour/tests/files.prg new file mode 100644 index 0000000000..661f4ac9a7 --- /dev/null +++ b/harbour/tests/files.prg @@ -0,0 +1,78 @@ +/* + * $Id$ + */ + +// This test was written by Jose Gimenez (JFG) +// +// 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