1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/nsDOMBlobBuilder.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,187 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsDOMBlobBuilder_h 1.10 +#define nsDOMBlobBuilder_h 1.11 + 1.12 +#include "nsDOMFile.h" 1.13 + 1.14 +#include "mozilla/CheckedInt.h" 1.15 +#include "mozilla/Attributes.h" 1.16 +#include <algorithm> 1.17 + 1.18 +#define NS_DOMMULTIPARTBLOB_CID { 0x47bf0b43, 0xf37e, 0x49ef, \ 1.19 + { 0x81, 0xa0, 0x18, 0xba, 0xc0, 0x57, 0xb5, 0xcc } } 1.20 +#define NS_DOMMULTIPARTBLOB_CONTRACTID "@mozilla.org/dom/multipart-blob;1" 1.21 + 1.22 +#define NS_DOMMULTIPARTFILE_CID { 0xc3361f77, 0x60d1, 0x4ea9, \ 1.23 + { 0x94, 0x96, 0xdf, 0x5d, 0x6f, 0xcd, 0xd7, 0x8f } } 1.24 +#define NS_DOMMULTIPARTFILE_CONTRACTID "@mozilla.org/dom/multipart-file;1" 1.25 + 1.26 +class nsDOMMultipartFile : public nsDOMFile, 1.27 + public nsIJSNativeInitializer 1.28 +{ 1.29 +public: 1.30 + // Create as a file 1.31 + nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs, 1.32 + const nsAString& aName, 1.33 + const nsAString& aContentType) 1.34 + : nsDOMFile(aName, aContentType, UINT64_MAX), 1.35 + mBlobs(aBlobs), 1.36 + mIsFromNsiFile(false) 1.37 + { 1.38 + } 1.39 + 1.40 + // Create as a blob 1.41 + nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs, 1.42 + const nsAString& aContentType) 1.43 + : nsDOMFile(aContentType, UINT64_MAX), 1.44 + mBlobs(aBlobs), 1.45 + mIsFromNsiFile(false) 1.46 + { 1.47 + } 1.48 + 1.49 + // Create as a file to be later initialized 1.50 + nsDOMMultipartFile(const nsAString& aName) 1.51 + : nsDOMFile(aName, EmptyString(), UINT64_MAX), 1.52 + mIsFromNsiFile(false) 1.53 + { 1.54 + } 1.55 + 1.56 + // Create as a blob to be later initialized 1.57 + nsDOMMultipartFile() 1.58 + : nsDOMFile(EmptyString(), UINT64_MAX), 1.59 + mIsFromNsiFile(false) 1.60 + { 1.61 + } 1.62 + 1.63 + NS_DECL_ISUPPORTS_INHERITED 1.64 + 1.65 + // nsIJSNativeInitializer 1.66 + NS_IMETHOD Initialize(nsISupports* aOwner, 1.67 + JSContext* aCx, 1.68 + JSObject* aObj, 1.69 + const JS::CallArgs& aArgs) MOZ_OVERRIDE; 1.70 + 1.71 + typedef nsIDOMBlob* (*UnwrapFuncPtr)(JSContext*, JSObject*); 1.72 + nsresult InitBlob(JSContext* aCx, 1.73 + uint32_t aArgc, 1.74 + JS::Value* aArgv, 1.75 + UnwrapFuncPtr aUnwrapFunc); 1.76 + nsresult InitFile(JSContext* aCx, 1.77 + uint32_t aArgc, 1.78 + JS::Value* aArgv); 1.79 + nsresult InitChromeFile(JSContext* aCx, 1.80 + uint32_t aArgc, 1.81 + JS::Value* aArgv); 1.82 + 1.83 + already_AddRefed<nsIDOMBlob> 1.84 + CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType) MOZ_OVERRIDE; 1.85 + 1.86 + NS_IMETHOD GetSize(uint64_t*) MOZ_OVERRIDE; 1.87 + NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE; 1.88 + 1.89 + static nsresult 1.90 + NewFile(const nsAString& aName, nsISupports* *aNewObject); 1.91 + 1.92 + // DOMClassInfo constructor (for Blob([b1, "foo"], { type: "image/png" })) 1.93 + static nsresult 1.94 + NewBlob(nsISupports* *aNewObject); 1.95 + 1.96 + // DOMClassInfo constructor (for File([b1, "foo"], { type: "image/png", 1.97 + // name: "foo.png" })) 1.98 + inline static nsresult 1.99 + NewFile(nsISupports* *aNewObject) 1.100 + { 1.101 + // Initialization will set the filename, so we can pass in an empty string 1.102 + // for now. 1.103 + return NewFile(EmptyString(), aNewObject); 1.104 + } 1.105 + 1.106 + virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >* 1.107 + GetSubBlobs() const MOZ_OVERRIDE { return &mBlobs; } 1.108 + 1.109 + NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE; 1.110 + 1.111 +protected: 1.112 + nsresult ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue, 1.113 + bool aNativeEOL, UnwrapFuncPtr aUnwrapFunc); 1.114 + 1.115 + nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs; 1.116 + bool mIsFromNsiFile; 1.117 +}; 1.118 + 1.119 +class BlobSet { 1.120 +public: 1.121 + BlobSet() 1.122 + : mData(nullptr), mDataLen(0), mDataBufferLen(0) 1.123 + {} 1.124 + 1.125 + nsresult AppendVoidPtr(const void* aData, uint32_t aLength); 1.126 + nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx); 1.127 + nsresult AppendBlob(nsIDOMBlob* aBlob); 1.128 + nsresult AppendArrayBuffer(JSObject* aBuffer); 1.129 + nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob); 1.130 + 1.131 + nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; } 1.132 + 1.133 + already_AddRefed<nsIDOMBlob> 1.134 + GetBlobInternal(const nsACString& aContentType) 1.135 + { 1.136 + nsCOMPtr<nsIDOMBlob> blob = 1.137 + new nsDOMMultipartFile(GetBlobs(), NS_ConvertASCIItoUTF16(aContentType)); 1.138 + return blob.forget(); 1.139 + } 1.140 + 1.141 +protected: 1.142 + bool ExpandBufferSize(uint64_t aSize) 1.143 + { 1.144 + using mozilla::CheckedUint32; 1.145 + 1.146 + if (mDataBufferLen >= mDataLen + aSize) { 1.147 + mDataLen += aSize; 1.148 + return true; 1.149 + } 1.150 + 1.151 + // Start at 1 or we'll loop forever. 1.152 + CheckedUint32 bufferLen = 1.153 + std::max<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1); 1.154 + while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize) 1.155 + bufferLen *= 2; 1.156 + 1.157 + if (!bufferLen.isValid()) 1.158 + return false; 1.159 + 1.160 + void* data = moz_realloc(mData, bufferLen.value()); 1.161 + if (!data) 1.162 + return false; 1.163 + 1.164 + mData = data; 1.165 + mDataBufferLen = bufferLen.value(); 1.166 + mDataLen += aSize; 1.167 + return true; 1.168 + } 1.169 + 1.170 + void Flush() { 1.171 + if (mData) { 1.172 + // If we have some data, create a blob for it 1.173 + // and put it on the stack 1.174 + 1.175 + nsCOMPtr<nsIDOMBlob> blob = 1.176 + new nsDOMMemoryFile(mData, mDataLen, EmptyString(), EmptyString()); 1.177 + mBlobs.AppendElement(blob); 1.178 + mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer 1.179 + mDataLen = 0; 1.180 + mDataBufferLen = 0; 1.181 + } 1.182 + } 1.183 + 1.184 + nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs; 1.185 + void* mData; 1.186 + uint64_t mDataLen; 1.187 + uint64_t mDataBufferLen; 1.188 +}; 1.189 + 1.190 +#endif