static HB_FOFFSET getblock( PFT_DISPC dispc, HB_FOFFSET offset ) { /* set the file pointer to the proper offset and if an error occured then check to see if a positive offset was requested, if so then set the pointer to the offset from the end of the file, otherwise set it from the beginning of the file. */ hb_fsSeekLarge( dispc->infile, offset, FS_SET ); /* read in the file and set the buffer bottom variable equal */ /* to the number of bytes actually read in. */ dispc->buffbot = hb_fsReadLarge( dispc->infile, dispc->buffer, dispc->buffsize ); /* if a full buffer's worth was not read in, make it full. */ if( dispc->buffbot != dispc->buffsize && dispc->fsize > dispc->buffsize ) { if( offset > 0 ) hb_fsSeekLarge( dispc->infile, -dispc->buffsize, FS_END ); else hb_fsSeekLarge( dispc->infile, dispc->buffsize, FS_SET ); dispc->buffbot = hb_fsReadLarge( dispc->infile, dispc->buffer, dispc->buffsize ); } /* return the actual file position */ return hb_fsSeekLarge( dispc->infile, 0, FS_RELATIVE ) - dispc->buffbot; }
/* deletes xxx bytes from the current file, beginning at the current record */ static int _del_buff( PFT_TEXT ft_text, HB_ISIZ iLen ) { char * WriteBuff = ( char * ) hb_xgrab( BUFFSIZE ); HB_FOFFSET fpRead, fpWrite; HB_ISIZ WriteLen; HB_ISIZ SaveLen; /* initialize file pointers */ fpWrite = ft_text->offset[ ft_text->area ]; fpRead = ft_text->offset[ ft_text->area ] + iLen; /* do initial load of buffer */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpRead, FS_SET ); WriteLen = hb_fsRead( ft_text->handles[ ft_text->area ], WriteBuff, BUFFSIZE ); fpRead += WriteLen; ft_text->error[ ft_text->area ] = 0; while( WriteLen > 0 ) { /* position to beginning of write area */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpWrite, FS_SET ); SaveLen = hb_fsWriteLarge( ft_text->handles[ ft_text->area ], WriteBuff, WriteLen ); /* move write pointer */ fpWrite += SaveLen; if( SaveLen != WriteLen ) { /* error, fetch errcode and quit */ ft_text->error[ ft_text->area ] = hb_fsError(); break; } /* return to read area and read another buffer */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpRead, FS_SET ); WriteLen = hb_fsRead( ft_text->handles[ ft_text->area ], WriteBuff, BUFFSIZE ); fpRead += WriteLen; } /* store length in bytes, set legacy EOF marker */ ft_text->lastbyte[ ft_text->area ] = hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpWrite, FS_SET ); hb_fsWrite( ft_text->handles[ ft_text->area ], WriteBuff, 0 ); /* clear last_rec so next gobot will recount the records */ ft_text->last_rec[ ft_text->area ] = 0; hb_fsSeekLarge( ft_text->handles[ ft_text->area ], ft_text->offset[ ft_text->area ], FS_SET ); hb_xfree( WriteBuff ); return ft_text->error[ ft_text->area ]; }
static HB_SIZE ct_StrFile( const char * pFileName, const char * pcStr, HB_SIZE nLen, HB_BOOL bOverwrite, HB_FOFFSET nOffset, HB_BOOL bTrunc ) { HB_FHANDLE hFile; HB_BOOL bOpen = HB_FALSE; HB_BOOL bFile = hb_fsFile( pFileName ); HB_SIZE nWrite = 0; if( bFile && bOverwrite ) { hFile = hb_fsOpen( pFileName, FO_READWRITE ); bOpen = HB_TRUE; } else if( ! bFile || ! ct_getsafety() ) hFile = hb_fsCreate( pFileName, ct_getfcreate() ); else hFile = FS_ERROR; if( hFile != FS_ERROR ) { if( nOffset ) hb_fsSeekLarge( hFile, nOffset, FS_SET ); else if( bOpen ) hb_fsSeek( hFile, 0, FS_END ); nWrite = hb_fsWriteLarge( hFile, pcStr, nLen ); if( ( nWrite == nLen ) && bOpen && bTrunc ) hb_fsWrite( hFile, NULL, 0 ); hb_fsClose( hFile ); } return nWrite; }
static const char * s_findFileMimeType( HB_FHANDLE fileIn ) { char buf[ 512 ]; int iLen; HB_FOFFSET nPos; nPos = hb_fsSeekLarge( fileIn, 0, FS_RELATIVE ); hb_fsSeek( fileIn, 0, FS_SET ); iLen = hb_fsRead( fileIn, buf, sizeof( buf ) ); if( iLen > 0 ) { hb_fsSeekLarge( fileIn, nPos, FS_SET ); return s_findStringMimeType( buf, iLen ); } return NULL; }
HB_FOFFSET hb_fsFSize( const char * pszFileName, HB_BOOL bUseDirEntry ) { if( bUseDirEntry ) { #if defined( HB_OS_WIN ) PHB_FFIND ffind = hb_fsFindFirst( pszFileName, HB_FA_ALL ); hb_fsSetIOError( ffind != NULL, 0 ); if( ffind ) { HB_FOFFSET size = ffind->size; hb_fsFindClose( ffind ); return size; } #elif defined( HB_USE_LARGEFILE64 ) char * pszFree; HB_BOOL fResult; struct stat64 statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat64( pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #else char * pszFree; HB_BOOL fResult; struct stat statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat( ( char * ) pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #endif } else { HB_FHANDLE hFileHandle = hb_fsOpen( pszFileName, FO_READ | FO_COMPAT ); if( hFileHandle != FS_ERROR ) { HB_FOFFSET nPos = hb_fsSeekLarge( hFileHandle, 0, FS_END ); hb_fsClose( hFileHandle ); return nPos; } } return 0; }
static char * hb_fsReadLine( HB_FHANDLE hFileHandle, HB_ISIZ * plBuffLen, const char ** pTerm, HB_ISIZ * pnTermSizes, HB_ISIZ nTerms, HB_BOOL * pbFound, HB_BOOL * pbEOF ) { HB_ISIZ nPosTerm = 0, nPos, nPosition; int nTries; HB_ISIZ nRead = 0, nOffset, nSize; char * pBuff; HB_TRACE( HB_TR_DEBUG, ( "hb_fsReadLine(%p, %" HB_PFS "d, %p, %p, %" HB_PFS "d, %p, %p)", ( void * ) ( HB_PTRUINT ) hFileHandle, *plBuffLen, pTerm, pnTermSizes, nTerms, pbFound, pbEOF ) ); *pbFound = HB_FALSE; *pbEOF = HB_FALSE; nTries = 0; nOffset = 0; nSize = *plBuffLen; if( *plBuffLen < 10 ) *plBuffLen = READING_BLOCK; pBuff = ( char * ) hb_xgrab( *plBuffLen + 1 ); do { if( nTries > 0 ) { /* pBuff can be enlarged to hold the line as needed.. */ nSize = ( *plBuffLen * ( nTries + 1 ) ) + 1; pBuff = ( char * ) hb_xrealloc( pBuff, nSize ); nOffset += nRead; } /* read from file */ nRead = hb_fsReadLarge( hFileHandle, pBuff + nOffset, nSize - nOffset ); /* scan the read buffer */ if( nRead > 0 ) { for( nPos = 0; nPos < nRead; nPos++ ) { for( nPosTerm = 0; nPosTerm < nTerms; nPosTerm++ ) { /* Compare with the LAST terminator byte */ if( pBuff[ nOffset + nPos ] == pTerm[ nPosTerm ][ pnTermSizes[ nPosTerm ] - 1 ] && ( pnTermSizes[ nPosTerm ] - 1 ) <= ( nPos + nOffset ) ) { *pbFound = HB_TRUE; for( nPosition = 0; nPosition < ( pnTermSizes[ nPosTerm ] - 1 ); nPosition++ ) { if( pTerm[ nPosTerm ][ nPosition ] != pBuff[ nOffset + ( nPos - pnTermSizes[ nPosTerm ] ) + nPosition + 1 ] ) { *pbFound = HB_FALSE; break; } } if( *pbFound ) break; } } if( *pbFound ) break; } if( *pbFound ) { *plBuffLen = nOffset + nPos - pnTermSizes[ nPosTerm ] + 1; pBuff[ *plBuffLen ] = '\0'; /* Set handle pointer in the end of the line */ hb_fsSeekLarge( hFileHandle, ( ( nRead - nPos ) * -1 ) + 1, FS_RELATIVE ); return pBuff; } } else { if( ! *pbFound ) { if( nTries == 0 ) { pBuff[ 0 ] = '\0'; *plBuffLen = 0; } else { pBuff[ nOffset + nRead ] = '\0'; *plBuffLen = nOffset + nRead; } *pbEOF = HB_TRUE; } } nTries++; } while( ! *pbFound && nRead > 0 ); return pBuff; }
static HB_FOFFSET s_fileSize( PHB_FILE pFile ) { return hb_fsSeekLarge( pFile->hFile, 0, FS_END ); }
static HB_FOFFSET s_fileSeek( PHB_FILE pFile, HB_FOFFSET nOffset, HB_USHORT uiFlags ) { return hb_fsSeekLarge( pFile->hFile, nOffset, uiFlags ); }
/* internal routine to do buffer skips. Passing a positive value performs a downward skip, a negative number does an upward skip. Passing 0 skips to the end of file. Returns a long indicating the number of records skipped */ static long _ft_skip( long iRecs ) { PFT_TEXT ft_text = ( PFT_TEXT ) hb_stackGetTSD( &s_ft_text ); HB_ISIZ iByteCount; HB_ISIZ iBytesRead, iBytesRemaining; char * cPtr; long iSkipped = 0; char * cBuff = ( char * ) hb_xgrab( BUFFSIZE ); HB_FOFFSET fpOffset = ft_text->offset[ ft_text->area ]; ft_text->isBof[ ft_text->area ] = HB_FALSE; ft_text->isEof[ ft_text->area ] = HB_FALSE; ft_text->error[ ft_text->area ] = 0; /* iRecs is zero if they want to find the EOF, start a top of file */ if( iRecs == 0 ) { fpOffset = 0; ft_text->recno[ ft_text->area ] = 1; } if( iRecs >= 0 ) { do { cPtr = cBuff; /* position file pointer to beginning of current record */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpOffset, FS_SET ); /* read a chunk */ iBytesRead = hb_fsRead( ft_text->handles[ ft_text->area ], cBuff, BUFFSIZE ); if( ! iBytesRead ) { /* buffer is empty thus EOF, set vars and quit */ ft_text->isEof[ ft_text->area ] = HB_TRUE; ft_text->last_rec[ ft_text->area ] = ft_text->recno[ ft_text->area ]; ft_text->last_off[ ft_text->area ] = ft_text->offset[ ft_text->area ]; ft_text->error[ ft_text->area ] = hb_fsError(); break; } iBytesRemaining = iBytesRead; /* parse the buffer while there's still stuff in it */ do { /* get count of chars in this line */ iByteCount = _findeol( cPtr, iBytesRemaining, NULL ); if( iByteCount > 0 && iByteCount != iBytesRemaining ) { /* found an EOL, iByteCount points to first char of next record */ iBytesRemaining -= iByteCount; fpOffset += iByteCount; cPtr += iByteCount; ft_text->offset[ ft_text->area ] = fpOffset; ft_text->recno[ ft_text->area ]++; iSkipped++; if( iRecs && ( iSkipped == iRecs ) ) iBytesRemaining = iBytesRead = 0; } else { /* no more EOLs in this buffer, or EOL is last chars in the buffer */ /* check for EOF */ if( iBytesRead != BUFFSIZE ) { /* buffer was not full, thus EOF, set vars and quit */ iBytesRemaining = 0; ft_text->last_rec[ ft_text->area ] = ft_text->recno[ ft_text->area ]; ft_text->last_off[ ft_text->area ] = ft_text->offset[ ft_text->area ]; if( iRecs ) ft_text->isEof[ ft_text->area ] = HB_TRUE; } else { /* buffer was full, so probably not EOF, but maybe EOL straddled end of buffer, so back up pointer a bit before doing the next read */ fpOffset = hb_fsSeekLarge( ft_text->handles[ ft_text->area ], 0, FS_RELATIVE ) - 1; iBytesRemaining = 0; } } } while( iBytesRemaining > 0 ); } while( iBytesRead == BUFFSIZE ); } else { /* skip backwards */ iRecs = -iRecs; if( ft_text->recno[ ft_text->area ] > iRecs ) { do { /* calc offset to read area of file ahead of current pointer */ fpOffset = HB_MAX( ft_text->offset[ ft_text->area ] - BUFFSIZE, 0 ); /* move file pointer */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpOffset, FS_SET ); /* read a chunk */ iBytesRead = hb_fsRead( ft_text->handles[ ft_text->area ], cBuff, BUFFSIZE ); if( ! iBytesRead ) { /* buffer is empty thus file is zero len, set vars and quit */ ft_text->isBof[ ft_text->area ] = HB_TRUE; ft_text->isEof[ ft_text->area ] = HB_TRUE; ft_text->recno[ ft_text->area ] = 0; ft_text->offset[ ft_text->area ] = 0; ft_text->last_rec[ ft_text->area ] = 0; ft_text->error[ ft_text->area ] = hb_fsError(); break; } /* set pointer within buffer */ iBytesRemaining = ( int ) ( ft_text->offset[ ft_text->area ] - fpOffset ); cPtr = cBuff + iBytesRemaining; /* parse the buffer while there's still stuff in it */ do { /* get count of chars in this line */ iByteCount = _findbol( cPtr, iBytesRemaining ); if( iByteCount > 0 ) { /* found an EOL, iByteCount points to first char of next record */ iBytesRemaining -= iByteCount; ft_text->offset[ ft_text->area ] -= iByteCount; cPtr -= iByteCount; fpOffset = ft_text->offset[ ft_text->area ]; ft_text->recno[ ft_text->area ]--; iSkipped++; if( iSkipped == iRecs ) iBytesRemaining = iBytesRead = 0; } else { /* no more EOLs in this buffer so we're either at BOF or record crosses buffer boundary */ /* check for BOF */ if( iBytesRead != BUFFSIZE ) { /* buffer was not full, thus BOF, set vars and quit */ iBytesRemaining = 0; ft_text->offset[ ft_text->area ] = 0; ft_text->recno[ ft_text->area ] = 1; ft_text->isBof[ ft_text->area ] = HB_TRUE; } else { /* buffer was full, so not BOF */ iBytesRemaining = 0; } } } while( iBytesRemaining > 0 ); } while( fpOffset > 0 && iBytesRead == BUFFSIZE ); } else { ft_text->offset[ ft_text->area ] = 0; ft_text->recno[ ft_text->area ] = 1; ft_text->isBof[ ft_text->area ] = HB_TRUE; } } hb_xfree( cBuff ); return iSkipped; }
/* the contents of the inserted bytes are indeterminate, i.e. you'll have to write to them before they mean anything */ static int _ins_buff( PFT_TEXT ft_text, HB_ISIZ iLen ) { char * ReadBuff = ( char * ) hb_xgrab( BUFFSIZE ); char * WriteBuff = ( char * ) hb_xgrab( BUFFSIZE ); char * SaveBuff; HB_FOFFSET fpRead, fpWrite; HB_ISIZ WriteLen, ReadLen; HB_ISIZ SaveLen; HB_ISIZ iLenRemaining = iLen; /* set target move distance, this allows iLen to be greater than BUFFSIZE */ iLen = HB_MIN( iLenRemaining, BUFFSIZE ); iLenRemaining -= iLen; /* initialize file pointers */ fpRead = ft_text->offset[ ft_text->area ]; fpWrite = ft_text->offset[ ft_text->area ] + iLen; /* do initial load of both buffers */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpRead, FS_SET ); WriteLen = hb_fsRead( ft_text->handles[ ft_text->area ], WriteBuff, BUFFSIZE ); fpRead += WriteLen; ReadLen = hb_fsRead( ft_text->handles[ ft_text->area ], ReadBuff, BUFFSIZE ); fpRead += ReadLen; ft_text->error[ ft_text->area ] = 0; while( ! ft_text->error[ ft_text->area ] && iLen > 0 ) { while( WriteLen > 0 ) { /* position to beginning of write area */ if( hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpWrite, FS_SET ) != fpWrite ) { ft_text->error[ ft_text->area ] = hb_fsError(); break; } SaveLen = hb_fsWriteLarge( ft_text->handles[ ft_text->area ], WriteBuff, WriteLen ); if( ! SaveLen ) { ft_text->error[ ft_text->area ] = hb_fsError(); break; } /* move write pointer */ fpWrite += SaveLen; if( SaveLen != WriteLen ) { /* error, fetch errcode and quit */ ft_text->error[ ft_text->area ] = hb_fsError(); break; } #if 0 WriteLen = SaveLen; #endif /* swap buffers */ SaveBuff = WriteBuff; WriteBuff = ReadBuff; ReadBuff = SaveBuff; WriteLen = ReadLen; /* return to read area and read another buffer */ hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpRead, FS_SET ); ReadLen = hb_fsRead( ft_text->handles[ ft_text->area ], ReadBuff, BUFFSIZE ); fpRead += ReadLen; } iLen = HB_MIN( iLenRemaining, BUFFSIZE ); iLenRemaining -= iLen; } /* store length in bytes, set legacy EOF marker */ ft_text->lastbyte[ ft_text->area ] = hb_fsSeekLarge( ft_text->handles[ ft_text->area ], fpWrite, FS_SET ); hb_fsWrite( ft_text->handles[ ft_text->area ], WriteBuff, 0 ); /* clear last_rec so next gobot will recount the records */ ft_text->last_rec[ ft_text->area ] = 0; hb_fsSeekLarge( ft_text->handles[ ft_text->area ], ft_text->offset[ ft_text->area ], FS_SET ); hb_xfree( ReadBuff ); hb_xfree( WriteBuff ); return ft_text->error[ ft_text->area ]; }
HB_FOFFSET hb_fsFSize( const char * pszFileName, HB_BOOL bUseDirEntry ) { if( bUseDirEntry ) { #if defined( HB_OS_WIN ) typedef BOOL ( WINAPI * _HB_GETFILEATTRIBUTESEX )( LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID ); static _HB_GETFILEATTRIBUTESEX s_pGetFileAttributesEx = ( _HB_GETFILEATTRIBUTESEX ) -1; if( s_pGetFileAttributesEx == ( _HB_GETFILEATTRIBUTESEX ) -1 ) { HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); if( hModule ) s_pGetFileAttributesEx = ( _HB_GETFILEATTRIBUTESEX ) HB_WINAPI_GETPROCADDRESST( hModule, "GetFileAttributesEx" ); else s_pGetFileAttributesEx = NULL; } if( s_pGetFileAttributesEx ) { LPCTSTR lpFileName; LPTSTR lpFree; WIN32_FILE_ATTRIBUTE_DATA attrex; HB_BOOL fResult; lpFileName = HB_FSNAMECONV( pszFileName, &lpFree ); memset( &attrex, 0, sizeof( attrex ) ); fResult = s_pGetFileAttributesEx( lpFileName, GetFileExInfoStandard, &attrex ) && ( attrex.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0; hb_fsSetIOError( fResult, 0 ); if( lpFree ) hb_xfree( lpFree ); if( fResult ) return ( HB_FOFFSET ) attrex.nFileSizeLow + ( ( HB_FOFFSET ) attrex.nFileSizeHigh << 32 ); } else { PHB_FFIND ffind = hb_fsFindFirst( pszFileName, HB_FA_ALL ); hb_fsSetIOError( ffind != NULL, 0 ); if( ffind ) { HB_FOFFSET size = ffind->size; hb_fsFindClose( ffind ); return size; } } #elif defined( HB_USE_LARGEFILE64 ) char * pszFree; HB_BOOL fResult; struct stat64 statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat64( pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #else char * pszFree; HB_BOOL fResult; struct stat statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat( ( char * ) pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #endif } else { HB_FHANDLE hFileHandle = hb_fsOpen( pszFileName, FO_READ | FO_COMPAT ); if( hFileHandle != FS_ERROR ) { HB_FOFFSET nPos = hb_fsSeekLarge( hFileHandle, 0, FS_END ); hb_fsClose( hFileHandle ); return nPos; } } return 0; }