From 1c70367da5a8f140259bf46f822f0393bdbd65a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Thu, 9 May 2024 23:23:26 +0200 Subject: [PATCH] 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. --- ChangeLog.txt | 23 ++++++++++++ include/hbapifs.h | 1 + src/rtl/fscopy.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++ src/rtl/vfile.c | 19 ++++++++++ 4 files changed, 132 insertions(+) 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 ) {