Bug 1551962. Add a way to create an input stream from a moved nsTArray<uint8_t>. r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D31296

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2019-05-15 18:28:00 +00:00
Родитель 6752f52807
Коммит 17561de5b9
2 изменённых файлов: 55 добавлений и 3 удалений

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsIClassInfoImpl.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/ReentrantMonitor.h"
#include "nsIIPCSerializableInputStream.h"
#include "XPCOMModule.h"
@ -54,6 +55,8 @@ class nsStringInputStream final : public nsIStringInputStream,
nsresult Init(nsCString&& aString);
nsresult Init(nsTArray<uint8_t>&& aArray);
private:
~nsStringInputStream() {}
@ -72,12 +75,16 @@ class nsStringInputStream final : public nsIStringInputStream,
nsDependentCSubstring mData;
uint32_t mOffset;
// If we were initialized from an nsTArray, we store its data here.
Maybe<nsTArray<uint8_t>> mArray;
mozilla::ReentrantMonitor mMon;
};
nsresult nsStringInputStream::Init(nsCString&& aString) {
ReentrantMonitorAutoEnter lock(mMon);
mArray.reset();
if (!mData.Assign(std::move(aString), fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -86,6 +93,24 @@ nsresult nsStringInputStream::Init(nsCString&& aString) {
return NS_OK;
}
nsresult nsStringInputStream::Init(nsTArray<uint8_t>&& aArray) {
ReentrantMonitorAutoEnter lock(mMon);
mArray.reset();
mArray.emplace(std::move(aArray));
mOffset = 0;
if (mArray->IsEmpty()) {
// Not sure it's safe to Rebind() with a null pointer. Pretty
// sure it's not, in fact.
mData.Truncate();
} else {
mData.Rebind(reinterpret_cast<const char*>(mArray->Elements()),
mArray->Length());
}
return NS_OK;
}
// This class needs to support threadsafe refcounting since people often
// allocate a string stream, and then read it from a background thread.
NS_IMPL_ADDREF(nsStringInputStream)
@ -132,6 +157,7 @@ NS_IMETHODIMP
nsStringInputStream::SetData(const nsACString& aData) {
ReentrantMonitorAutoEnter lock(mMon);
mArray.reset();
if (NS_WARN_IF(!mData.Assign(aData, fallible))) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -158,6 +184,7 @@ nsStringInputStream::SetData(const char* aData, int32_t aDataLen) {
return NS_ERROR_INVALID_ARG;
}
mArray.reset();
if (NS_WARN_IF(!mData.Assign(aData, aDataLen, fallible))) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -173,6 +200,7 @@ nsStringInputStream::AdoptData(char* aData, int32_t aDataLen) {
if (NS_WARN_IF(!aData)) {
return NS_ERROR_INVALID_ARG;
}
mArray.reset();
mData.Adopt(aData, aDataLen);
mOffset = 0;
return NS_OK;
@ -186,6 +214,7 @@ nsStringInputStream::ShareData(const char* aData, int32_t aDataLen) {
return NS_ERROR_INVALID_ARG;
}
mArray.reset();
if (aDataLen < 0) {
aDataLen = strlen(aData);
}
@ -486,6 +515,21 @@ nsresult NS_NewByteInputStream(nsIInputStream** aStreamResult,
return NS_OK;
}
nsresult NS_NewByteInputStream(nsIInputStream** aStreamResult,
nsTArray<uint8_t>&& aArray) {
MOZ_ASSERT(aStreamResult, "null out ptr");
RefPtr<nsStringInputStream> stream = new nsStringInputStream();
nsresult rv = stream->Init(std::move(aArray));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
stream.forget(aStreamResult);
return NS_OK;
}
nsresult NS_NewCStringInputStream(nsIInputStream** aStreamResult,
const nsACString& aStringToRead) {
MOZ_ASSERT(aStreamResult, "null out ptr");

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsIStringStream.h"
#include "nsString.h"
#include "nsMemory.h"
#include "nsTArray.h"
/**
* Implements:
@ -43,14 +44,21 @@
* If aAssignment is NS_ASSIGNMENT_ADOPT, then the resulting stream refers
* directly to the given buffer (aStringToRead) and will free aStringToRead
* once the stream is closed.
*
* If aLength is less than zero, then the length of aStringToRead will be
* determined by scanning the buffer for the first null byte.
*/
extern nsresult NS_NewByteInputStream(nsIInputStream** aStreamResult,
mozilla::Span<const char> aStringToRead,
nsAssignmentType aAssignment);
/**
* Factory method to get an nsIInputStream from an nsTArray representing a byte
* buffer. This will take ownership of the data and empty out the nsTArray.
*
* Result will implement nsIStringInputStream, nsITellableStream and
* nsISeekableStream.
*/
extern nsresult NS_NewByteInputStream(nsIInputStream** aStreamResult,
nsTArray<uint8_t>&& aArray);
/**
* Factory method to get an nsInputStream from an nsACString. Result will
* implement nsIStringInputStream, nsTellableStream and nsISeekableStream.