content/base/src/nsDOMBlobBuilder.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:69f8036aedad
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef nsDOMBlobBuilder_h
7 #define nsDOMBlobBuilder_h
8
9 #include "nsDOMFile.h"
10
11 #include "mozilla/CheckedInt.h"
12 #include "mozilla/Attributes.h"
13 #include <algorithm>
14
15 #define NS_DOMMULTIPARTBLOB_CID { 0x47bf0b43, 0xf37e, 0x49ef, \
16 { 0x81, 0xa0, 0x18, 0xba, 0xc0, 0x57, 0xb5, 0xcc } }
17 #define NS_DOMMULTIPARTBLOB_CONTRACTID "@mozilla.org/dom/multipart-blob;1"
18
19 #define NS_DOMMULTIPARTFILE_CID { 0xc3361f77, 0x60d1, 0x4ea9, \
20 { 0x94, 0x96, 0xdf, 0x5d, 0x6f, 0xcd, 0xd7, 0x8f } }
21 #define NS_DOMMULTIPARTFILE_CONTRACTID "@mozilla.org/dom/multipart-file;1"
22
23 class nsDOMMultipartFile : public nsDOMFile,
24 public nsIJSNativeInitializer
25 {
26 public:
27 // Create as a file
28 nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
29 const nsAString& aName,
30 const nsAString& aContentType)
31 : nsDOMFile(aName, aContentType, UINT64_MAX),
32 mBlobs(aBlobs),
33 mIsFromNsiFile(false)
34 {
35 }
36
37 // Create as a blob
38 nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs,
39 const nsAString& aContentType)
40 : nsDOMFile(aContentType, UINT64_MAX),
41 mBlobs(aBlobs),
42 mIsFromNsiFile(false)
43 {
44 }
45
46 // Create as a file to be later initialized
47 nsDOMMultipartFile(const nsAString& aName)
48 : nsDOMFile(aName, EmptyString(), UINT64_MAX),
49 mIsFromNsiFile(false)
50 {
51 }
52
53 // Create as a blob to be later initialized
54 nsDOMMultipartFile()
55 : nsDOMFile(EmptyString(), UINT64_MAX),
56 mIsFromNsiFile(false)
57 {
58 }
59
60 NS_DECL_ISUPPORTS_INHERITED
61
62 // nsIJSNativeInitializer
63 NS_IMETHOD Initialize(nsISupports* aOwner,
64 JSContext* aCx,
65 JSObject* aObj,
66 const JS::CallArgs& aArgs) MOZ_OVERRIDE;
67
68 typedef nsIDOMBlob* (*UnwrapFuncPtr)(JSContext*, JSObject*);
69 nsresult InitBlob(JSContext* aCx,
70 uint32_t aArgc,
71 JS::Value* aArgv,
72 UnwrapFuncPtr aUnwrapFunc);
73 nsresult InitFile(JSContext* aCx,
74 uint32_t aArgc,
75 JS::Value* aArgv);
76 nsresult InitChromeFile(JSContext* aCx,
77 uint32_t aArgc,
78 JS::Value* aArgv);
79
80 already_AddRefed<nsIDOMBlob>
81 CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType) MOZ_OVERRIDE;
82
83 NS_IMETHOD GetSize(uint64_t*) MOZ_OVERRIDE;
84 NS_IMETHOD GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
85
86 static nsresult
87 NewFile(const nsAString& aName, nsISupports* *aNewObject);
88
89 // DOMClassInfo constructor (for Blob([b1, "foo"], { type: "image/png" }))
90 static nsresult
91 NewBlob(nsISupports* *aNewObject);
92
93 // DOMClassInfo constructor (for File([b1, "foo"], { type: "image/png",
94 // name: "foo.png" }))
95 inline static nsresult
96 NewFile(nsISupports* *aNewObject)
97 {
98 // Initialization will set the filename, so we can pass in an empty string
99 // for now.
100 return NewFile(EmptyString(), aNewObject);
101 }
102
103 virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
104 GetSubBlobs() const MOZ_OVERRIDE { return &mBlobs; }
105
106 NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
107
108 protected:
109 nsresult ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
110 bool aNativeEOL, UnwrapFuncPtr aUnwrapFunc);
111
112 nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
113 bool mIsFromNsiFile;
114 };
115
116 class BlobSet {
117 public:
118 BlobSet()
119 : mData(nullptr), mDataLen(0), mDataBufferLen(0)
120 {}
121
122 nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
123 nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx);
124 nsresult AppendBlob(nsIDOMBlob* aBlob);
125 nsresult AppendArrayBuffer(JSObject* aBuffer);
126 nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob);
127
128 nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; }
129
130 already_AddRefed<nsIDOMBlob>
131 GetBlobInternal(const nsACString& aContentType)
132 {
133 nsCOMPtr<nsIDOMBlob> blob =
134 new nsDOMMultipartFile(GetBlobs(), NS_ConvertASCIItoUTF16(aContentType));
135 return blob.forget();
136 }
137
138 protected:
139 bool ExpandBufferSize(uint64_t aSize)
140 {
141 using mozilla::CheckedUint32;
142
143 if (mDataBufferLen >= mDataLen + aSize) {
144 mDataLen += aSize;
145 return true;
146 }
147
148 // Start at 1 or we'll loop forever.
149 CheckedUint32 bufferLen =
150 std::max<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
151 while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
152 bufferLen *= 2;
153
154 if (!bufferLen.isValid())
155 return false;
156
157 void* data = moz_realloc(mData, bufferLen.value());
158 if (!data)
159 return false;
160
161 mData = data;
162 mDataBufferLen = bufferLen.value();
163 mDataLen += aSize;
164 return true;
165 }
166
167 void Flush() {
168 if (mData) {
169 // If we have some data, create a blob for it
170 // and put it on the stack
171
172 nsCOMPtr<nsIDOMBlob> blob =
173 new nsDOMMemoryFile(mData, mDataLen, EmptyString(), EmptyString());
174 mBlobs.AppendElement(blob);
175 mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer
176 mDataLen = 0;
177 mDataBufferLen = 0;
178 }
179 }
180
181 nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
182 void* mData;
183 uint64_t mDataLen;
184 uint64_t mDataBufferLen;
185 };
186
187 #endif

mercurial