int VSIUnixStdioHandle::Seek( vsi_l_offset nOffset, int nWhence ) { // seeks that do nothing are still surprisingly expensive with MSVCRT. // try and short circuit if possible. if( nWhence == SEEK_SET && nOffset == this->nOffset ) return 0; int nResult = VSI_FSEEK64( fp, nOffset, nWhence ); int nError = errno; #ifdef VSI_DEBUG if( nWhence == SEEK_SET ) { VSIDebug3( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",SEEK_SET) = %d", fp, nOffset, nResult ); } else if( nWhence == SEEK_END ) { VSIDebug3( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",SEEK_END) = %d", fp, nOffset, nResult ); } else if( nWhence == SEEK_CUR ) { VSIDebug3( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",SEEK_CUR) = %d", fp, nOffset, nResult ); } else { VSIDebug4( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",%d-Unknown) = %d", fp, nOffset, nWhence, nResult ); } #endif if( nResult != -1 ) { if( nWhence == SEEK_SET ) { this->nOffset = nOffset; } else if( nWhence == SEEK_END ) { this->nOffset = VSI_FTELL64( fp ); } else if( nWhence == SEEK_CUR ) { this->nOffset += nOffset; } } bLastOpWrite = FALSE; bLastOpRead = FALSE; bAtEOF = FALSE; errno = nError; return nResult; }
vsi_l_offset VSIUnixStdioHandle::Tell() { #ifdef notdef vsi_l_offset nOffset = VSI_FTELL64( fp ); int nError = errno; VSIDebug2( "VSIUnixStdioHandle::Tell(%p) = %ld", fp, (long)nOffset ); errno = nError; return nOffset; #endif return nOffset; }
size_t VSIUnixStdioHandle::Read( void * pBuffer, size_t nSize, size_t nCount ) { /* -------------------------------------------------------------------- */ /* If a fwrite() is followed by an fread(), the POSIX rules are */ /* that some of the write may still be buffered and lost. We */ /* are required to do a seek between to force flushing. So we */ /* keep careful track of what happened last to know if we */ /* skipped a flushing seek that we may need to do now. */ /* -------------------------------------------------------------------- */ if( bLastOpWrite ) VSI_FSEEK64( fp, nOffset, SEEK_SET ); /* -------------------------------------------------------------------- */ /* Perform the read. */ /* -------------------------------------------------------------------- */ size_t nResult = fread( pBuffer, nSize, nCount, fp ); int nError = errno; VSIDebug4( "VSIUnixStdioHandle::Read(%p,%ld,%ld) = %ld", fp, (long)nSize, (long)nCount, (long)nResult ); errno = nError; /* -------------------------------------------------------------------- */ /* Update current offset. */ /* -------------------------------------------------------------------- */ #ifdef VSI_COUNT_BYTES_READ nTotalBytesRead += nSize * nResult; #endif nOffset += nSize * nResult; bLastOpWrite = FALSE; bLastOpRead = TRUE; if (nResult != nCount) { errno = 0; vsi_l_offset nNewOffset = VSI_FTELL64( fp ); if( errno == 0 ) /* ftell() can fail if we are end of file with a pipe */ nOffset = nNewOffset; else CPLDebug("VSI", "%s", VSIStrerror(errno)); bAtEOF = feof(fp); } return nResult; }
vsi_l_offset VSIUnixStdioHandle::Tell() { return( VSI_FTELL64( fp ) ); }
int VSIUnixStdioHandle::Seek( vsi_l_offset nOffset, int nWhence ) { bAtEOF = FALSE; // seeks that do nothing are still surprisingly expensive with MSVCRT. // try and short circuit if possible. if( nWhence == SEEK_SET && nOffset == this->nOffset ) return 0; // on a read-only file, we can avoid a lseek() system call to be issued // if the next position to seek to is within the buffered page if( bReadOnly && nWhence == SEEK_SET ) { GIntBig nDiff = (GIntBig)nOffset - (GIntBig)this->nOffset; if( nDiff > 0 && nDiff < 4096 ) { GByte abyTemp[4096]; int nRead = (int)fread(abyTemp, 1, (int)nDiff, fp); if( nRead == (int)nDiff ) { this->nOffset = nOffset; bLastOpWrite = FALSE; bLastOpRead = FALSE; return 0; } } } const int nResult = VSI_FSEEK64( fp, nOffset, nWhence ); int nError = errno; #ifdef VSI_DEBUG if( nWhence == SEEK_SET ) { VSIDebug3( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",SEEK_SET) = %d", fp, nOffset, nResult ); } else if( nWhence == SEEK_END ) { VSIDebug3( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",SEEK_END) = %d", fp, nOffset, nResult ); } else if( nWhence == SEEK_CUR ) { VSIDebug3( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",SEEK_CUR) = %d", fp, nOffset, nResult ); } else { VSIDebug4( "VSIUnixStdioHandle::Seek(%p," CPL_FRMT_GUIB ",%d-Unknown) = %d", fp, nOffset, nWhence, nResult ); } #endif if( nResult != -1 ) { if( nWhence == SEEK_SET ) { this->nOffset = nOffset; } else if( nWhence == SEEK_END ) { this->nOffset = VSI_FTELL64( fp ); } else if( nWhence == SEEK_CUR ) { this->nOffset += nOffset; } } bLastOpWrite = FALSE; bLastOpRead = FALSE; errno = nError; return nResult; }