diff --git a/ChangeLog.txt b/ChangeLog.txt index a149e5544b..082e33cd5b 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,29 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2024-05-09 23:23 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbapifs.h + * src/rtl/fscopy.c + + added new C function: + HB_BOOL hb_fileCopyEx( const char * pszSource, const char * pszDest, + HB_SIZE nBufSize, HB_BOOL fTime, + PHB_ITEM pCallBack ); + Unlike hb_fileCopy() it is never redirected to remote server and copy + operation is always done locally. + pCallBack is codeblock or function symbol, it's executed at the + beginning and then on each nBufSize bytes written and receives two + parameters: nBytesWritten, nTotalSize. + Warning: nTotalSize could be 0 when non regular files like pipes or + sockets are copied. + + * src/rtl/vfile.c + + added new PRG function: + hb_vfCopyFile( , , [=65536], ; + [=.t.], [] ) --> + It's wrapper to hb_fileCopyEx() C function. + For very big files setting to greater value, i.e. 16777216 + may increase performance. + 2024-04-10 15:39 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * utils/hbmk2/hbmk2.prg ! fixed my last modification and check if HB_WITH_* contains diff --git a/include/hbapifs.h b/include/hbapifs.h index 6aacc119da..4e0aa3127b 100644 --- a/include/hbapifs.h +++ b/include/hbapifs.h @@ -415,6 +415,7 @@ extern HB_EXPORT HB_BOOL hb_fileDelete ( const char * pszFileName ); extern HB_EXPORT HB_BOOL hb_fileRename ( const char * pszFileName, const char * pszNewName ); extern HB_EXPORT HB_BOOL hb_fileCopy ( const char * pszSrcFile, const char * pszDstFile ); extern HB_EXPORT HB_BOOL hb_fileMove ( const char * pszSrcFile, const char * pszDstFile ); +extern HB_EXPORT HB_BOOL hb_fileCopyEx ( const char * pszSource, const char * pszDest, HB_SIZE nBufSize, HB_BOOL fTime, PHB_ITEM pCallBack ); extern HB_EXPORT HB_BOOL hb_fileDirExists ( const char * pszDirName ); extern HB_EXPORT HB_BOOL hb_fileDirMake ( const char * pszDirName ); diff --git a/src/rtl/fscopy.c b/src/rtl/fscopy.c index fb530e62a8..692018442a 100644 --- a/src/rtl/fscopy.c +++ b/src/rtl/fscopy.c @@ -45,6 +45,7 @@ */ #include "hbapi.h" +#include "hbvm.h" #include "hbapifs.h" #define HB_FSCOPY_BUFFERSIZE 65536 @@ -105,6 +106,94 @@ HB_BOOL hb_fsCopy( const char * pszSource, const char * pszDest ) return fResult; } +HB_BOOL hb_fileCopyEx( const char * pszSource, const char * pszDest, HB_SIZE nBufSize, HB_BOOL fTime, PHB_ITEM pCallBack ) +{ + HB_BOOL fResult = HB_FALSE; + PHB_FILE pSrcFile; + + if( pCallBack && ! HB_IS_EVALITEM( pCallBack ) ) + pCallBack = NULL; + + if( ( pSrcFile = hb_fileExtOpen( pszSource, NULL, FO_READ | FO_SHARED | FXO_SHARELOCK, NULL, NULL ) ) != NULL ) + { + PHB_FILE pDstFile; + HB_ERRCODE errCode = 0; + + if( ( pDstFile = hb_fileExtOpen( pszDest, NULL, FXO_TRUNCATE | FO_READWRITE | FO_EXCLUSIVE | FXO_SHARELOCK, NULL, NULL ) ) != NULL ) + { + HB_SIZE nTotal = pCallBack ? hb_fileSize( pSrcFile ) : 0, nWritten = 0, + nSize = nBufSize > 0 ? nBufSize : HB_FSCOPY_BUFFERSIZE; + void * pbyBuffer = hb_xgrab( nSize ); + + if( pCallBack ) + { + hb_vmPushEvalSym(); + hb_vmPush( pCallBack ); + hb_vmPushInteger( 0 ); + hb_vmPushNumInt( ( HB_MAXINT ) nTotal ); + hb_vmSend( 2 ); + } + + while( pCallBack == NULL || hb_vmRequestQuery() == 0 ) + { + HB_SIZE nBytesRead; + + if( ( nBytesRead = hb_fileRead( pSrcFile, pbyBuffer, nSize, -1 ) ) > 0 && + nBytesRead != ( HB_SIZE ) FS_ERROR ) + { + if( nBytesRead != hb_fileWrite( pDstFile, pbyBuffer, nBytesRead, -1 ) ) + { + errCode = hb_fsError(); + break; + } + nWritten += nBytesRead; + if( pCallBack ) + { + hb_vmPushEvalSym(); + hb_vmPush( pCallBack ); + hb_vmPushNumInt( ( HB_MAXINT ) nWritten ); + hb_vmPushNumInt( ( HB_MAXINT ) nTotal ); + hb_vmSend( 2 ); + } + } + else + { + errCode = hb_fsError(); + fResult = errCode == 0; + break; + } + } + + hb_xfree( pbyBuffer ); + + hb_fileClose( pDstFile ); + } + else + errCode = hb_fsError(); + + hb_fileClose( pSrcFile ); + + if( fResult ) + { + HB_FATTR ulAttr; + + if( hb_fileAttrGet( pszSource, &ulAttr ) ) + hb_fileAttrSet( pszDest, ulAttr ); + + if( fTime ) + { + long lJulian, lMillisec; + + if( hb_fileTimeGet( pszSource, &lJulian, &lMillisec ) ) + hb_fileTimeSet( hb_parcx( 1 ), lJulian, lMillisec ); + } + } + hb_fsSetError( errCode ); + } + + return fResult; +} + HB_FUNC( HB_FCOPY ) { HB_ERRCODE errCode = 2; /* file not found */ diff --git a/src/rtl/vfile.c b/src/rtl/vfile.c index a49c35d16c..7bc4c2bbcf 100644 --- a/src/rtl/vfile.c +++ b/src/rtl/vfile.c @@ -217,6 +217,25 @@ HB_FUNC( HB_VFCOPYFILE ) hb_retni( iResult ); } +/* hb_vfCopyFile( , , [], [=.t.], [] ) --> */ +HB_FUNC( HB_VFCOPYFILEEX ) +{ + const char * pszSource = hb_parc( 1 ), + * pszDestin = hb_parc( 2 ); + HB_ERRCODE uiError = 2; + int iResult = F_ERROR; + + if( pszSource && pszDestin ) + { + if( hb_fileCopyEx( pszSource, pszDestin, hb_parns( 3 ), hb_parldef( 4, HB_TRUE ), hb_param( 5, HB_IT_EVALITEM ) ) ) + iResult = 0; + uiError = hb_fsError(); + } + + hb_fsSetFError( uiError ); + hb_retni( iResult ); +} + /* hb_vfMoveFile( , ) --> */ HB_FUNC( HB_VFMOVEFILE ) {