Bug 1312412 - Introducing BlobImplString, r=smaug

This commit is contained in:
Andrea Marchesini 2016-10-25 07:53:54 +02:00
Родитель c11a158627
Коммит fa19ea68e4
7 изменённых файлов: 79 добавлений и 39 удалений

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

@ -188,6 +188,16 @@ Blob::Create(nsISupports* aParent, const nsAString& aContentType,
return blob.forget();
}
/* static */ already_AddRefed<Blob>
Blob::CreateStringBlob(nsISupports* aParent, const nsACString& aData,
const nsAString& aContentType)
{
RefPtr<Blob> blob = Blob::Create(aParent,
new BlobImplString(aData, aContentType));
MOZ_ASSERT(!blob->mImpl->IsFile());
return blob.forget();
}
/* static */ already_AddRefed<Blob>
Blob::CreateMemoryBlob(nsISupports* aParent, void* aMemoryBuffer,
uint64_t aLength, const nsAString& aContentType)
@ -1038,6 +1048,28 @@ EmptyBlobImpl::GetInternalStream(nsIInputStream** aStream,
}
}
////////////////////////////////////////////////////////////////////////////
// BlobImplString implementation
NS_IMPL_ISUPPORTS_INHERITED0(BlobImplString, BlobImpl)
already_AddRefed<BlobImpl>
BlobImplString::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType,
ErrorResult& aRv)
{
RefPtr<BlobImpl> impl =
new BlobImplString(Substring(mData, aStart, aLength),
aContentType);
return impl.forget();
}
void
BlobImplString::GetInternalStream(nsIInputStream** aStream, ErrorResult& aRv)
{
aRv = NS_NewCStringInputStream(aStream, mData);
}
////////////////////////////////////////////////////////////////////////////
// BlobImplMemory implementation

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

@ -71,6 +71,10 @@ public:
Create(nsISupports* aParent, const nsAString& aContentType, uint64_t aStart,
uint64_t aLength);
static already_AddRefed<Blob>
CreateStringBlob(nsISupports* aParent, const nsACString& aData,
const nsAString& aContentType);
// The returned Blob takes ownership of aMemoryBuffer. aMemoryBuffer will be
// freed by free so it must be allocated by malloc or something
// compatible with it.
@ -520,6 +524,28 @@ protected:
const uint64_t mSerialNumber;
};
class BlobImplString final : public BlobImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
BlobImplString(const nsACString& aData, const nsAString& aContentType)
: BlobImplBase(aContentType, aData.Length())
, mData(aData)
{}
virtual void GetInternalStream(nsIInputStream** aStream,
ErrorResult& aRv) override;
virtual already_AddRefed<BlobImpl>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType, ErrorResult& aRv) override;
private:
~BlobImplString() {}
nsCString mData;
};
/**
* This class may be used off the main thread, and in particular, its
* constructor and destructor may not run on the same thread. Be careful!

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

@ -1973,9 +1973,14 @@ WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData,
if (mBinaryType == dom::BinaryType::Blob) {
messageType = nsIWebSocketEventListener::TYPE_BLOB;
nsresult rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData,
&jsData);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<Blob> blob =
Blob::CreateStringBlob(GetOwner(), aData, EmptyString());
MOZ_ASSERT(blob);
if (!ToJSValue(cx, blob, &jsData)) {
return NS_ERROR_FAILURE;
}
} else if (mBinaryType == dom::BinaryType::Arraybuffer) {
messageType = nsIWebSocketEventListener::TYPE_ARRAYBUFFER;

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

@ -6248,32 +6248,6 @@ nsContentUtils::CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
return NS_OK;
}
// Initial implementation: only stores to RAM, not file
// TODO: bug 704447: large file support
nsresult
nsContentUtils::CreateBlobBuffer(JSContext* aCx,
nsISupports* aParent,
const nsACString& aData,
JS::MutableHandle<JS::Value> aBlob)
{
uint32_t blobLen = aData.Length();
void* blobData = malloc(blobLen);
RefPtr<Blob> blob;
if (blobData) {
memcpy(blobData, aData.BeginReading(), blobLen);
blob = mozilla::dom::Blob::CreateMemoryBlob(aParent, blobData, blobLen,
EmptyString());
} else {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!ToJSValue(aCx, blob, aBlob)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void
nsContentUtils::StripNullChars(const nsAString& aInStr, nsAString& aOutStr)
{

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

@ -1863,11 +1863,6 @@ public:
static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
JSObject** aResult);
static nsresult CreateBlobBuffer(JSContext* aCx,
nsISupports* aParent,
const nsACString& aData,
JS::MutableHandle<JS::Value> aBlob);
static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
/**

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

@ -395,8 +395,13 @@ nsDOMDataChannel::DoOnMessageAvailable(const nsACString& aData,
if (aBinary) {
if (mBinaryType == DC_BINARY_TYPE_BLOB) {
rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData, &jsData);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<Blob> blob =
Blob::CreateStringBlob(GetOwner(), aData, EmptyString());
MOZ_ASSERT(blob);
if (!ToJSValue(cx, blob, &jsData)) {
return NS_ERROR_FAILURE;
}
} else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
JS::Rooted<JSObject*> arrayBuf(cx);
rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address());

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

@ -504,9 +504,12 @@ PresentationConnection::DoReceiveMessage(const nsACString& aData, bool aIsBinary
nsresult rv;
if (aIsBinary) {
if (mBinaryType == PresentationConnectionBinaryType::Blob) {
rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData, &jsData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
RefPtr<Blob> blob =
Blob::CreateStringBlob(GetOwner(), aData, EmptyString());
MOZ_ASSERT(blob);
if (!ToJSValue(cx, blob, &jsData)) {
return NS_ERROR_FAILURE;
}
} else if (mBinaryType == PresentationConnectionBinaryType::Arraybuffer) {
JS::Rooted<JSObject*> arrayBuf(cx);