NS_IMETHODIMP nsTemporaryFileInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, uint32_t count, uint32_t * result) { NS_ASSERTION(result, "null ptr"); NS_ASSERTION(mCurPos <= mEndPos, "bad stream state"); *result = 0; if (mClosed) { return NS_BASE_STREAM_CLOSED; } mozilla::MutexAutoLock lock(mFileDescOwner->FileMutex()); int64_t offset = PR_Seek64(mFileDescOwner->mFD, mCurPos, PR_SEEK_SET); if (offset == -1) { return NS_ErrorAccordingToNSPR(); } // Limit requested count to the amount remaining in our section of the file. count = std::min(count, uint32_t(mEndPos - mCurPos)); char buf[4096]; while (*result < count) { uint32_t bufCount = std::min(count - *result, (uint32_t) sizeof(buf)); int32_t bytesRead = PR_Read(mFileDescOwner->mFD, buf, bufCount); if (bytesRead < 0) { return NS_ErrorAccordingToNSPR(); } int32_t bytesWritten = 0; while (bytesWritten < bytesRead) { uint32_t writerCount = 0; nsresult rv = writer(this, closure, buf + bytesWritten, *result, bytesRead - bytesWritten, &writerCount); if (NS_FAILED(rv) || writerCount == 0) { // nsIInputStream::ReadSegments' contract specifies that errors // from writer are not propagated to ReadSegments' caller. // // If writer fails, leaving bytes still in buf, that's okay: we // only update mCurPos to reflect successful writes, so the call // to PR_Seek64 at the top will restart us at the right spot. return NS_OK; } NS_ASSERTION(writerCount <= (uint32_t) (bytesRead - bytesWritten), "writer should not write more than we asked it to write"); bytesWritten += writerCount; *result += writerCount; mCurPos += writerCount; } } return NS_OK; }
/* unsigned long available (); */ NS_IMETHODIMP nsMsgFileStream::Available(PRUint32 *aResult) { if (!mFileDesc) return NS_BASE_STREAM_CLOSED; PRInt32 avail = PR_Available(mFileDesc); if (avail == -1) return NS_ErrorAccordingToNSPR(); *aResult = avail; return NS_OK; }
NS_IMETHODIMP nsMsgFileStream::Seek(PRInt32 whence, PRInt64 offset) { if (mFileDesc == nsnull) return NS_BASE_STREAM_CLOSED; nsInt64 cnt = PR_Seek64(mFileDesc, offset, (PRSeekWhence)whence); if (cnt == nsInt64(-1)) { return NS_ErrorAccordingToNSPR(); } return NS_OK; }
NS_IMETHODIMP nsMsgFileStream::Flush(void) { if (mFileDesc == nsnull) return NS_BASE_STREAM_CLOSED; PRInt32 cnt = PR_Sync(mFileDesc); if (cnt == -1) return NS_ErrorAccordingToNSPR(); return NS_OK; }
NS_IMETHODIMP nsFileOutputStream::Flush(void) { if (mFD == nsnull) return NS_BASE_STREAM_CLOSED; PRInt32 cnt = PR_Sync(mFD); if (cnt == -1) { return NS_ErrorAccordingToNSPR(); } return NS_OK; }
NS_IMETHODIMP nsMsgFileStream::Tell(PRInt64 *result) { if (mFileDesc == nsnull) return NS_BASE_STREAM_CLOSED; nsInt64 cnt = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR); if (cnt == nsInt64(-1)) { return NS_ErrorAccordingToNSPR(); } *result = cnt; return NS_OK; }
NS_IMETHODIMP nsMsgFileStream::Write(const char *buf, PRUint32 count, PRUint32 *result) { if (mFileDesc == nsnull) return NS_BASE_STREAM_CLOSED; PRInt32 cnt = PR_Write(mFileDesc, buf, count); if (cnt == -1) { return NS_ErrorAccordingToNSPR(); } *result = cnt; return NS_OK; }
NS_IMETHODIMP nsFileInputStream::Available(PRUint32* aResult) { if (!mFD) { return NS_BASE_STREAM_CLOSED; } PRInt32 avail = PR_Available(mFD); if (avail == -1) { return NS_ErrorAccordingToNSPR(); } *aResult = avail; return NS_OK; }
/* [noscript] unsigned long read (in charPtr aBuf, in unsigned long aCount); */ NS_IMETHODIMP nsMsgFileStream::Read(char * aBuf, PRUint32 aCount, PRUint32 *aResult) { if (!mFileDesc) { *aResult = 0; return NS_OK; } PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount); if (bytesRead == -1) return NS_ErrorAccordingToNSPR(); *aResult = bytesRead; return NS_OK; }
nsresult FileLocation::Data::Copy(char *buf, uint32_t len) { if (mFd) { for (uint32_t totalRead = 0; totalRead < len; ) { int32_t read = PR_Read(mFd, buf + totalRead, NS_MIN(len - totalRead, uint32_t(PR_INT32_MAX))); if (read < 0) return NS_ErrorAccordingToNSPR(); totalRead += read; } return NS_OK; } else if (mItem) { nsZipCursor cursor(mItem, mZip, reinterpret_cast<uint8_t *>(buf), len, true); uint32_t readLen; cursor.Copy(&readLen); return (readLen == len) ? NS_OK : NS_ERROR_FILE_CORRUPTED; } return NS_ERROR_NOT_INITIALIZED; }
nsresult FileLocation::Data::GetSize(uint32_t *result) { if (mFd) { PRFileInfo64 fileInfo; if (PR_SUCCESS != PR_GetOpenFileInfo64(mFd, &fileInfo)) return NS_ErrorAccordingToNSPR(); if (fileInfo.size > int64_t(PR_UINT32_MAX)) return NS_ERROR_FILE_TOO_BIG; *result = fileInfo.size; return NS_OK; } else if (mItem) { *result = mItem->RealSize(); return NS_OK; } return NS_ERROR_NOT_INITIALIZED; }
NS_IMETHODIMP nsTemporaryFileInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, uint32_t count, uint32_t * result) { NS_ASSERTION(result, "null ptr"); NS_ASSERTION(mStartPos <= mEndPos, "bad stream state"); *result = 0; if (mClosed) { return NS_BASE_STREAM_CLOSED; } mozilla::MutexAutoLock lock(mFileDescOwner->FileMutex()); PR_Seek64(mFileDescOwner->mFD, mStartPos, PR_SEEK_SET); count = std::min(count, uint32_t(mEndPos - mStartPos)); uint32_t remainBufCount = count; char buf[4096]; while (remainBufCount > 0) { uint32_t bufCount = std::min(remainBufCount, (uint32_t)sizeof(buf)); int32_t read_result = PR_Read(mFileDescOwner->mFD, buf, bufCount); if (read_result < 0) { return NS_ErrorAccordingToNSPR(); } uint32_t write_result = 0; nsresult rv = writer(this, closure, buf, count - remainBufCount, bufCount, &write_result); remainBufCount -= bufCount; if (NS_SUCCEEDED(rv)) { NS_ASSERTION(write_result <= bufCount, "writer should not write more than we asked it to write"); } mStartPos += bufCount; } *result = count; return NS_OK; }
NS_IMETHODIMP nsFileInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aResult) { if (!mFD) { *aResult = 0; return NS_OK; } PRInt32 bytesRead = PR_Read(mFD, aBuf, aCount); if (bytesRead == -1) { return NS_ErrorAccordingToNSPR(); } // Check if we're at the end of file and need to close if (mBehaviorFlags & CLOSE_ON_EOF) { if (bytesRead == 0) { Close(); } } *aResult = bytesRead; return NS_OK; }