tor-browser

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

GeckoViewInputStream.cpp (3771B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cin: */
      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 "GeckoViewInputStream.h"
      8 
      9 #include "nsIURI.h"
     10 #include "nsStreamUtils.h"
     11 
     12 using namespace mozilla;
     13 
     14 NS_IMPL_ISUPPORTS(GeckoViewInputStream, nsIInputStream,
     15                  nsIAndroidContentInputStream);
     16 
     17 NS_IMETHODIMP
     18 GeckoViewInputStream::Init(nsIURI* aUri) {
     19  nsAutoCString scheme;
     20  aUri->GetScheme(scheme);
     21 
     22  if (!scheme.EqualsLiteral("content")) {
     23    return NS_ERROR_FILE_INVALID_PATH;
     24  }
     25 
     26  nsAutoCString spec;
     27  aUri->GetSpec(spec);
     28 
     29  if (!java::ContentInputStream::IsReadable(jni::StringParam(spec))) {
     30    return NS_ERROR_FILE_ACCESS_DENIED;
     31  }
     32 
     33  mInstance =
     34      java::ContentInputStream::GetInstance(jni::StringParam(spec), false);
     35 
     36  return NS_OK;
     37 }
     38 
     39 NS_IMETHODIMP
     40 GeckoViewInputStream::Close() {
     41  mClosed = true;
     42  mInstance->Close();
     43 
     44  return NS_OK;
     45 }
     46 
     47 NS_IMETHODIMP
     48 GeckoViewInputStream::Available(uint64_t* aCount) {
     49  if (mClosed) {
     50    return NS_BASE_STREAM_CLOSED;
     51  }
     52 
     53  if (!mInstance) {
     54    return NS_ERROR_NOT_INITIALIZED;
     55  }
     56 
     57  *aCount = static_cast<uint64_t>(mInstance->Available());
     58  return NS_OK;
     59 }
     60 
     61 NS_IMETHODIMP
     62 GeckoViewInputStream::StreamStatus() {
     63  return mClosed ? NS_BASE_STREAM_CLOSED : NS_OK;
     64 }
     65 
     66 NS_IMETHODIMP
     67 GeckoViewInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aReadCount) {
     68  return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aReadCount);
     69 }
     70 
     71 NS_IMETHODIMP
     72 GeckoViewInputStream::ReadSegments(nsWriteSegmentFun writer, void* aClosure,
     73                                   uint32_t aCount, uint32_t* result) {
     74  NS_ASSERTION(result, "null ptr");
     75 
     76  if (mClosed) {
     77    return NS_BASE_STREAM_CLOSED;
     78  }
     79 
     80  if (!mInstance) {
     81    return NS_ERROR_NOT_INITIALIZED;
     82  }
     83 
     84  auto bufferAddress =
     85      static_cast<const char*>(mInstance->MBuffer()->Address());
     86  uint32_t segmentPos = static_cast<uint32_t>(mInstance->MPos());
     87  int32_t dataLength = 0;
     88  nsresult rv;
     89 
     90  *result = 0;
     91  while (aCount) {
     92    rv = mInstance->Read(static_cast<int64_t>(aCount), &dataLength);
     93    if (NS_FAILED(rv)) {
     94      return NS_BASE_STREAM_OSERROR;
     95    }
     96 
     97    if (dataLength == -1) {
     98      break;
     99    }
    100 
    101    uint32_t uDataLength = static_cast<uint32_t>(dataLength);
    102    uint32_t written;
    103    rv = writer(this, aClosure, bufferAddress + segmentPos, *result,
    104                uDataLength, &written);
    105 
    106    if (NS_FAILED(rv)) {
    107      // InputStreams do not propagate errors to caller.
    108      break;
    109    }
    110 
    111    NS_ASSERTION(written > 0, "Must have written something");
    112 
    113    *result += written;
    114    aCount -= written;
    115 
    116    segmentPos = static_cast<uint32_t>(mInstance->ConsumedData(written));
    117  }
    118 
    119  return NS_OK;
    120 }
    121 
    122 NS_IMETHODIMP
    123 GeckoViewInputStream::IsNonBlocking(bool* aNonBlocking) {
    124  *aNonBlocking = true;
    125  return NS_OK;
    126 }
    127 
    128 bool GeckoViewInputStream::IsClosed() const {
    129  if (!mInstance) {
    130    return true;
    131  }
    132 
    133  return mInstance->IsClosed();
    134 }
    135 
    136 bool GeckoViewContentInputStream::isReadable(const nsAutoCString& aUri) {
    137  return mozilla::java::ContentInputStream::IsReadable(
    138      mozilla::jni::StringParam(aUri));
    139 }
    140 
    141 nsresult GeckoViewContentInputStream::GetInstance(const nsAutoCString& aUri,
    142                                                  Allow aAllow,
    143                                                  nsIInputStream** aInstance) {
    144  RefPtr<GeckoViewContentInputStream> instance =
    145      new GeckoViewContentInputStream(aUri, aAllow == Allow::PDFOnly);
    146  if (instance->IsClosed()) {
    147    return NS_ERROR_FILE_NOT_FOUND;
    148  }
    149  *aInstance = instance.forget().take();
    150 
    151  return NS_OK;
    152 }