diff --git a/ChangeLog.txt b/ChangeLog.txt index 68ccca6dab..36671132bb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,33 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2015-09-01 17:05 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbapifs.h + * src/rtl/filebufd.c + * moved HB_FILE_ERR_UNSUPPORTED macro to header file + + * include/hbapifs.h + * src/rtl/filebuf.c + * added new C function hb_fileLoad() - it can be used to load data + from regular files and streams + + * src/rtl/memofile.c + * modified [hb_]Memo{Read|Writ}() to work with streams, i.e. now + this code works: + + REQUEST HB_PIPEIO + cDir := hb_memoRead( "|ls -la" ) + ? upper( cDir ) + + or: + + cData := hb_memoRead( "|xz -c data.gz" ) + ? hb_memoWrit( "data2.txt", cData ) + ? hb_memoWrit( "|sh -c 'xz -9 -e > data2.xz'", cData ) + + * src/rtl/fscopy.c + * removed not used in current code unix header files + 2015-09-01 15:07 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * ChangeLog.txt ! fixed typo in ChangeLog entry. I used hb_socketNew() instead of diff --git a/contrib/hbpipeio/pipeio.c b/contrib/hbpipeio/pipeio.c index 00407ac282..c0edf6ea87 100644 --- a/contrib/hbpipeio/pipeio.c +++ b/contrib/hbpipeio/pipeio.c @@ -325,8 +325,6 @@ static PHB_FILE hb_fileProcessOpen( const char * pszCommand, HB_FATTR nMode, return NULL; } - printf( "\nOPEN( '%s', %p, %p ), nMode=%ld\n", pszCommand, phStdIn, phStdOut, ( long ) nMode ); fflush( stdout ); - hProcess = hb_fsProcessOpen( pszCommand, phStdIn, phStdOut, NULL, fDetach, NULL ); return hProcess != FS_ERROR ? s_fileNew( hProcess, hPipeRD, hPipeWR, timeout ) : NULL; diff --git a/include/hbapifs.h b/include/hbapifs.h index cb40e62db2..04d5f60bab 100644 --- a/include/hbapifs.h +++ b/include/hbapifs.h @@ -417,6 +417,8 @@ extern HB_EXPORT HB_BOOL hb_fileDetach( PHB_FILE pFile ); extern HB_EXPORT HB_BOOL hb_fileIsLocal( PHB_FILE pFile ); extern HB_EXPORT HB_BOOL hb_fileIsLocalName( const char * pszFileName ); extern HB_EXPORT HB_SIZE hb_fileResult( HB_SIZE nSize ); +extern HB_EXPORT HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, HB_SIZE * pnSize ); + /* interface to PRG level hb_vf*() file pointer items */ extern HB_EXPORT PHB_FILE hb_fileParam( int iParam ); @@ -424,6 +426,7 @@ extern HB_EXPORT PHB_FILE hb_fileItemGet( PHB_ITEM pItem ); extern HB_EXPORT PHB_ITEM hb_fileItemPut( PHB_ITEM pItem, PHB_FILE pFile ); extern HB_EXPORT void hb_fileItemClear( PHB_ITEM pItem ); +#define HB_FILE_ERR_UNSUPPORTED ( ( HB_ERRCODE ) FS_ERROR ) /* wrapper to fopen() which calls hb_fsNameConv() */ extern HB_EXPORT FILE * hb_fopen( const char *path, const char *mode ); diff --git a/src/rtl/filebuf.c b/src/rtl/filebuf.c index 24df5c9bd2..5a8732acc8 100644 --- a/src/rtl/filebuf.c +++ b/src/rtl/filebuf.c @@ -1487,3 +1487,75 @@ HB_SIZE hb_fileResult( HB_SIZE nSize ) { return nSize == ( HB_SIZE ) FS_ERROR ? 0 : nSize; } + +#define HB_FILELOAD_BUFFERSIZE 65536 + +HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, + HB_SIZE * pnSize ) +{ + HB_BYTE * pFileBuf = NULL; + HB_SIZE nSize = 0; + PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL, + FO_READ | FO_SHARED | FO_PRIVATE | + FXO_SHARELOCK | FXO_NOSEEKPOS, + NULL, NULL ); + + if( pFile != NULL ) + { + HB_FOFFSET nFileSize = hb_fileSize( pFile ); + + if( nFileSize == FS_ERROR || + ( nFileSize == 0 && hb_fsError() == HB_FILE_ERR_UNSUPPORTED ) ) + { + HB_SIZE nRead, nBufSize = 0; + + for( ;; ) + { + if( nBufSize == nSize ) + { + nBufSize += nBufSize == 0 ? HB_FILELOAD_BUFFERSIZE : nBufSize >> 1; + if( nMaxSize > 0 && nBufSize > nMaxSize ) + { + nBufSize = nMaxSize; + if( nBufSize == nSize ) + break; + } + pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nBufSize ); + } + nRead = hb_fileRead( pFile, pFileBuf + nSize, nBufSize - nSize, -1 ); + if( nRead == 0 || nRead == ( HB_SIZE ) FS_ERROR ) + break; + nSize += nRead; + } + } + else + { + nSize = ( HB_SIZE ) nFileSize; + if( nMaxSize > 0 && nSize > nMaxSize ) + nSize = nMaxSize; + + pFileBuf = ( HB_BYTE * ) hb_xgrab( nSize + 1 ); + nSize = hb_fileReadAt( pFile, pFileBuf, nSize, 0 ); + if( nSize == ( HB_SIZE ) FS_ERROR ) + nSize = 0; + } + + hb_fileClose( pFile ); + + if( nSize > 0 ) + { + pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nSize + 1 ); + pFileBuf[ nSize ] = '\0'; + } + else if( pFileBuf ) + { + hb_xfree( pFileBuf ); + pFileBuf = NULL; + } + } + + if( pnSize ) + *pnSize = nSize; + + return pFileBuf; +} diff --git a/src/rtl/filebufd.c b/src/rtl/filebufd.c index 957aa49aeb..b62688fd8c 100644 --- a/src/rtl/filebufd.c +++ b/src/rtl/filebufd.c @@ -52,8 +52,6 @@ #include "hbapi.h" #include "hbapifs.h" -#define HB_FILE_ERR_UNSUPPORTED ( ( HB_ERRCODE ) FS_ERROR ) - static HB_BOOL s_fileAccept( PHB_FILE_FUNCS pFuncs, const char * pszFileName ) { HB_SYMBOL_UNUSED( pFuncs ); diff --git a/src/rtl/fscopy.c b/src/rtl/fscopy.c index 5190b8c300..855192423b 100644 --- a/src/rtl/fscopy.c +++ b/src/rtl/fscopy.c @@ -49,11 +49,6 @@ #include "hbapi.h" #include "hbapifs.h" -#if defined( HB_OS_UNIX ) - #include - #include -#endif - #define HB_FSCOPY_BUFFERSIZE 65536 HB_BOOL hb_fsCopy( const char * pszSource, const char * pszDest ) diff --git a/src/rtl/memofile.c b/src/rtl/memofile.c index 468a3a6fa2..66573e5a47 100644 --- a/src/rtl/memofile.c +++ b/src/rtl/memofile.c @@ -60,36 +60,18 @@ static void hb_memoread( HB_BOOL bHandleEOF ) if( pszFileName ) { - PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL, - FO_READ | FO_SHARED | FO_PRIVATE | - FXO_SHARELOCK | FXO_NOSEEKPOS, - NULL, NULL ); + HB_SIZE nSize; + char * pBuffer = ( char * ) hb_fileLoad( pszFileName, 0, &nSize ); - if( pFile != NULL ) + if( pBuffer ) { - HB_SIZE nSize = ( HB_SIZE ) hb_fileSize( pFile ); - - if( nSize != 0 ) + /* Don't read the file terminating EOF character */ + if( bHandleEOF && nSize > 0 ) { - char * pbyBuffer = ( char * ) hb_xgrab( nSize + 1 ); - - nSize = hb_fileReadAt( pFile, pbyBuffer, nSize, 0 ); - if( nSize == ( HB_SIZE ) FS_ERROR ) - nSize = 0; - - /* Don't read the file terminating EOF character */ - if( bHandleEOF && nSize > 0 ) - { - if( pbyBuffer[ nSize - 1 ] == HB_CHAR_EOF ) - --nSize; - } - - hb_retclen_buffer( pbyBuffer, nSize ); + if( pBuffer[ nSize - 1 ] == HB_CHAR_EOF ) + --nSize; } - else - hb_retc_null(); - - hb_fileClose( pFile ); + hb_retclen_buffer( pBuffer, nSize ); } else hb_retc_null(); @@ -118,21 +100,30 @@ static HB_BOOL hb_memowrit( HB_BOOL bHandleEOF ) { PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL, FO_READWRITE | FO_EXCLUSIVE | FO_PRIVATE | - FXO_TRUNCATE | FXO_SHARELOCK | FXO_NOSEEKPOS, + FXO_TRUNCATE | FXO_SHARELOCK, NULL, NULL ); if( pFile != NULL ) { HB_SIZE nSize = hb_itemGetCLen( pString ); + const char * pData = hb_itemGetCPtr( pString ); - bRetVal = hb_fileWriteAt( pFile, hb_itemGetCPtr( pString ), nSize, 0 ) == nSize; + while( nSize > 0 ) + { + HB_SIZE nWritten = hb_fileWrite( pFile, pData, nSize, 0 ); + if( nWritten == 0 || nWritten == ( HB_SIZE ) FS_ERROR ) + break; + nSize -= nWritten; + pData += nWritten; + } + bRetVal = nSize == 0; /* NOTE: CA-Cl*pper will add the EOF even if the write failed. [vszakats] */ /* NOTE: CA-Cl*pper will not return .F. when the EOF could not be written. [vszakats] */ if( bHandleEOF && bRetVal ) /* if true, then write EOF */ { char cEOF = HB_CHAR_EOF; - hb_fileWriteAt( pFile, &cEOF, sizeof( char ), nSize ); + hb_fileWrite( pFile, &cEOF, sizeof( char ), -1 ); } hb_fileClose( pFile );