1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla File API.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Kyle Huey <me@kylehuey.com>
19 : * Portions created by the Initial Developer are Copyright (C) 2011
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsDOMBlobBuilder_h
39 : #define nsDOMBlobBuilder_h
40 :
41 : #include "nsDOMFile.h"
42 : #include "CheckedInt.h"
43 :
44 : #include "mozilla/StandardInteger.h"
45 :
46 : using namespace mozilla;
47 :
48 : class nsDOMMultipartFile : public nsDOMFileBase,
49 : public nsIJSNativeInitializer
50 0 : {
51 : public:
52 : // Create as a file
53 0 : nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
54 : const nsAString& aName,
55 : const nsAString& aContentType)
56 : : nsDOMFileBase(aName, aContentType, UINT64_MAX),
57 0 : mBlobs(aBlobs)
58 : {
59 0 : }
60 :
61 : // Create as a blob
62 0 : nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
63 : const nsAString& aContentType)
64 : : nsDOMFileBase(aContentType, UINT64_MAX),
65 0 : mBlobs(aBlobs)
66 : {
67 0 : }
68 :
69 : // Create as a blob to be later initialized
70 0 : nsDOMMultipartFile()
71 0 : : nsDOMFileBase(EmptyString(), UINT64_MAX)
72 : {
73 0 : }
74 :
75 : NS_DECL_ISUPPORTS_INHERITED
76 :
77 : // nsIJSNativeInitializer
78 : NS_IMETHOD Initialize(nsISupports* aOwner,
79 : JSContext* aCx,
80 : JSObject* aObj,
81 : PRUint32 aArgc,
82 : jsval* aArgv);
83 :
84 : already_AddRefed<nsIDOMBlob>
85 : CreateSlice(PRUint64 aStart, PRUint64 aLength, const nsAString& aContentType);
86 :
87 : NS_IMETHOD GetSize(PRUint64*);
88 : NS_IMETHOD GetInternalStream(nsIInputStream**);
89 :
90 : // DOMClassInfo constructor (for Blob([b1, "foo"], { type: "image/png" }))
91 : static nsresult
92 : NewBlob(nsISupports* *aNewObject);
93 :
94 : virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
95 0 : GetSubBlobs() const { return &mBlobs; }
96 :
97 : protected:
98 : nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
99 : };
100 :
101 0 : class BlobSet {
102 : public:
103 0 : BlobSet()
104 0 : : mData(nsnull), mDataLen(0), mDataBufferLen(0)
105 0 : {}
106 :
107 : nsresult AppendVoidPtr(const void* aData, PRUint32 aLength);
108 : nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx);
109 : nsresult AppendBlob(nsIDOMBlob* aBlob);
110 : nsresult AppendArrayBuffer(JSObject* aBuffer);
111 : nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob);
112 :
113 0 : nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; }
114 :
115 : protected:
116 0 : bool ExpandBufferSize(PRUint64 aSize)
117 : {
118 0 : if (mDataBufferLen >= mDataLen + aSize) {
119 0 : mDataLen += aSize;
120 0 : return true;
121 : }
122 :
123 : // Start at 1 or we'll loop forever.
124 0 : CheckedUint32 bufferLen = NS_MAX<PRUint32>(mDataBufferLen, 1);
125 0 : while (bufferLen.valid() && bufferLen.value() < mDataLen + aSize)
126 0 : bufferLen *= 2;
127 :
128 0 : if (!bufferLen.valid())
129 0 : return false;
130 :
131 : // PR_ memory functions are still fallible
132 0 : void* data = PR_Realloc(mData, bufferLen.value());
133 0 : if (!data)
134 0 : return false;
135 :
136 0 : mData = data;
137 0 : mDataBufferLen = bufferLen.value();
138 0 : mDataLen += aSize;
139 0 : return true;
140 : }
141 :
142 0 : void Flush() {
143 0 : if (mData) {
144 : // If we have some data, create a blob for it
145 : // and put it on the stack
146 :
147 : nsCOMPtr<nsIDOMBlob> blob =
148 0 : new nsDOMMemoryFile(mData, mDataLen, EmptyString(), EmptyString());
149 0 : mBlobs.AppendElement(blob);
150 0 : mData = nsnull; // The nsDOMMemoryFile takes ownership of the buffer
151 0 : mDataLen = 0;
152 0 : mDataBufferLen = 0;
153 : }
154 0 : }
155 :
156 : nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
157 : void* mData;
158 : PRUint64 mDataLen;
159 : PRUint64 mDataBufferLen;
160 : };
161 :
162 : class nsDOMBlobBuilder : public nsIDOMMozBlobBuilder
163 0 : {
164 : public:
165 0 : nsDOMBlobBuilder()
166 0 : : mBlobSet()
167 0 : {}
168 :
169 : NS_DECL_ISUPPORTS
170 : NS_DECL_NSIDOMMOZBLOBBUILDER
171 :
172 0 : nsresult AppendVoidPtr(const void* aData, PRUint32 aLength)
173 0 : { return mBlobSet.AppendVoidPtr(aData, aLength); }
174 :
175 : nsresult GetBlobInternal(const nsAString& aContentType,
176 : bool aClearBuffer, nsIDOMBlob** aBlob);
177 : protected:
178 : BlobSet mBlobSet;
179 : };
180 :
181 : #endif
|