OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Library General Public License | 14 * You should have received a copy of the GNU Library General Public License |
15 * along with this library; see the file COPYING.LIB. If not, write to | 15 * along with this library; see the file COPYING.LIB. If not, write to |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
18 * | 18 * |
19 */ | 19 */ |
20 | 20 |
21 #include "config.h" | 21 #include "config.h" |
22 #include "core/html/FormDataList.h" | 22 #include "core/html/FormDataList.h" |
23 | 23 |
24 #include "core/fileapi/File.h" | 24 #include "core/fileapi/File.h" |
25 #include "platform/network/FormDataBuilder.h" | 25 #include "platform/network/FormDataBuilder.h" |
26 #include "platform/text/LineEnding.h" | 26 #include "platform/text/LineEnding.h" |
| 27 #include "wtf/CurrentTime.h" |
27 | 28 |
28 namespace blink { | 29 namespace blink { |
29 | 30 |
30 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(FormDataList); | 31 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(FormDataList); |
31 | 32 |
32 FormDataList::FormDataList(const WTF::TextEncoding& c) | 33 FormDataList::FormDataList(const WTF::TextEncoding& c) |
33 : m_encoding(c) | 34 : m_encoding(c) |
34 { | 35 { |
35 } | 36 } |
36 | 37 |
37 void FormDataList::appendString(const String& string) | 38 void FormDataList::appendString(const String& string) |
38 { | 39 { |
39 CString encodedString = m_encoding.encode(string, WTF::EntitiesForUnencodabl
es); | 40 m_items.append(encodeAndNormalize(string)); |
40 m_items.append(normalizeLineEndingsToCRLF(encodedString)); | |
41 } | 41 } |
42 | 42 |
43 void FormDataList::appendString(const CString& string) | 43 void FormDataList::appendString(const CString& string) |
44 { | 44 { |
45 m_items.append(string); | 45 m_items.append(string); |
46 } | 46 } |
47 | 47 |
48 void FormDataList::appendBlob(Blob* blob, const String& filename) | 48 void FormDataList::appendBlob(Blob* blob, const String& filename) |
49 { | 49 { |
50 m_items.append(Item(blob, filename)); | 50 m_items.append(Item(blob, filename)); |
51 } | 51 } |
52 | 52 |
| 53 void FormDataList::deleteEntry(const String& key) |
| 54 { |
| 55 const CString keyData = encodeAndNormalize(key); |
| 56 ASSERT(!(m_items.size() % 2)); |
| 57 size_t i = 0; |
| 58 while (i < m_items.size()) { |
| 59 if (m_items[i].data() == keyData) { |
| 60 m_items.remove(i, 2); |
| 61 } else { |
| 62 i += 2; |
| 63 } |
| 64 } |
| 65 ASSERT(!(m_items.size() % 2)); |
| 66 return; |
| 67 } |
| 68 |
| 69 FormDataList::Entry FormDataList::getEntry(const String& key) const |
| 70 { |
| 71 const CString keyData = encodeAndNormalize(key); |
| 72 const FormDataListItems& items = this->items(); |
| 73 size_t formDataListSize = items.size(); |
| 74 ASSERT(!(formDataListSize % 2)); |
| 75 for (size_t i = 0; i < formDataListSize; i += 2) { |
| 76 const FormDataList::Item& key = items[i]; |
| 77 if (key.data() != keyData) |
| 78 continue; |
| 79 const FormDataList::Item& value = items[i + 1]; |
| 80 return itemsToEntry(key, value); |
| 81 } |
| 82 return Entry(); |
| 83 } |
| 84 |
| 85 FormDataList::Entry FormDataList::getEntry(size_t index) const |
| 86 { |
| 87 const FormDataListItems& items = this->items(); |
| 88 size_t formDataListSize = items.size(); |
| 89 ASSERT(!(formDataListSize % 2)); |
| 90 if (index >= formDataListSize / 2) |
| 91 return Entry(); |
| 92 const FormDataList::Item& key = items[index * 2]; |
| 93 const FormDataList::Item& value = items[index * 2 + 1]; |
| 94 return itemsToEntry(key, value); |
| 95 } |
| 96 |
| 97 WillBeHeapVector<FormDataList::Entry> FormDataList::getAll(const String& key) co
nst |
| 98 { |
| 99 WillBeHeapVector<FormDataList::Entry> matches; |
| 100 |
| 101 const CString keyData = encodeAndNormalize(key); |
| 102 const FormDataListItems& items = this->items(); |
| 103 size_t formDataListSize = items.size(); |
| 104 ASSERT(!(formDataListSize % 2)); |
| 105 for (size_t i = 0; i < formDataListSize; i += 2) { |
| 106 const FormDataList::Item& key = items[i]; |
| 107 if (key.data() != keyData) |
| 108 continue; |
| 109 const FormDataList::Item& value = items[i + 1]; |
| 110 matches.append(itemsToEntry(key, value)); |
| 111 } |
| 112 |
| 113 return matches; |
| 114 } |
| 115 |
| 116 FormDataList::Entry FormDataList::itemsToEntry(const FormDataList::Item& key, co
nst FormDataList::Item& value) const |
| 117 { |
| 118 const CString nameData = key.data(); |
| 119 const String name = m_encoding.decode(nameData.data(), nameData.length()); |
| 120 |
| 121 if (!value.blob()) { |
| 122 const CString valueData = value.data(); |
| 123 return Entry(name, m_encoding.decode(valueData.data(), valueData.length(
))); |
| 124 } |
| 125 |
| 126 // The spec uses the passed filename when inserting entries into the list. |
| 127 // Here, we apply the filename (if present) as an override when extracting |
| 128 // items. |
| 129 // FIXME: Consider applying the name during insertion. |
| 130 |
| 131 if (value.blob()->isFile()) { |
| 132 File* file = toFile(value.blob()); |
| 133 if (value.filename().isNull()) |
| 134 return Entry(name, file); |
| 135 return Entry(name, file->clone(value.filename())); |
| 136 } |
| 137 |
| 138 String filename = value.filename(); |
| 139 if (filename.isNull()) |
| 140 filename = "blob"; |
| 141 return Entry(name, File::create(filename, currentTime(), value.blob()->blobD
ataHandle())); |
| 142 } |
| 143 |
| 144 bool FormDataList::hasEntry(const String& key) const |
| 145 { |
| 146 const CString keyData = encodeAndNormalize(key); |
| 147 const FormDataListItems& items = this->items(); |
| 148 size_t formDataListSize = items.size(); |
| 149 ASSERT(!(formDataListSize % 2)); |
| 150 for (size_t i = 0; i < formDataListSize; i += 2) { |
| 151 const FormDataList::Item& key = items[i]; |
| 152 if (key.data() == keyData) |
| 153 return true; |
| 154 } |
| 155 return false; |
| 156 } |
| 157 |
| 158 void FormDataList::setBlob(const String& key, Blob* blob, const String& filename
) |
| 159 { |
| 160 setEntry(key, Item(blob, filename)); |
| 161 } |
| 162 |
| 163 void FormDataList::setData(const String& key, const String& value) |
| 164 { |
| 165 setEntry(key, encodeAndNormalize(value)); |
| 166 } |
| 167 |
| 168 void FormDataList::setEntry(const String& key, const Item& item) |
| 169 { |
| 170 const CString keyData = encodeAndNormalize(key); |
| 171 ASSERT(!(m_items.size() % 2)); |
| 172 bool found = false; |
| 173 size_t i = 0; |
| 174 while (i < m_items.size()) { |
| 175 if (m_items[i].data() != keyData) { |
| 176 i += 2; |
| 177 } else if (found) { |
| 178 m_items.remove(i, 2); |
| 179 } else { |
| 180 found = true; |
| 181 m_items[i + 1] = item; |
| 182 i += 2; |
| 183 } |
| 184 } |
| 185 if (!found) { |
| 186 m_items.append(keyData); |
| 187 m_items.append(item); |
| 188 } |
| 189 ASSERT(!(m_items.size() % 2)); |
| 190 return; |
| 191 } |
| 192 |
53 PassRefPtr<FormData> FormDataList::createFormData(FormData::EncodingType encodin
gType) | 193 PassRefPtr<FormData> FormDataList::createFormData(FormData::EncodingType encodin
gType) |
54 { | 194 { |
55 RefPtr<FormData> result = FormData::create(); | 195 RefPtr<FormData> result = FormData::create(); |
56 appendKeyValuePairItemsTo(result.get(), m_encoding, false, encodingType); | 196 appendKeyValuePairItemsTo(result.get(), m_encoding, false, encodingType); |
57 return result.release(); | 197 return result.release(); |
58 } | 198 } |
59 | 199 |
60 PassRefPtr<FormData> FormDataList::createMultiPartFormData() | 200 PassRefPtr<FormData> FormDataList::createMultiPartFormData() |
61 { | 201 { |
62 RefPtr<FormData> result = FormData::create(); | 202 RefPtr<FormData> result = FormData::create(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(),
value.data(), encodingType); | 275 FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(),
value.data(), encodingType); |
136 } | 276 } |
137 } | 277 } |
138 | 278 |
139 if (isMultiPartForm) | 279 if (isMultiPartForm) |
140 FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, formData->bou
ndary().data(), true); | 280 FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, formData->bou
ndary().data(), true); |
141 | 281 |
142 formData->appendData(encodedData.data(), encodedData.size()); | 282 formData->appendData(encodedData.data(), encodedData.size()); |
143 } | 283 } |
144 | 284 |
| 285 CString FormDataList::encodeAndNormalize(const String& string) const |
| 286 { |
| 287 CString encodedString = m_encoding.encode(string, WTF::EntitiesForUnencodabl
es); |
| 288 return normalizeLineEndingsToCRLF(encodedString); |
| 289 } |
| 290 |
145 void FormDataList::trace(Visitor* visitor) | 291 void FormDataList::trace(Visitor* visitor) |
146 { | 292 { |
147 visitor->trace(m_items); | 293 visitor->trace(m_items); |
148 } | 294 } |
149 | 295 |
| 296 |
| 297 void FormDataList::Entry::trace(Visitor* visitor) |
| 298 { |
| 299 visitor->trace(m_file); |
| 300 } |
| 301 |
150 void FormDataList::Item::trace(Visitor* visitor) | 302 void FormDataList::Item::trace(Visitor* visitor) |
151 { | 303 { |
152 visitor->trace(m_blob); | 304 visitor->trace(m_blob); |
153 } | 305 } |
154 | 306 |
155 } // namespace | 307 } // namespace blink |
OLD | NEW |