示例#1
0
// nsISeekableStream
NS_IMETHODIMP
CacheFileInputStream::Seek(int32_t whence, int64_t offset)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::Seek() [this=%p, whence=%d, offset=%lld]",
       this, whence, offset));

  if (mClosed) {
    LOG(("CacheFileInputStream::Seek() - Stream is closed. [this=%p]", this));
    return NS_BASE_STREAM_CLOSED;
  }

  int64_t newPos = offset;
  switch (whence) {
    case NS_SEEK_SET:
      break;
    case NS_SEEK_CUR:
      newPos += mPos;
      break;
    case NS_SEEK_END:
      newPos += mFile->mDataSize;
      break;
    default:
      NS_ERROR("invalid whence");
      return NS_ERROR_INVALID_ARG;
  }
  mPos = newPos;
  EnsureCorrectChunk(true);

  LOG(("CacheFileInputStream::Seek() [this=%p, pos=%lld]", this, mPos));
  return NS_OK;
}
示例#2
0
NS_IMETHODIMP
CacheFileInputStream::AsyncWait(nsIInputStreamCallback *aCallback,
                                uint32_t aFlags,
                                uint32_t aRequestedCount,
                                nsIEventTarget *aEventTarget)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::AsyncWait() [this=%p, callback=%p, flags=%d, "
       "requestedCount=%d, eventTarget=%p]", this, aCallback, aFlags,
       aRequestedCount, aEventTarget));

  mCallback = aCallback;
  mCallbackFlags = aFlags;

  if (!mCallback) {
    if (mWaitingForUpdate) {
      mChunk->CancelWait(this);
      mWaitingForUpdate = false;
    }
    return NS_OK;
  }

  if (mClosed) {
    NotifyListener();
    return NS_OK;
  }

  EnsureCorrectChunk(false);

  MaybeNotifyListener();

  return NS_OK;
}
示例#3
0
NS_IMETHODIMP
CacheFileInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
                                   uint32_t aCount, uint32_t *_retval)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::ReadSegments() [this=%p, count=%d]",
       this, aCount));

  nsresult rv;

  if (mClosed) {
    LOG(("CacheFileInputStream::ReadSegments() - Stream is closed. [this=%p, "
         "status=0x%08x]", this, mStatus));

    if NS_FAILED(mStatus)
      return mStatus;

    *_retval = 0;
    return NS_OK;
  }

  EnsureCorrectChunk(false);
  if (!mChunk) {
    if (mListeningForChunk == -1) {
      *_retval = 0;
      return NS_OK;
    }
    else {
      return NS_BASE_STREAM_WOULD_BLOCK;
    }
  }

  int64_t canRead;
  const char *buf;
  CanRead(&canRead, &buf);

  if (canRead < 0) {
    // file was truncated ???
    MOZ_ASSERT(false, "SetEOF is currenty not implemented?!");
    *_retval = 0;
    rv = NS_OK;
  }
  else if (canRead > 0) {
    uint32_t toRead = std::min(static_cast<uint32_t>(canRead), aCount);

    // We need to release the lock to avoid lock re-entering
#ifdef DEBUG
    int64_t oldPos = mPos;
#endif
    mInReadSegments = true;
    lock.Unlock();
    rv = aWriter(this, aClosure, buf, 0, toRead, _retval);
    lock.Lock();
    mInReadSegments = false;
#ifdef DEBUG
    MOZ_ASSERT(oldPos == mPos);
#endif

    if (NS_SUCCEEDED(rv)) {
      MOZ_ASSERT(*_retval <= toRead,
                 "writer should not write more than we asked it to write");
      mPos += *_retval;
    }

    EnsureCorrectChunk(!(canRead < aCount && mPos % kChunkSize == 0));

    rv = NS_OK;
  }
  else {
    if (mFile->mOutput)
      rv = NS_BASE_STREAM_WOULD_BLOCK;
    else {
      *_retval = 0;
      rv = NS_OK;
    }
  }

  LOG(("CacheFileInputStream::ReadSegments() [this=%p, rv=0x%08x, retval=%d",
       this, rv, *_retval));

  return rv;
}
示例#4
0
NS_IMETHODIMP
CacheFileInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
                                   uint32_t aCount, uint32_t *_retval)
{
  CacheFileAutoLock lock(mFile);

  LOG(("CacheFileInputStream::ReadSegments() [this=%p, count=%d]",
       this, aCount));

  nsresult rv;

  *_retval = 0;

  if (mClosed) {
    LOG(("CacheFileInputStream::ReadSegments() - Stream is closed. [this=%p, "
         "status=0x%08x]", this, mStatus));

    if NS_FAILED(mStatus)
      return mStatus;

    return NS_OK;
  }

  EnsureCorrectChunk(false);

  while (true) {
    if (NS_FAILED(mStatus))
      return mStatus;

    if (!mChunk) {
      if (mListeningForChunk == -1) {
        return NS_OK;
      }
      else {
        return NS_BASE_STREAM_WOULD_BLOCK;
      }
    }

    int64_t canRead;
    const char *buf;
    CanRead(&canRead, &buf);
    if (NS_FAILED(mStatus)) {
      return mStatus;
    }

    if (canRead < 0) {
      // file was truncated ???
      MOZ_ASSERT(false, "SetEOF is currenty not implemented?!");
      rv = NS_OK;
    } else if (canRead > 0) {
      uint32_t toRead = std::min(static_cast<uint32_t>(canRead), aCount);

      uint32_t read;
      rv = aWriter(this, aClosure, buf, *_retval, toRead, &read);

      if (NS_SUCCEEDED(rv)) {
        MOZ_ASSERT(read <= toRead,
                   "writer should not write more than we asked it to write");

        *_retval += read;
        mPos += read;
        aCount -= read;

        // The last chunk is released after the caller closes this stream.
        EnsureCorrectChunk(false);

        if (mChunk && aCount) {
          // We have the next chunk! Go on.
          continue;
        }
      }

      rv = NS_OK;
    } else {
      if (mFile->mOutput)
        rv = NS_BASE_STREAM_WOULD_BLOCK;
      else {
        rv = NS_OK;
      }
    }

    break;
  }

  LOG(("CacheFileInputStream::ReadSegments() [this=%p, rv=0x%08x, retval=%d]",
       this, rv, *_retval));

  return rv;
}