LCOV - code coverage report
Current view: top level - netwerk/base - nsTemporaryFileInputStream.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 118 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsTemporaryFileInputStream.h"
       7             : #include "nsStreamUtils.h"
       8             : #include "mozilla/ipc/InputStreamUtils.h"
       9             : #include "private/pprio.h"
      10             : #include <algorithm>
      11             : 
      12             : using namespace mozilla;
      13             : using namespace mozilla::ipc;
      14             : 
      15             : typedef mozilla::ipc::FileDescriptor::PlatformHandleType FileHandleType;
      16             : 
      17           0 : NS_IMPL_ISUPPORTS(nsTemporaryFileInputStream,
      18             :                   nsIInputStream,
      19             :                   nsISeekableStream,
      20             :                   nsIIPCSerializableInputStream)
      21             : 
      22           0 : nsTemporaryFileInputStream::nsTemporaryFileInputStream(FileDescOwner* aFileDescOwner, uint64_t aStartPos, uint64_t aEndPos)
      23             :   : mFileDescOwner(aFileDescOwner),
      24             :     mStartPos(aStartPos),
      25             :     mCurPos(aStartPos),
      26             :     mEndPos(aEndPos),
      27           0 :     mClosed(false)
      28             : {
      29           0 :   NS_ASSERTION(aStartPos <= aEndPos, "StartPos should less equal than EndPos!");
      30           0 : }
      31             : 
      32           0 : nsTemporaryFileInputStream::nsTemporaryFileInputStream()
      33             :   : mStartPos(0),
      34             :     mCurPos(0),
      35             :     mEndPos(0),
      36           0 :     mClosed(false)
      37             : {
      38           0 : }
      39             : 
      40             : NS_IMETHODIMP
      41           0 : nsTemporaryFileInputStream::Close()
      42             : {
      43           0 :   mClosed = true;
      44           0 :   return NS_OK;
      45             : }
      46             : 
      47             : NS_IMETHODIMP
      48           0 : nsTemporaryFileInputStream::Available(uint64_t * bytesAvailable)
      49             : {
      50           0 :   if (mClosed)
      51           0 :     return NS_BASE_STREAM_CLOSED;
      52             : 
      53           0 :   NS_ASSERTION(mCurPos <= mEndPos, "CurPos should less equal than EndPos!");
      54             : 
      55           0 :   *bytesAvailable = mEndPos - mCurPos;
      56           0 :   return NS_OK;
      57             : }
      58             : 
      59             : NS_IMETHODIMP
      60           0 : nsTemporaryFileInputStream::Read(char* buffer, uint32_t count, uint32_t* bytesRead)
      61             : {
      62           0 :   return ReadSegments(NS_CopySegmentToBuffer, buffer, count, bytesRead);
      63             : }
      64             : 
      65             : NS_IMETHODIMP
      66           0 : nsTemporaryFileInputStream::ReadSegments(nsWriteSegmentFun writer,
      67             :                                          void *            closure,
      68             :                                          uint32_t          count,
      69             :                                          uint32_t *        result)
      70             : {
      71           0 :   NS_ASSERTION(result, "null ptr");
      72           0 :   NS_ASSERTION(mCurPos <= mEndPos, "bad stream state");
      73           0 :   *result = 0;
      74             : 
      75           0 :   if (mClosed) {
      76           0 :     return NS_BASE_STREAM_CLOSED;
      77             :   }
      78             : 
      79           0 :   mozilla::MutexAutoLock lock(mFileDescOwner->FileMutex());
      80           0 :   int64_t offset = PR_Seek64(mFileDescOwner->mFD, mCurPos, PR_SEEK_SET);
      81           0 :   if (offset == -1) {
      82           0 :     return NS_ErrorAccordingToNSPR();
      83             :   }
      84             : 
      85             :   // Limit requested count to the amount remaining in our section of the file.
      86           0 :   count = std::min(count, uint32_t(mEndPos - mCurPos));
      87             : 
      88             :   char buf[4096];
      89           0 :   while (*result < count) {
      90           0 :     uint32_t bufCount = std::min(count - *result, (uint32_t) sizeof(buf));
      91           0 :     int32_t bytesRead = PR_Read(mFileDescOwner->mFD, buf, bufCount);
      92           0 :     if (bytesRead == 0) {
      93           0 :       mClosed = true;
      94           0 :       return NS_OK;
      95             :     }
      96             : 
      97           0 :     if (bytesRead < 0) {
      98           0 :       return NS_ErrorAccordingToNSPR();
      99             :     }
     100             : 
     101           0 :     int32_t bytesWritten = 0;
     102           0 :     while (bytesWritten < bytesRead) {
     103           0 :       uint32_t writerCount = 0;
     104           0 :       nsresult rv = writer(this, closure, buf + bytesWritten, *result,
     105           0 :                            bytesRead - bytesWritten, &writerCount);
     106           0 :       if (NS_FAILED(rv) || writerCount == 0) {
     107             :         // nsIInputStream::ReadSegments' contract specifies that errors
     108             :         // from writer are not propagated to ReadSegments' caller.
     109             :         //
     110             :         // If writer fails, leaving bytes still in buf, that's okay: we
     111             :         // only update mCurPos to reflect successful writes, so the call
     112             :         // to PR_Seek64 at the top will restart us at the right spot.
     113           0 :         return NS_OK;
     114             :       }
     115           0 :       NS_ASSERTION(writerCount <= (uint32_t) (bytesRead - bytesWritten),
     116             :                    "writer should not write more than we asked it to write");
     117           0 :       bytesWritten += writerCount;
     118           0 :       *result += writerCount;
     119           0 :       mCurPos += writerCount;
     120             :     }
     121             :   }
     122             : 
     123           0 :   return NS_OK;
     124             : }
     125             : 
     126             : NS_IMETHODIMP
     127           0 : nsTemporaryFileInputStream::IsNonBlocking(bool * nonBlocking)
     128             : {
     129           0 :   *nonBlocking = false;
     130           0 :   return NS_OK;
     131             : }
     132             : 
     133             : NS_IMETHODIMP
     134           0 : nsTemporaryFileInputStream::Seek(int32_t aWhence, int64_t aOffset)
     135             : {
     136           0 :   if (mClosed) {
     137           0 :     return NS_BASE_STREAM_CLOSED;
     138             :   }
     139             : 
     140           0 :   switch (aWhence) {
     141             :     case nsISeekableStream::NS_SEEK_SET:
     142           0 :       aOffset += mStartPos;
     143           0 :       break;
     144             : 
     145             :     case nsISeekableStream::NS_SEEK_CUR:
     146           0 :       aOffset += mCurPos;
     147           0 :       break;
     148             : 
     149             :     case nsISeekableStream::NS_SEEK_END:
     150           0 :       aOffset += mEndPos;
     151           0 :       break;
     152             : 
     153             :     default:
     154           0 :       return NS_ERROR_FAILURE;
     155             :   }
     156             : 
     157           0 :   if (aOffset < (int64_t)mStartPos || aOffset > (int64_t)mEndPos) {
     158           0 :     return NS_ERROR_INVALID_ARG;
     159             :   }
     160             : 
     161           0 :   mCurPos = aOffset;
     162           0 :   return NS_OK;
     163             : }
     164             : 
     165             : NS_IMETHODIMP
     166           0 : nsTemporaryFileInputStream::Tell(int64_t* aPos)
     167             : {
     168           0 :   if (!aPos) {
     169           0 :     return NS_ERROR_FAILURE;
     170             :   }
     171             : 
     172           0 :   if (mClosed) {
     173           0 :     return NS_BASE_STREAM_CLOSED;
     174             :   }
     175             : 
     176           0 :   MOZ_ASSERT(mStartPos <= mCurPos, "StartPos should less equal than CurPos!");
     177           0 :   *aPos = mCurPos - mStartPos;
     178           0 :   return NS_OK;
     179             : }
     180             : 
     181             : NS_IMETHODIMP
     182           0 : nsTemporaryFileInputStream::SetEOF()
     183             : {
     184           0 :   if (mClosed) {
     185           0 :     return NS_BASE_STREAM_CLOSED;
     186             :   }
     187             : 
     188           0 :   return Close();
     189             : }
     190             : 
     191             : void
     192           0 : nsTemporaryFileInputStream::Serialize(InputStreamParams& aParams,
     193             :                                       FileDescriptorArray& aFileDescriptors)
     194             : {
     195           0 :   TemporaryFileInputStreamParams params;
     196             : 
     197           0 :   MutexAutoLock lock(mFileDescOwner->FileMutex());
     198           0 :   MOZ_ASSERT(mFileDescOwner->mFD);
     199           0 :   if (!mClosed) {
     200           0 :     FileHandleType fd = FileHandleType(PR_FileDesc2NativeHandle(mFileDescOwner->mFD));
     201           0 :     NS_ASSERTION(fd, "This should never be null!");
     202             : 
     203           0 :     DebugOnly<FileDescriptor*> dbgFD = aFileDescriptors.AppendElement(fd);
     204           0 :     NS_ASSERTION(dbgFD->IsValid(), "Sending an invalid file descriptor!");
     205             : 
     206           0 :     params.fileDescriptorIndex() = aFileDescriptors.Length() - 1;
     207             : 
     208           0 :     Close();
     209             :   } else {
     210             :     NS_WARNING("The stream is already closed. "
     211           0 :                "Sending an invalid file descriptor to the other process!");
     212             : 
     213           0 :     params.fileDescriptorIndex() = UINT32_MAX;
     214             :   }
     215           0 :   params.startPos() = mCurPos;
     216           0 :   params.endPos() = mEndPos;
     217           0 :   aParams = params;
     218           0 : }
     219             : 
     220             : bool
     221           0 : nsTemporaryFileInputStream::Deserialize(const InputStreamParams& aParams,
     222             :                                         const FileDescriptorArray& aFileDescriptors)
     223             : {
     224           0 :   const TemporaryFileInputStreamParams& params = aParams.get_TemporaryFileInputStreamParams();
     225             : 
     226           0 :   uint32_t fileDescriptorIndex = params.fileDescriptorIndex();
     227           0 :   FileDescriptor fd;
     228           0 :   if (fileDescriptorIndex < aFileDescriptors.Length()) {
     229           0 :     fd = aFileDescriptors[fileDescriptorIndex];
     230           0 :     NS_WARNING_ASSERTION(fd.IsValid(),
     231             :                          "Received an invalid file descriptor!");
     232             :   } else {
     233           0 :     NS_WARNING("Received a bad file descriptor index!");
     234             :   }
     235             : 
     236           0 :   if (fd.IsValid()) {
     237           0 :     auto rawFD = fd.ClonePlatformHandle();
     238           0 :     PRFileDesc* fileDesc = PR_ImportFile(PROsfd(rawFD.release()));
     239           0 :     if (!fileDesc) {
     240           0 :       NS_WARNING("Failed to import file handle!");
     241           0 :       return false;
     242             :     }
     243           0 :     mFileDescOwner = new FileDescOwner(fileDesc);
     244             :   } else {
     245           0 :     mClosed = true;
     246             :   }
     247             : 
     248           0 :   mStartPos = mCurPos = params.startPos();
     249           0 :   mEndPos = params.endPos();
     250           0 :   return true;
     251             : }
     252             : 
     253             : Maybe<uint64_t>
     254           0 : nsTemporaryFileInputStream::ExpectedSerializedLength()
     255             : {
     256           0 :   return Nothing();
     257             : }

Generated by: LCOV version 1.13