Esempio n. 1
0
nsresult
SourceBufferResource::Seek(int32_t aWhence, int64_t aOffset)
{
  SBR_DEBUG("Seek(aWhence=%d, aOffset=%lld)",
            aWhence, aOffset);
  ReentrantMonitorAutoEnter mon(mMonitor);

  int64_t newOffset = mOffset;
  switch (aWhence) {
  case nsISeekableStream::NS_SEEK_END:
    newOffset = GetLength() - aOffset;
    break;
  case nsISeekableStream::NS_SEEK_CUR:
    newOffset += aOffset;
    break;
  case nsISeekableStream::NS_SEEK_SET:
    newOffset = aOffset;
    break;
  }

  SBR_DEBUGV("newOffset=%lld GetOffset()=%llu GetLength()=%llu)",
             newOffset, mInputBuffer.GetOffset(), GetLength());
  nsresult rv = SeekInternal(newOffset);
  mon.NotifyAll();
  return rv;
}
Esempio n. 2
0
nsresult
SourceBufferResource::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
{
  SBR_DEBUGV("Read(aBuffer=%p, aCount=%u, aBytes=%p)",
             aBuffer, aCount, aBytes);
  ReentrantMonitorAutoEnter mon(mMonitor);

  return ReadInternal(aBuffer, aCount, aBytes, /* aMayBlock = */ true);
}
nsresult
SourceBufferResource::ReadInternal(char* aBuffer, uint32_t aCount, uint32_t* aBytes, bool aMayBlock)
{
  mMonitor.AssertCurrentThreadIn();
  MOZ_ASSERT_IF(!aMayBlock, aBytes);

  // Cache the offset for the read in case mOffset changes while waiting on the
  // monitor below. It's basically impossible to implement these API semantics
  // sanely. :-(
  uint64_t readOffset = mOffset;

  while (aMayBlock &&
         !mEnded &&
         readOffset + aCount > static_cast<uint64_t>(GetLength())) {
    SBR_DEBUGV("waiting for data");
    mMonitor.Wait();
    // The callers of this function should have checked this, but it's
    // possible that we had an eviction while waiting on the monitor.
    if (readOffset < mInputBuffer.GetOffset()) {
      return NS_ERROR_FAILURE;
    }
  }

  uint32_t available = GetLength() - readOffset;
  uint32_t count = std::min(aCount, available);
  SBR_DEBUGV("readOffset=%llu GetLength()=%u available=%u count=%u mEnded=%d",
             readOffset, GetLength(), available, count, mEnded);
  if (available == 0) {
    SBR_DEBUGV("reached EOF");
    *aBytes = 0;
    return NS_OK;
  }

  mInputBuffer.CopyData(readOffset, count, aBuffer);
  *aBytes = count;

  // From IRC:
  // <@cpearce>bholley: *this* is why there should only every be a ReadAt() and
  // no Read() on a Stream abstraction! there's no good answer, they all suck.
  mOffset = readOffset + count;

  return NS_OK;
}