diff --git a/content/base/public/BlobSet.h b/content/base/public/BlobSet.h new file mode 100644 index 000000000000..198e80850b43 --- /dev/null +++ b/content/base/public/BlobSet.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef mozilla_dom_BlobSet_h +#define mozilla_dom_BlobSet_h + +#include "mozilla/CheckedInt.h" +#include "mozilla/dom/File.h" + +namespace mozilla { +namespace dom { + +class BlobSet { +public: + BlobSet() + : mData(nullptr), mDataLen(0), mDataBufferLen(0) + {} + + ~BlobSet() + { + moz_free(mData); + } + + nsresult AppendVoidPtr(const void* aData, uint32_t aLength); + nsresult AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx); + nsresult AppendBlobImpl(FileImpl* aBlobImpl); + nsresult AppendBlobImpls(const nsTArray>& aBlobImpls); + + nsTArray>& GetBlobImpls() { Flush(); return mBlobImpls; } + + already_AddRefed GetBlobInternal(nsISupports* aParent, + const nsACString& aContentType); + +protected: + bool ExpandBufferSize(uint64_t aSize) + { + using mozilla::CheckedUint32; + + if (mDataBufferLen >= mDataLen + aSize) { + mDataLen += aSize; + return true; + } + + // Start at 1 or we'll loop forever. + CheckedUint32 bufferLen = + std::max(static_cast(mDataBufferLen), 1); + while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize) + bufferLen *= 2; + + if (!bufferLen.isValid()) + return false; + + void* data = moz_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 + + nsRefPtr blobImpl = + new FileImplMemory(mData, mDataLen, EmptyString()); + mBlobImpls.AppendElement(blobImpl); + mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer + mDataLen = 0; + mDataBufferLen = 0; + } + } + + nsTArray> mBlobImpls; + void* mData; + uint64_t mDataLen; + uint64_t mDataBufferLen; +}; + +} // dom namespace +} // mozilla namespace + +#endif // mozilla_dom_BlobSet_h diff --git a/content/base/public/File.h b/content/base/public/File.h index 44e991d09b4d..d7a1d88674dd 100644 --- a/content/base/public/File.h +++ b/content/base/public/File.h @@ -58,9 +58,6 @@ struct BlobPropertyBag; struct FilePropertyBag; class FileImpl; -/* FOLLOWUP TODO: -1. remove nsDOMBlobBuilder.h -*/ class File MOZ_FINAL : public nsIDOMFile , public nsIXHRSendable , public nsIMutable diff --git a/content/base/public/moz.build b/content/base/public/moz.build index 49a74d15b0a7..c0dad7074ca0 100644 --- a/content/base/public/moz.build +++ b/content/base/public/moz.build @@ -66,6 +66,7 @@ EXPORTS += [ ] EXPORTS.mozilla.dom += [ + 'BlobSet.h', 'DirectionalityUtils.h', 'Element.h', 'ElementInlines.h', diff --git a/content/base/src/File.cpp b/content/base/src/File.cpp index c6372b1ed974..6c737cbd60e4 100644 --- a/content/base/src/File.cpp +++ b/content/base/src/File.cpp @@ -6,10 +6,10 @@ #include "mozilla/dom/File.h" +#include "MultipartFileImpl.h" #include "nsCExternalHandlerService.h" #include "nsContentCID.h" #include "nsContentUtils.h" -#include "nsDOMBlobBuilder.h" #include "nsError.h" #include "nsICharsetDetector.h" #include "nsIConverterInputStream.h" @@ -35,6 +35,7 @@ #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" @@ -1237,5 +1238,70 @@ FileList::Item(uint32_t aIndex, nsIDOMFile **aFile) return NS_OK; } +//////////////////////////////////////////////////////////////////////////// +// BlobSet implementation + +already_AddRefed +BlobSet::GetBlobInternal(nsISupports* aParent, const nsACString& aContentType) +{ + nsRefPtr blob = new File(aParent, + new MultipartFileImpl(GetBlobImpls(), + NS_ConvertASCIItoUTF16(aContentType))); + 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.FindChar('\r') != kNotFound) { + 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(FileImpl* aBlobImpl) +{ + NS_ENSURE_ARG_POINTER(aBlobImpl); + + Flush(); + mBlobImpls.AppendElement(aBlobImpl); + + return NS_OK; +} + +nsresult +BlobSet::AppendBlobImpls(const nsTArray>& aBlobImpls) +{ + Flush(); + mBlobImpls.AppendElements(aBlobImpls); + + return NS_OK; +} + } // dom namespace } // mozilla namespace diff --git a/content/base/src/nsDOMBlobBuilder.cpp b/content/base/src/MultipartFileImpl.cpp similarity index 89% rename from content/base/src/nsDOMBlobBuilder.cpp rename to content/base/src/MultipartFileImpl.cpp index 18f4d2ba09cb..4de8f88d9011 100644 --- a/content/base/src/nsDOMBlobBuilder.cpp +++ b/content/base/src/MultipartFileImpl.cpp @@ -3,8 +3,9 @@ * 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 "nsDOMBlobBuilder.h" +#include "MultipartFileImpl.h" #include "jsfriendapi.h" +#include "mozilla/dom/BlobSet.h" #include "mozilla/dom/FileBinding.h" #include "nsAutoPtr.h" #include "nsDOMClassInfoID.h" @@ -350,56 +351,3 @@ MultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow, InitializeChromeFile(aWindow, file, aBag, false, aRv); } - -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 aNativeEOL, JSContext* aCx) -{ - NS_ConvertUTF16toUTF8 utf8Str(aString); - - if (aNativeEOL) { - if (utf8Str.FindChar('\r') != kNotFound) { - 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(FileImpl* aBlobImpl) -{ - NS_ENSURE_ARG_POINTER(aBlobImpl); - - Flush(); - mBlobImpls.AppendElement(aBlobImpl); - - return NS_OK; -} - -nsresult -BlobSet::AppendBlobImpls(const nsTArray>& aBlobImpls) -{ - Flush(); - mBlobImpls.AppendElements(aBlobImpls); - - return NS_OK; -} diff --git a/content/base/src/nsDOMBlobBuilder.h b/content/base/src/MultipartFileImpl.h similarity index 62% rename from content/base/src/nsDOMBlobBuilder.h rename to content/base/src/MultipartFileImpl.h index 9e238eb86131..7173f51766bf 100644 --- a/content/base/src/nsDOMBlobBuilder.h +++ b/content/base/src/MultipartFileImpl.h @@ -3,8 +3,8 @@ * 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/. */ -#ifndef nsDOMBlobBuilder_h -#define nsDOMBlobBuilder_h +#ifndef mozilla_dom_MultipartFileImpl_h +#define mozilla_dom_MultipartFileImpl_h #include "mozilla/Attributes.h" #include "mozilla/CheckedInt.h" @@ -120,79 +120,4 @@ protected: bool mIsFromNsIFile; }; -class BlobSet { -public: - BlobSet() - : mData(nullptr), mDataLen(0), mDataBufferLen(0) - {} - - ~BlobSet() - { - moz_free(mData); - } - - nsresult AppendVoidPtr(const void* aData, uint32_t aLength); - nsresult AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx); - nsresult AppendBlobImpl(FileImpl* aBlobImpl); - nsresult AppendBlobImpls(const nsTArray>& aBlobImpls); - - nsTArray>& GetBlobImpls() { Flush(); return mBlobImpls; } - - already_AddRefed - GetBlobInternal(nsISupports* aParent, const nsACString& aContentType) - { - nsRefPtr blob = new File(aParent, - new MultipartFileImpl(GetBlobImpls(), NS_ConvertASCIItoUTF16(aContentType))); - return blob.forget(); - } - -protected: - bool ExpandBufferSize(uint64_t aSize) - { - using mozilla::CheckedUint32; - - if (mDataBufferLen >= mDataLen + aSize) { - mDataLen += aSize; - return true; - } - - // Start at 1 or we'll loop forever. - CheckedUint32 bufferLen = - std::max(static_cast(mDataBufferLen), 1); - while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize) - bufferLen *= 2; - - if (!bufferLen.isValid()) - return false; - - void* data = moz_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 - - nsRefPtr blobImpl = - new FileImplMemory(mData, mDataLen, EmptyString()); - mBlobImpls.AppendElement(blobImpl); - mData = nullptr; // The FileImplMemory takes ownership of the buffer - mDataLen = 0; - mDataBufferLen = 0; - } - } - - nsTArray> mBlobImpls; - void* mData; - uint64_t mDataLen; - uint64_t mDataBufferLen; -}; - -#endif +#endif // mozilla_dom_MultipartFileImpl_h diff --git a/content/base/src/moz.build b/content/base/src/moz.build index c9ac5f42647b..358794428dac 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -104,6 +104,7 @@ UNIFIED_SOURCES += [ 'FragmentOrElement.cpp', 'ImportManager.cpp', 'Link.cpp', + 'MultipartFileImpl.cpp', 'NodeIterator.cpp', 'nsAtomListUtils.cpp', 'nsAttrAndChildArray.cpp', @@ -125,7 +126,6 @@ UNIFIED_SOURCES += [ 'nsDataDocumentContentPolicy.cpp', 'nsDocumentEncoder.cpp', 'nsDOMAttributeMap.cpp', - 'nsDOMBlobBuilder.cpp', 'nsDOMCaretPosition.cpp', 'nsDOMFileReader.cpp', 'nsDOMMutationObserver.cpp', diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 59b48e51cc43..108d8fa75b60 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -10,13 +10,13 @@ #include #endif #include "mozilla/ArrayUtils.h" +#include "mozilla/dom/BlobSet.h" #include "mozilla/dom/File.h" #include "mozilla/dom/XMLHttpRequestUploadBinding.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventListenerManager.h" #include "mozilla/LoadInfo.h" #include "mozilla/MemoryReporting.h" -#include "nsDOMBlobBuilder.h" #include "nsIDOMDocument.h" #include "mozilla/dom/ProgressEvent.h" #include "nsIJARChannel.h" diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h index 36c6c8df9d11..f92747a70c6e 100644 --- a/content/base/src/nsXMLHttpRequest.h +++ b/content/base/src/nsXMLHttpRequest.h @@ -41,7 +41,6 @@ #endif class AsyncVerifyRedirectCallbackForwarder; -class BlobSet; class nsFormData; class nsIJARChannel; class nsILoadGroup; @@ -51,6 +50,7 @@ class nsIJSID; namespace mozilla { namespace dom { +class BlobSet; class File; } @@ -676,7 +676,7 @@ protected: nsRefPtr mDOMFile; // We stream data to mBlobSet when response type is "blob" or "moz-blob" // and mDOMFile is null. - nsAutoPtr mBlobSet; + nsAutoPtr mBlobSet; nsString mOverrideMimeType; diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 473631e36862..c3fe0c58dd49 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -35,7 +35,6 @@ #include "nsIXPConnect.h" #include "xptcall.h" #include "nsTArray.h" -#include "nsDOMBlobBuilder.h" // General helper includes #include "nsGlobalWindow.h" diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 22cdecc27c17..eecfba00a59b 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -74,7 +74,6 @@ #include "mozilla/dom/PermissionMessageUtils.h" #include "mozilla/dom/quota/PersistenceType.h" #include "mozilla/dom/quota/QuotaManager.h" -#include "nsDOMBlobBuilder.h" #include "nsPrintfCString.h" #include "nsViewportInfo.h" #include "nsIFormControl.h" diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index fac8f1b8457b..f51ebee2d687 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -36,7 +36,6 @@ #include "nsIDirectoryEnumerator.h" #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h" -#include "nsDOMBlobBuilder.h" #include "nsNetUtil.h" #include "nsCycleCollectionParticipant.h" #include "nsIPrincipal.h" diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index bb058b429cba..31f87c2f1097 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -34,7 +34,6 @@ #include "nsIFileURL.h" #include "nsIJARURI.h" #include "nsNetUtil.h" -#include "nsDOMBlobBuilder.h" #include "jsprf.h" #include "nsJSPrincipals.h" #include "nsJSUtils.h" diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 39572d36fc09..b5752093f264 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -67,7 +67,6 @@ #include "nsContentCreatorFunctions.h" // DOM includes -#include "nsDOMBlobBuilder.h" #include "nsDOMFileReader.h" #include "nsFormData.h"