summaryrefslogtreecommitdiffstats
path: root/xpcom/io/nsScriptableInputStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/io/nsScriptableInputStream.cpp')
-rw-r--r--xpcom/io/nsScriptableInputStream.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/xpcom/io/nsScriptableInputStream.cpp b/xpcom/io/nsScriptableInputStream.cpp
new file mode 100644
index 0000000000..5f8b139c6f
--- /dev/null
+++ b/xpcom/io/nsScriptableInputStream.cpp
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "nsScriptableInputStream.h"
+#include "nsString.h"
+
+NS_IMPL_ISUPPORTS(nsScriptableInputStream, nsIScriptableInputStream)
+
+// nsIScriptableInputStream methods
+NS_IMETHODIMP
+nsScriptableInputStream::Close() {
+ if (!mInputStream) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return mInputStream->Close();
+}
+
+NS_IMETHODIMP
+nsScriptableInputStream::Init(nsIInputStream* aInputStream) {
+ if (!aInputStream) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ mInputStream = aInputStream;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptableInputStream::Available(uint64_t* aResult) {
+ if (!mInputStream) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ return mInputStream->Available(aResult);
+}
+
+NS_IMETHODIMP
+nsScriptableInputStream::Read(uint32_t aCount, char** aResult) {
+ nsresult rv = NS_OK;
+ uint64_t count64 = 0;
+ char* buffer = nullptr;
+
+ if (!mInputStream) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ rv = mInputStream->Available(&count64);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // bug716556 - Ensure count+1 doesn't overflow
+ uint32_t count =
+ XPCOM_MIN((uint32_t)XPCOM_MIN<uint64_t>(count64, aCount), UINT32_MAX - 1);
+ buffer = (char*)malloc(count + 1); // make room for '\0'
+ if (!buffer) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ rv = ReadHelper(buffer, count);
+ if (NS_FAILED(rv)) {
+ free(buffer);
+ return rv;
+ }
+
+ buffer[count] = '\0';
+ *aResult = buffer;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsScriptableInputStream::ReadBytes(uint32_t aCount, nsACString& aResult) {
+ if (!mInputStream) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ if (!aResult.SetLength(aCount, mozilla::fallible)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ MOZ_ASSERT(aResult.Length() == aCount);
+ char* ptr = aResult.BeginWriting();
+ nsresult rv = ReadHelper(ptr, aCount);
+ if (NS_FAILED(rv)) {
+ aResult.Truncate();
+ }
+ return rv;
+}
+
+nsresult nsScriptableInputStream::ReadHelper(char* aBuffer, uint32_t aCount) {
+ uint32_t totalBytesRead = 0;
+ while (1) {
+ uint32_t bytesRead;
+ nsresult rv = mInputStream->Read(aBuffer + totalBytesRead,
+ aCount - totalBytesRead, &bytesRead);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ totalBytesRead += bytesRead;
+ if (totalBytesRead == aCount) {
+ break;
+ }
+
+ // If we have read zero bytes, we have hit EOF.
+ if (bytesRead == 0) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+ return NS_OK;
+}
+
+nsresult nsScriptableInputStream::Create(REFNSIID aIID, void** aResult) {
+ RefPtr<nsScriptableInputStream> sis = new nsScriptableInputStream();
+ return sis->QueryInterface(aIID, aResult);
+}