summaryrefslogtreecommitdiffstats
path: root/mobile/android/components/geckoview/GeckoViewInputStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/components/geckoview/GeckoViewInputStream.cpp')
-rw-r--r--mobile/android/components/geckoview/GeckoViewInputStream.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/mobile/android/components/geckoview/GeckoViewInputStream.cpp b/mobile/android/components/geckoview/GeckoViewInputStream.cpp
new file mode 100644
index 0000000000..187a0ce10c
--- /dev/null
+++ b/mobile/android/components/geckoview/GeckoViewInputStream.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cin: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GeckoViewInputStream.h"
+#include "nsStreamUtils.h"
+
+NS_IMPL_ISUPPORTS(GeckoViewInputStream, nsIInputStream);
+
+NS_IMETHODIMP
+GeckoViewInputStream::Close() {
+ mClosed = true;
+ mInstance->Close();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+GeckoViewInputStream::Available(uint64_t* aCount) {
+ if (mClosed) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ *aCount = static_cast<uint64_t>(mInstance->Available());
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+GeckoViewInputStream::StreamStatus() {
+ return mClosed ? NS_BASE_STREAM_CLOSED : NS_OK;
+}
+
+NS_IMETHODIMP
+GeckoViewInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aReadCount) {
+ return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aReadCount);
+}
+
+NS_IMETHODIMP
+GeckoViewInputStream::ReadSegments(nsWriteSegmentFun writer, void* aClosure,
+ uint32_t aCount, uint32_t* result) {
+ NS_ASSERTION(result, "null ptr");
+
+ if (mClosed) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
+ auto bufferAddress =
+ static_cast<const char*>(mInstance->MBuffer()->Address());
+ uint32_t segmentPos = static_cast<uint32_t>(mInstance->MPos());
+ int32_t dataLength = 0;
+ nsresult rv;
+
+ *result = 0;
+ while (aCount) {
+ rv = mInstance->Read(static_cast<int64_t>(aCount), &dataLength);
+ if (NS_FAILED(rv)) {
+ return NS_BASE_STREAM_OSERROR;
+ }
+
+ if (dataLength == -1) {
+ break;
+ }
+
+ uint32_t uDataLength = static_cast<uint32_t>(dataLength);
+ uint32_t written;
+ rv = writer(this, aClosure, bufferAddress + segmentPos, *result,
+ uDataLength, &written);
+
+ if (NS_FAILED(rv)) {
+ // InputStreams do not propagate errors to caller.
+ break;
+ }
+
+ NS_ASSERTION(written > 0, "Must have written something");
+
+ *result += written;
+ aCount -= written;
+
+ segmentPos = static_cast<uint32_t>(mInstance->ConsumedData(written));
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+GeckoViewInputStream::IsNonBlocking(bool* aNonBlocking) {
+ *aNonBlocking = true;
+ return NS_OK;
+}
+
+bool GeckoViewInputStream::isClosed() const { return mInstance->IsClosed(); }
+
+bool GeckoViewContentInputStream::isReadable(const nsAutoCString& aUri) {
+ return mozilla::java::ContentInputStream::IsReadable(
+ mozilla::jni::StringParam(aUri));
+}
+
+nsresult GeckoViewContentInputStream::getInstance(const nsAutoCString& aUri,
+ nsIInputStream** aInstance) {
+ RefPtr<GeckoViewContentInputStream> instance =
+ new GeckoViewContentInputStream(aUri);
+ if (instance->isClosed()) {
+ return NS_ERROR_FILE_NOT_FOUND;
+ }
+ *aInstance = instance.forget().take();
+
+ return NS_OK;
+}