Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: Source/core/html/FormData.cpp

Issue 1338193002: Reduce allocation size of FormData::m_entries. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/html/FormData.h ('k') | Source/core/html/FormDataTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 class FormDataIterationSource final : public PairIterable<String, FormDataEntryV alue>::IterationSource { 46 class FormDataIterationSource final : public PairIterable<String, FormDataEntryV alue>::IterationSource {
47 public: 47 public:
48 FormDataIterationSource(FormData* formData) : m_formData(formData), m_curren t(0) { } 48 FormDataIterationSource(FormData* formData) : m_formData(formData), m_curren t(0) { }
49 49
50 bool next(ScriptState* scriptState, String& key, FormDataEntryValue& value, ExceptionState& exceptionState) override 50 bool next(ScriptState* scriptState, String& key, FormDataEntryValue& value, ExceptionState& exceptionState) override
51 { 51 {
52 if (m_current >= m_formData->size()) 52 if (m_current >= m_formData->size())
53 return false; 53 return false;
54 54
55 const FormData::Entry& entry = m_formData->entries()[m_current++]; 55 const FormData::Entry& entry = *m_formData->entries()[m_current++];
56 key = m_formData->decode(entry.key()); 56 key = m_formData->decode(entry.key());
57 if (entry.isString()) { 57 if (entry.isString()) {
58 value.setUSVString(m_formData->decode(entry.data())); 58 value.setUSVString(m_formData->decode(entry.data()));
59 } else { 59 } else {
60 ASSERT(entry.isFile()); 60 ASSERT(entry.isFile());
61 value.setFile(entry.file()); 61 value.setFile(entry.file());
62 } 62 }
63 return true; 63 return true;
64 } 64 }
65 65
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 UseCounter::count(context, UseCounter::FormDataAppendNull); 124 UseCounter::count(context, UseCounter::FormDataAppendNull);
125 } 125 }
126 appendBlob(name, blob, filename); 126 appendBlob(name, blob, filename);
127 } 127 }
128 128
129 void FormData::deleteEntry(const String& name) 129 void FormData::deleteEntry(const String& name)
130 { 130 {
131 const CString keyData = encodeAndNormalize(name); 131 const CString keyData = encodeAndNormalize(name);
132 size_t i = 0; 132 size_t i = 0;
133 while (i < m_entries.size()) { 133 while (i < m_entries.size()) {
134 if (m_entries[i].key() == keyData) { 134 if (m_entries[i]->key() == keyData) {
135 m_entries.remove(i); 135 m_entries.remove(i);
136 } else { 136 } else {
137 ++i; 137 ++i;
138 } 138 }
139 } 139 }
140 } 140 }
141 141
142 void FormData::get(const String& name, FormDataEntryValue& result) 142 void FormData::get(const String& name, FormDataEntryValue& result)
143 { 143 {
144 if (m_opaque) 144 if (m_opaque)
145 return; 145 return;
146 const CString encodedName = encodeAndNormalize(name); 146 const CString encodedName = encodeAndNormalize(name);
147 for (const Entry& entry : entries()) { 147 for (const auto& entry : entries()) {
148 if (entry.key() == encodedName) { 148 if (entry->key() == encodedName) {
149 if (entry.isString()) { 149 if (entry->isString()) {
150 result.setUSVString(decode(entry.data())); 150 result.setUSVString(decode(entry->data()));
151 } else { 151 } else {
152 ASSERT(entry.isFile()); 152 ASSERT(entry->isFile());
153 result.setFile(entry.file()); 153 result.setFile(entry->file());
154 } 154 }
155 return; 155 return;
156 } 156 }
157 } 157 }
158 } 158 }
159 159
160 HeapVector<FormDataEntryValue> FormData::getAll(const String& name) 160 HeapVector<FormDataEntryValue> FormData::getAll(const String& name)
161 { 161 {
162 HeapVector<FormDataEntryValue> results; 162 HeapVector<FormDataEntryValue> results;
163 163
164 if (m_opaque) 164 if (m_opaque)
165 return results; 165 return results;
166 166
167 const CString encodedName = encodeAndNormalize(name); 167 const CString encodedName = encodeAndNormalize(name);
168 for (const Entry& entry : entries()) { 168 for (const auto& entry : entries()) {
169 if (entry.key() != encodedName) 169 if (entry->key() != encodedName)
170 continue; 170 continue;
171 FormDataEntryValue value; 171 FormDataEntryValue value;
172 if (entry.isString()) { 172 if (entry->isString()) {
173 value.setUSVString(decode(entry.data())); 173 value.setUSVString(decode(entry->data()));
174 } else { 174 } else {
175 ASSERT(entry.isFile()); 175 ASSERT(entry->isFile());
176 value.setFile(entry.file()); 176 value.setFile(entry->file());
177 } 177 }
178 results.append(value); 178 results.append(value);
179 } 179 }
180 return results; 180 return results;
181 } 181 }
182 182
183 bool FormData::has(const String& name) 183 bool FormData::has(const String& name)
184 { 184 {
185 if (m_opaque) 185 if (m_opaque)
186 return false; 186 return false;
187 const CString keyData = encodeAndNormalize(name); 187 const CString keyData = encodeAndNormalize(name);
188 for (const Entry& entry : entries()) { 188 for (const auto& entry : entries()) {
189 if (entry.key() == keyData) 189 if (entry->key() == keyData)
190 return true; 190 return true;
191 } 191 }
192 return false; 192 return false;
193 } 193 }
194 194
195 void FormData::set(const String& name, const String& value) 195 void FormData::set(const String& name, const String& value)
196 { 196 {
197 setEntry(Entry(encodeAndNormalize(name), encodeAndNormalize(value))); 197 setEntry(new Entry(encodeAndNormalize(name), encodeAndNormalize(value)));
198 } 198 }
199 199
200 void FormData::set(const String& name, Blob* blob, const String& filename) 200 void FormData::set(const String& name, Blob* blob, const String& filename)
201 { 201 {
202 setEntry(Entry(encodeAndNormalize(name), blob, filename)); 202 setEntry(new Entry(encodeAndNormalize(name), blob, filename));
203 } 203 }
204 204
205 void FormData::setEntry(const Entry& entry) 205 void FormData::setEntry(const Entry* entry)
206 { 206 {
207 const CString keyData = entry.key(); 207 ASSERT(entry);
208 const CString keyData = entry->key();
208 bool found = false; 209 bool found = false;
209 size_t i = 0; 210 size_t i = 0;
210 while (i < m_entries.size()) { 211 while (i < m_entries.size()) {
211 if (m_entries[i].key() != keyData) { 212 if (m_entries[i]->key() != keyData) {
212 ++i; 213 ++i;
213 } else if (found) { 214 } else if (found) {
214 m_entries.remove(i); 215 m_entries.remove(i);
215 } else { 216 } else {
216 found = true; 217 found = true;
217 m_entries[i] = entry; 218 m_entries[i] = entry;
218 ++i; 219 ++i;
219 } 220 }
220 } 221 }
221 if (!found) 222 if (!found)
222 m_entries.append(entry); 223 m_entries.append(entry);
223 } 224 }
224 225
225 void FormData::appendData(const String& key, const String& value) 226 void FormData::appendData(const String& key, const String& value)
226 { 227 {
227 m_entries.append(Entry(encodeAndNormalize(key), encodeAndNormalize(value))); 228 m_entries.append(new Entry(encodeAndNormalize(key), encodeAndNormalize(value )));
228 } 229 }
229 230
230 void FormData::appendData(const String& key, int value) 231 void FormData::appendData(const String& key, int value)
231 { 232 {
232 m_entries.append(Entry(encodeAndNormalize(key), encodeAndNormalize(String::n umber(value)))); 233 appendData(key, String::number(value));
233 } 234 }
234 235
235 void FormData::appendBlob(const String& key, Blob* blob, const String& filename) 236 void FormData::appendBlob(const String& key, Blob* blob, const String& filename)
236 { 237 {
237 m_entries.append(Entry(encodeAndNormalize(key), blob, filename)); 238 m_entries.append(new Entry(encodeAndNormalize(key), blob, filename));
238 } 239 }
239 240
240 CString FormData::encodeAndNormalize(const String& string) const 241 CString FormData::encodeAndNormalize(const String& string) const
241 { 242 {
242 CString encodedString = m_encoding.encode(string, WTF::EntitiesForUnencodabl es); 243 CString encodedString = m_encoding.encode(string, WTF::EntitiesForUnencodabl es);
243 return normalizeLineEndingsToCRLF(encodedString); 244 return normalizeLineEndingsToCRLF(encodedString);
244 } 245 }
245 246
246 String FormData::decode(const CString& data) const 247 String FormData::decode(const CString& data) const
247 { 248 {
248 return encoding().decode(data.data(), data.length()); 249 return encoding().decode(data.data(), data.length());
249 } 250 }
250 251
251 PassRefPtr<EncodedFormData> FormData::encodeFormData(EncodedFormData::EncodingTy pe encodingType) 252 PassRefPtr<EncodedFormData> FormData::encodeFormData(EncodedFormData::EncodingTy pe encodingType)
252 { 253 {
253 RefPtr<EncodedFormData> formData = EncodedFormData::create(); 254 RefPtr<EncodedFormData> formData = EncodedFormData::create();
254 Vector<char> encodedData; 255 Vector<char> encodedData;
255 for (const Entry& entry : entries()) 256 for (const auto& entry : entries())
256 FormDataEncoder::addKeyValuePairAsFormData(encodedData, entry.key(), ent ry.data(), encodingType); 257 FormDataEncoder::addKeyValuePairAsFormData(encodedData, entry->key(), en try->data(), encodingType);
257 formData->appendData(encodedData.data(), encodedData.size()); 258 formData->appendData(encodedData.data(), encodedData.size());
258 return formData.release(); 259 return formData.release();
259 } 260 }
260 261
261 PassRefPtr<EncodedFormData> FormData::encodeMultiPartFormData() 262 PassRefPtr<EncodedFormData> FormData::encodeMultiPartFormData()
262 { 263 {
263 RefPtr<EncodedFormData> formData = EncodedFormData::create(); 264 RefPtr<EncodedFormData> formData = EncodedFormData::create();
264 formData->setBoundary(FormDataEncoder::generateUniqueBoundaryString()); 265 formData->setBoundary(FormDataEncoder::generateUniqueBoundaryString());
265 Vector<char> encodedData; 266 Vector<char> encodedData;
266 for (const Entry& entry : entries()) { 267 for (const auto& entry : entries()) {
267 Vector<char> header; 268 Vector<char> header;
268 FormDataEncoder::beginMultiPartHeader(header, formData->boundary().data( ), entry.key()); 269 FormDataEncoder::beginMultiPartHeader(header, formData->boundary().data( ), entry->key());
269 270
270 // If the current type is blob, then we also need to include the 271 // If the current type is blob, then we also need to include the
271 // filename. 272 // filename.
272 if (entry.blob()) { 273 if (entry->blob()) {
273 String name; 274 String name;
274 if (entry.blob()->isFile()) { 275 if (entry->blob()->isFile()) {
275 File* file = toFile(entry.blob()); 276 File* file = toFile(entry->blob());
276 // For file blob, use the filename (or relative path if it is 277 // For file blob, use the filename (or relative path if it is
277 // present) as the name. 278 // present) as the name.
278 name = file->webkitRelativePath().isEmpty() ? file->name() : fil e->webkitRelativePath(); 279 name = file->webkitRelativePath().isEmpty() ? file->name() : fil e->webkitRelativePath();
279 280
280 // If a filename is passed in FormData.append(), use it instead 281 // If a filename is passed in FormData.append(), use it instead
281 // of the file blob's name. 282 // of the file blob's name.
282 if (!entry.filename().isNull()) 283 if (!entry->filename().isNull())
283 name = entry.filename(); 284 name = entry->filename();
284 } else { 285 } else {
285 // For non-file blob, use the filename if it is passed in 286 // For non-file blob, use the filename if it is passed in
286 // FormData.append(). 287 // FormData.append().
287 if (!entry.filename().isNull()) 288 if (!entry->filename().isNull())
288 name = entry.filename(); 289 name = entry->filename();
289 else 290 else
290 name = "blob"; 291 name = "blob";
291 } 292 }
292 293
293 // We have to include the filename=".." part in the header, even if 294 // We have to include the filename=".." part in the header, even if
294 // the filename is empty. 295 // the filename is empty.
295 FormDataEncoder::addFilenameToMultiPartHeader(header, encoding(), na me); 296 FormDataEncoder::addFilenameToMultiPartHeader(header, encoding(), na me);
296 297
297 // Add the content type if available, or "application/octet-stream" 298 // Add the content type if available, or "application/octet-stream"
298 // otherwise (RFC 1867). 299 // otherwise (RFC 1867).
299 String contentType; 300 String contentType;
300 if (entry.blob()->type().isEmpty()) 301 if (entry->blob()->type().isEmpty())
301 contentType = "application/octet-stream"; 302 contentType = "application/octet-stream";
302 else 303 else
303 contentType = entry.blob()->type(); 304 contentType = entry->blob()->type();
304 FormDataEncoder::addContentTypeToMultiPartHeader(header, contentType .latin1()); 305 FormDataEncoder::addContentTypeToMultiPartHeader(header, contentType .latin1());
305 } 306 }
306 307
307 FormDataEncoder::finishMultiPartHeader(header); 308 FormDataEncoder::finishMultiPartHeader(header);
308 309
309 // Append body 310 // Append body
310 formData->appendData(header.data(), header.size()); 311 formData->appendData(header.data(), header.size());
311 if (entry.blob()) { 312 if (entry->blob()) {
312 if (entry.blob()->hasBackingFile()) { 313 if (entry->blob()->hasBackingFile()) {
313 File* file = toFile(entry.blob()); 314 File* file = toFile(entry->blob());
314 // Do not add the file if the path is empty. 315 // Do not add the file if the path is empty.
315 if (!file->path().isEmpty()) 316 if (!file->path().isEmpty())
316 formData->appendFile(file->path()); 317 formData->appendFile(file->path());
317 if (!file->fileSystemURL().isEmpty()) 318 if (!file->fileSystemURL().isEmpty())
318 formData->appendFileSystemURL(file->fileSystemURL()); 319 formData->appendFileSystemURL(file->fileSystemURL());
319 } else { 320 } else {
320 formData->appendBlob(entry.blob()->uuid(), entry.blob()->blobDat aHandle()); 321 formData->appendBlob(entry->blob()->uuid(), entry->blob()->blobD ataHandle());
321 } 322 }
322 } else { 323 } else {
323 formData->appendData(entry.data().data(), entry.data().length()); 324 formData->appendData(entry->data().data(), entry->data().length());
324 } 325 }
325 formData->appendData("\r\n", 2); 326 formData->appendData("\r\n", 2);
326 } 327 }
327 FormDataEncoder::addBoundaryToMultiPartHeader(encodedData, formData->boundar y().data(), true); 328 FormDataEncoder::addBoundaryToMultiPartHeader(encodedData, formData->boundar y().data(), true);
328 formData->appendData(encodedData.data(), encodedData.size()); 329 formData->appendData(encodedData.data(), encodedData.size());
329 return formData.release(); 330 return formData.release();
330 } 331 }
331 332
332 PairIterable<String, FormDataEntryValue>::IterationSource* FormData::startIterat ion(ScriptState*, ExceptionState&) 333 PairIterable<String, FormDataEntryValue>::IterationSource* FormData::startIterat ion(ScriptState*, ExceptionState&)
333 { 334 {
(...skipping 25 matching lines...) Expand all
359 return file->clone(filename()); 360 return file->clone(filename());
360 } 361 }
361 362
362 String filename = m_filename; 363 String filename = m_filename;
363 if (filename.isNull()) 364 if (filename.isNull())
364 filename = "blob"; 365 filename = "blob";
365 return File::create(filename, currentTimeMS(), blob()->blobDataHandle()); 366 return File::create(filename, currentTimeMS(), blob()->blobDataHandle());
366 } 367 }
367 368
368 } // namespace blink 369 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/html/FormData.h ('k') | Source/core/html/FormDataTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698