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;
}
예제 #5
0
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;
}
예제 #8
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #13
0
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;
}