2015-09-02 15:54 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

* include/hbapifs.h
  * src/rtl/filebuf.c
    * added new C function hb_fileLoadData() - it can be used to load data
      from already opened regular files and streams

  * include/harbour.hbx
  * src/rtl/vfile.c
    + added new PRG function:
         hb_vfLoad( <cFileName>, [ <nMaxSize> ] ) -> <cFileBody> | NIL

  * src/vm/runner.c
    * use hb_fileLoadData()

  * contrib/hbwin/win_bmp.c
    * use hb_fileLoad()
This commit is contained in:
Przemysław Czerpak
2015-09-02 15:54:08 +02:00
parent 0f9398515e
commit 38af08e97d
7 changed files with 115 additions and 81 deletions

View File

@@ -10,6 +10,23 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2015-09-02 15:54 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* include/hbapifs.h
* src/rtl/filebuf.c
* added new C function hb_fileLoadData() - it can be used to load data
from already opened regular files and streams
* include/harbour.hbx
* src/rtl/vfile.c
+ added new PRG function:
hb_vfLoad( <cFileName>, [ <nMaxSize> ] ) -> <cFileBody> | NIL
* src/vm/runner.c
* use hb_fileLoadData()
* contrib/hbwin/win_bmp.c
* use hb_fileLoad()
2015-09-01 23:04 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* package/harbour.spec
+ added HBCOMIO, HBPIPEIO, HBTCPIO to RPM package

View File

@@ -91,34 +91,25 @@ HB_FUNC( WIN_BITMAPTYPE )
HB_FUNC( WIN_LOADBITMAPFILE )
{
char * pBuffer = NULL;
PHB_FILE pFile = hb_fileExtOpen( hb_parcx( 1 ), NULL,
FO_READ | FO_SHARED | FO_PRIVATE |
FXO_SHARELOCK | FXO_NOSEEKPOS,
NULL, NULL );
if( pFile != NULL )
{
HB_SIZE nSize = ( HB_SIZE ) hb_fileSize( pFile );
HB_SIZE nSize;
char * pBuffer = ( char * ) hb_fileLoad( hb_parcx( 1 ), HB_MAX_BMP_SIZE, &nSize );
if( pBuffer )
{
/* TOFIX: No check is done on read data from disk which is a large security hole
and may cause GPF even in simple error cases, like invalid file content.
[vszakats] */
if( nSize > 2 && nSize <= HB_MAX_BMP_SIZE )
{
pBuffer = ( char * ) hb_xgrab( nSize + 1 );
if( hb_fileReadAt( pFile, pBuffer, nSize, 0 ) != nSize ||
hbwin_bitmapType( pBuffer, nSize ) == HB_WIN_BITMAP_UNKNOWN )
{
hb_xfree( pBuffer );
pBuffer = NULL;
}
else
hb_retclen_buffer( pBuffer, nSize );
if( nSize <= 2 || hbwin_bitmapType( pBuffer, nSize ) == HB_WIN_BITMAP_UNKNOWN )
{
hb_xfree( pBuffer );
pBuffer = NULL;
}
hb_fileClose( pFile );
}
if( pBuffer == NULL )
if( pBuffer )
hb_retclen_buffer( pBuffer, nSize );
else
hb_retc_null();
}

View File

@@ -927,6 +927,7 @@ DYNAMIC hb_vfHandle
DYNAMIC hb_vfLink
DYNAMIC hb_vfLinkRead
DYNAMIC hb_vfLinkSym
DYNAMIC hb_vfLoad
DYNAMIC hb_vfLock
DYNAMIC hb_vfLockTest
DYNAMIC hb_vfOpen

View File

@@ -418,6 +418,7 @@ 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 );
extern HB_EXPORT HB_BYTE * hb_fileLoadData( PHB_FILE pFile, HB_SIZE nMaxSize, HB_SIZE * pnSize );
/* interface to PRG level hb_vf*() file pointer items */

View File

@@ -1490,68 +1490,58 @@ HB_SIZE hb_fileResult( HB_SIZE nSize )
#define HB_FILELOAD_BUFFERSIZE 65536
HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize,
HB_SIZE * pnSize )
HB_BYTE * hb_fileLoadData( PHB_FILE pFile, 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 );
HB_FOFFSET nFileSize = hb_fileSize( pFile );
if( pFile != NULL )
if( nFileSize == FS_ERROR ||
( nFileSize == 0 && hb_fsError() == HB_FILE_ERR_UNSUPPORTED ) )
{
HB_FOFFSET nFileSize = hb_fileSize( pFile );
HB_SIZE nRead, nBufSize = 0;
if( nFileSize == FS_ERROR ||
( nFileSize == 0 && hb_fsError() == HB_FILE_ERR_UNSUPPORTED ) )
for( ;; )
{
HB_SIZE nRead, nBufSize = 0;
for( ;; )
if( nBufSize == nSize )
{
if( nBufSize == nSize )
nBufSize += nBufSize == 0 ? HB_FILELOAD_BUFFERSIZE : nBufSize >> 1;
if( nMaxSize > 0 && nBufSize > nMaxSize )
{
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 );
nBufSize = nMaxSize;
if( nBufSize == nSize )
break;
}
nRead = hb_fileRead( pFile, pFileBuf + nSize, nBufSize - nSize, -1 );
if( nRead == 0 || nRead == ( HB_SIZE ) FS_ERROR )
break;
nSize += nRead;
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;
}
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;
}
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( nSize > 0 )
{
pFileBuf = ( HB_BYTE * ) hb_xrealloc( pFileBuf, nSize + 1 );
pFileBuf[ nSize ] = '\0';
}
else if( pFileBuf )
{
hb_xfree( pFileBuf );
pFileBuf = NULL;
}
if( pnSize )
@@ -1559,3 +1549,23 @@ HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize,
return pFileBuf;
}
HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize,
HB_SIZE * pnSize )
{
HB_BYTE * pFileBuf = NULL;
PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL,
FO_READ | FO_SHARED | FO_PRIVATE |
FXO_SHARELOCK | FXO_NOSEEKPOS,
NULL, NULL );
if( pFile != NULL )
{
pFileBuf = hb_fileLoadData( pFile, nMaxSize, pnSize );
hb_fileClose( pFile );
}
else if( pnSize )
*pnSize = 0;
return pFileBuf;
}

View File

@@ -856,3 +856,19 @@ HB_FUNC( HB_VFTEMPFILE )
hb_fsSetFError( hb_fsError() );
hb_storc( szName, 1 );
}
/* hb_vfLoad( <cFileName>, [ <nMaxSize> ] ) -> <cFileBody> | NIL */
HB_FUNC( HB_VFLOAD )
{
const char * pszFileName = hb_parc( 1 );
if( pszFileName )
{
HB_SIZE nSize;
char * pBuffer = ( char * ) hb_fileLoad( pszFileName, hb_parns( 2 ), &nSize );
if( pBuffer )
hb_retclen_buffer( pBuffer, nSize );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 2021, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

View File

@@ -602,20 +602,18 @@ static PHRB_BODY hb_hrbLoadFromFile( const char * szHrb, HB_USHORT usMode )
if( pFile != NULL )
{
HB_SIZE nBodySize = ( HB_SIZE ) hb_fileSize( pFile );
HB_SIZE nBodySize;
HB_BYTE * pBuffer = hb_fileLoadData( pFile, 0, &nBodySize );
if( nBodySize )
{
char * pbyBuffer;
pbyBuffer = ( char * ) hb_xgrab( nBodySize + sizeof( char ) + 1 );
hb_fileReadAt( pFile, pbyBuffer, nBodySize, 0 );
pbyBuffer[ nBodySize ] = '\0';
pHrbBody = hb_hrbLoad( ( const char * ) pbyBuffer, nBodySize, usMode, szHrb );
hb_xfree( pbyBuffer );
}
hb_fileClose( pFile );
if( pBuffer )
{
pHrbBody = hb_hrbLoad( ( const char * ) pBuffer, nBodySize, usMode, szHrb );
hb_xfree( pBuffer );
}
else
hb_errRT_BASE( EG_CORRUPTION, 9998, NULL, HB_ERR_FUNCNAME, 0 );
}
return pHrbBody;