tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FileSystemThreadSafeStreamOwner.cpp (3179B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "fs/FileSystemThreadSafeStreamOwner.h"
      8 
      9 #include "mozilla/CheckedInt.h"
     10 #include "mozilla/dom/FileSystemLog.h"
     11 #include "mozilla/dom/FileSystemWritableFileStream.h"
     12 #include "mozilla/dom/quota/QuotaCommon.h"
     13 #include "mozilla/dom/quota/ResultExtensions.h"
     14 #include "nsIOutputStream.h"
     15 #include "nsIRandomAccessStream.h"
     16 
     17 namespace mozilla::dom::fs {
     18 
     19 namespace {
     20 
     21 nsresult TruncFile(nsCOMPtr<nsIRandomAccessStream>& aStream, int64_t aEOF) {
     22  int64_t offset = 0;
     23  QM_TRY(MOZ_TO_RESULT(aStream->Tell(&offset)));
     24 
     25  QM_TRY(MOZ_TO_RESULT(aStream->Seek(nsISeekableStream::NS_SEEK_SET, aEOF)));
     26 
     27  QM_TRY(MOZ_TO_RESULT(aStream->SetEOF()));
     28 
     29  QM_TRY(MOZ_TO_RESULT(aStream->Seek(nsISeekableStream::NS_SEEK_END, 0)));
     30 
     31  // Restore original offset
     32  QM_TRY(MOZ_TO_RESULT(aStream->Seek(nsISeekableStream::NS_SEEK_SET, offset)));
     33 
     34  return NS_OK;
     35 }
     36 
     37 }  // namespace
     38 
     39 FileSystemThreadSafeStreamOwner::FileSystemThreadSafeStreamOwner(
     40    FileSystemWritableFileStream* aWritableFileStream,
     41    nsCOMPtr<nsIRandomAccessStream>&& aStream)
     42    :
     43 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     44      mWritableFileStream(aWritableFileStream),
     45 #endif
     46      mStream(std::forward<nsCOMPtr<nsIRandomAccessStream>>(aStream)),
     47      mClosed(false) {
     48  MOZ_ASSERT(mWritableFileStream);
     49 }
     50 
     51 nsresult FileSystemThreadSafeStreamOwner::Truncate(uint64_t aSize) {
     52  MOZ_DIAGNOSTIC_ASSERT(mWritableFileStream->IsCommandActive());
     53 
     54  if (mClosed) {  // Multiple closes can end up in a queue
     55    return NS_ERROR_DOM_INVALID_STATE_ERR;
     56  }
     57 
     58  int64_t where = 0;
     59  QM_TRY(MOZ_TO_RESULT(mStream->Tell(&where)));
     60 
     61  // Truncate filehandle (can extend with 0's)
     62  LOG(("%p: Truncate to %" PRIu64, this, aSize));
     63  QM_TRY(MOZ_TO_RESULT(TruncFile(mStream, aSize)));
     64 
     65  // Per non-normative text in the spec (2.5.3) we should adjust
     66  // the cursor position to be within the new file size
     67  if (static_cast<uint64_t>(where) > aSize) {
     68    QM_TRY(MOZ_TO_RESULT(mStream->Seek(nsISeekableStream::NS_SEEK_END, 0)));
     69  }
     70 
     71  return NS_OK;
     72 }
     73 
     74 nsresult FileSystemThreadSafeStreamOwner::Seek(uint64_t aPosition) {
     75  MOZ_DIAGNOSTIC_ASSERT(mWritableFileStream->IsCommandActive());
     76 
     77  if (mClosed) {  // Multiple closes can end up in a queue
     78    return NS_ERROR_DOM_INVALID_STATE_ERR;
     79  }
     80 
     81  const auto checkedPosition = CheckedInt<int64_t>(aPosition);
     82  if (!checkedPosition.isValid()) {
     83    return NS_ERROR_INVALID_ARG;
     84  }
     85 
     86  return mStream->Seek(nsISeekableStream::NS_SEEK_SET, checkedPosition.value());
     87 }
     88 
     89 void FileSystemThreadSafeStreamOwner::Close() {
     90  if (mClosed) {  // Multiple closes can end up in a queue
     91    return;
     92  }
     93 
     94  mClosed = true;
     95  mStream->OutputStream()->Close();
     96 }
     97 
     98 nsCOMPtr<nsIOutputStream> FileSystemThreadSafeStreamOwner::OutputStream() {
     99  MOZ_DIAGNOSTIC_ASSERT(mWritableFileStream->IsCommandActive());
    100 
    101  return mStream->OutputStream();
    102 }
    103 
    104 }  // namespace mozilla::dom::fs