Bug 1281748 - Cleanup BlobSet code, r=smaug

This commit is contained in:
Andrea Marchesini 2016-06-23 11:58:22 +02:00
Родитель 88efdabcf7
Коммит 6218847441
5 изменённых файлов: 158 добавлений и 122 удалений

138
dom/base/BlobSet.cpp Normal file
Просмотреть файл

@ -0,0 +1,138 @@
/* -*- 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 "mozilla/dom/BlobSet.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/dom/File.h"
#include "MultipartBlobImpl.h"
namespace mozilla {
namespace dom {
already_AddRefed<Blob>
BlobSet::GetBlobInternal(nsISupports* aParent,
const nsACString& aContentType,
ErrorResult& aRv)
{
RefPtr<BlobImpl> blobImpl =
MultipartBlobImpl::Create(GetBlobImpls(),
NS_ConvertASCIItoUTF16(aContentType),
aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
RefPtr<Blob> blob = Blob::Create(aParent, blobImpl);
return blob.forget();
}
nsresult
BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
{
NS_ENSURE_ARG_POINTER(aData);
if (!aLength) {
return NS_OK;
}
uint64_t offset = mDataLen;
if (!ExpandBufferSize(aLength)) {
return NS_ERROR_OUT_OF_MEMORY;
}
memcpy((char*)mData + offset, aData, aLength);
return NS_OK;
}
nsresult
BlobSet::AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx)
{
nsCString utf8Str = NS_ConvertUTF16toUTF8(aString);
if (nativeEOL) {
if (utf8Str.Contains('\r')) {
utf8Str.ReplaceSubstring("\r\n", "\n");
utf8Str.ReplaceSubstring("\r", "\n");
}
#ifdef XP_WIN
utf8Str.ReplaceSubstring("\n", "\r\n");
#endif
}
return AppendVoidPtr((void*)utf8Str.Data(),
utf8Str.Length());
}
nsresult
BlobSet::AppendBlobImpl(BlobImpl* aBlobImpl)
{
NS_ENSURE_ARG_POINTER(aBlobImpl);
Flush();
mBlobImpls.AppendElement(aBlobImpl);
return NS_OK;
}
nsresult
BlobSet::AppendBlobImpls(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls)
{
Flush();
mBlobImpls.AppendElements(aBlobImpls);
return NS_OK;
}
bool
BlobSet::ExpandBufferSize(uint64_t aSize)
{
if (mDataBufferLen >= mDataLen + aSize) {
mDataLen += aSize;
return true;
}
// Start at 1 or we'll loop forever.
CheckedUint32 bufferLen =
std::max<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize) {
bufferLen *= 2;
}
if (!bufferLen.isValid()) {
return false;
}
void* data = realloc(mData, bufferLen.value());
if (!data) {
return false;
}
mData = data;
mDataBufferLen = bufferLen.value();
mDataLen += aSize;
return true;
}
void
BlobSet::Flush()
{
if (mData) {
// If we have some data, create a blob for it
// and put it on the stack
RefPtr<BlobImpl> blobImpl =
new BlobImplMemory(mData, mDataLen, EmptyString());
mBlobImpls.AppendElement(blobImpl);
mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer
mDataLen = 0;
mDataBufferLen = 0;
return;
}
}
} // dom namespace
} // mozilla namespace

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

@ -7,16 +7,20 @@
#ifndef mozilla_dom_BlobSet_h
#define mozilla_dom_BlobSet_h
#include "mozilla/CheckedInt.h"
#include "mozilla/dom/File.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace dom {
class BlobSet {
class BlobImpl;
class BlobSet final
{
public:
BlobSet()
: mData(nullptr), mDataLen(0), mDataBufferLen(0)
: mData(nullptr)
, mDataLen(0)
, mDataBufferLen(0)
{}
~BlobSet()
@ -25,8 +29,12 @@ public:
}
nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
nsresult AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx);
nsresult AppendString(const nsAString& aString, bool nativeEOL,
JSContext* aCx);
nsresult AppendBlobImpl(BlobImpl* aBlobImpl);
nsresult AppendBlobImpls(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls);
nsTArray<RefPtr<BlobImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; }
@ -35,48 +43,10 @@ public:
const nsACString& aContentType,
ErrorResult& aRv);
protected:
bool ExpandBufferSize(uint64_t aSize)
{
using mozilla::CheckedUint32;
private:
bool ExpandBufferSize(uint64_t aSize);
if (mDataBufferLen >= mDataLen + aSize) {
mDataLen += aSize;
return true;
}
// Start at 1 or we'll loop forever.
CheckedUint32 bufferLen =
std::max<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
bufferLen *= 2;
if (!bufferLen.isValid())
return false;
void* data = realloc(mData, bufferLen.value());
if (!data)
return false;
mData = data;
mDataBufferLen = bufferLen.value();
mDataLen += aSize;
return true;
}
void Flush() {
if (mData) {
// If we have some data, create a blob for it
// and put it on the stack
RefPtr<BlobImpl> blobImpl =
new BlobImplMemory(mData, mDataLen, EmptyString());
mBlobImpls.AppendElement(blobImpl);
mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer
mDataLen = 0;
mDataBufferLen = 0;
}
}
void Flush();
nsTArray<RefPtr<BlobImpl>> mBlobImpls;
void* mData;

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

@ -35,7 +35,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/BlobSet.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/WorkerPrivate.h"
@ -1180,78 +1179,5 @@ BlobImplTemporaryBlob::GetInternalStream(nsIInputStream** aStream,
stream.forget(aStream);
}
////////////////////////////////////////////////////////////////////////////
// BlobSet implementation
already_AddRefed<Blob>
BlobSet::GetBlobInternal(nsISupports* aParent,
const nsACString& aContentType,
ErrorResult& aRv)
{
RefPtr<BlobImpl> blobImpl =
MultipartBlobImpl::Create(GetBlobImpls(),
NS_ConvertASCIItoUTF16(aContentType),
aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
RefPtr<Blob> blob = Blob::Create(aParent, blobImpl);
return blob.forget();
}
nsresult
BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
{
NS_ENSURE_ARG_POINTER(aData);
uint64_t offset = mDataLen;
if (!ExpandBufferSize(aLength))
return NS_ERROR_OUT_OF_MEMORY;
memcpy((char*)mData + offset, aData, aLength);
return NS_OK;
}
nsresult
BlobSet::AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx)
{
nsCString utf8Str = NS_ConvertUTF16toUTF8(aString);
if (nativeEOL) {
if (utf8Str.Contains('\r')) {
utf8Str.ReplaceSubstring("\r\n", "\n");
utf8Str.ReplaceSubstring("\r", "\n");
}
#ifdef XP_WIN
utf8Str.ReplaceSubstring("\n", "\r\n");
#endif
}
return AppendVoidPtr((void*)utf8Str.Data(),
utf8Str.Length());
}
nsresult
BlobSet::AppendBlobImpl(BlobImpl* aBlobImpl)
{
NS_ENSURE_ARG_POINTER(aBlobImpl);
Flush();
mBlobImpls.AppendElement(aBlobImpl);
return NS_OK;
}
nsresult
BlobSet::AppendBlobImpls(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls)
{
Flush();
mBlobImpls.AppendElements(aBlobImpls);
return NS_OK;
}
} // namespace dom
} // namespace mozilla

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

@ -212,6 +212,7 @@ UNIFIED_SOURCES += [
'AnonymousContent.cpp',
'Attr.cpp',
'BarProps.cpp',
'BlobSet.cpp',
'BodyUtil.cpp',
'ChildIterator.cpp',
'ChromeNodeList.cpp',

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

@ -4,6 +4,7 @@
* 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 "mozilla/DebugOnly.h"
#include "nsISupports.h"
#include "nsIDOMNodeList.h"
#include "nsIContentIterator.h"
@ -933,7 +934,7 @@ void
nsContentIterator::First()
{
if (mFirst) {
DebugOnly<nsresult> rv = PositionAt(mFirst);
mozilla::DebugOnly<nsresult> rv = PositionAt(mFirst);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to position iterator!");
}
@ -947,7 +948,7 @@ nsContentIterator::Last()
NS_ASSERTION(mLast, "No last node!");
if (mLast) {
DebugOnly<nsresult> rv = PositionAt(mLast);
mozilla::DebugOnly<nsresult> rv = PositionAt(mLast);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to position iterator!");
}