18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2cad810f21b803229eb11403f9209855525a25d57Steve Block * Copyright (C) 2004, 2006, 2008, 2011 Apple Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2009 Google Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
22545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FormData.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "BlobData.h"
265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "BlobURL.h"
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Chrome.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ChromeClient.h"
29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Document.h"
305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "File.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FileSystem.h"
32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "FormDataBuilder.h"
335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "FormDataList.h"
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "MIMETypeRegistry.h"
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Page.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextEncoding.h"
37cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/Decoder.h>
38cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/Encoder.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline FormData::FormData()
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    : m_identifier(0)
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_hasGeneratedFiles(false)
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_alwaysStream(false)
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline FormData::FormData(const FormData& data)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : RefCounted<FormData>()
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_elements(data.m_elements)
528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_identifier(data.m_identifier)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_hasGeneratedFiles(false)
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_alwaysStream(false)
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We shouldn't be copying FormData that hasn't already removed its generated files
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // but just in case, make sure the new FormData is ready to generate its own files.
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (data.m_hasGeneratedFiles) {
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        size_t n = m_elements.size();
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (size_t i = 0; i < n; ++i) {
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            FormDataElement& e = m_elements[i];
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (e.m_type == FormDataElement::encodedFile)
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                e.m_generatedFilename = String();
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFormData::~FormData()
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This cleanup should've happened when the form submission finished.
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Just in case, let's assert, and do the cleanup anyway in release builds.
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_hasGeneratedFiles);
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    removeGeneratedFilesIfNeeded();
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<FormData> FormData::create()
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return adoptRef(new FormData);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<FormData> FormData::create(const void* data, size_t size)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<FormData> result = create();
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result->appendData(data, size);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.release();
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<FormData> FormData::create(const CString& string)
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<FormData> result = create();
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result->appendData(string.data(), string.length());
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.release();
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<FormData> FormData::create(const Vector<char>& vector)
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<FormData> result = create();
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result->appendData(vector.data(), vector.size());
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.release();
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<FormData> FormData::create(const FormDataList& list, const TextEncoding& encoding)
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<FormData> result = create();
1055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    result->appendKeyValuePairItems(list, encoding, false, 0);
106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return result.release();
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenPassRefPtr<FormData> FormData::createMultiPart(const FormDataList& list, const TextEncoding& encoding, Document* document)
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<FormData> result = create();
1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    result->appendKeyValuePairItems(list, encoding, true, document);
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return result.release();
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<FormData> FormData::copy() const
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return adoptRef(new FormData(*this));
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<FormData> FormData::deepCopy() const
122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RefPtr<FormData> formData(create());
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    formData->m_alwaysStream = m_alwaysStream;
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    size_t n = m_elements.size();
1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    formData->m_elements.reserveInitialCapacity(n);
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    for (size_t i = 0; i < n; ++i) {
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        const FormDataElement& e = m_elements[i];
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        switch (e.m_type) {
132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case FormDataElement::data:
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            formData->m_elements.append(FormDataElement(e.m_data));
134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        case FormDataElement::encodedFile:
136dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#if ENABLE(BLOB)
137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            formData->m_elements.append(FormDataElement(e.m_filename, e.m_fileStart, e.m_fileLength, e.m_expectedFileModificationTime, e.m_shouldGenerateFile));
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#else
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            formData->m_elements.append(FormDataElement(e.m_filename, e.m_shouldGenerateFile));
140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            break;
142e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if ENABLE(BLOB)
143e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        case FormDataElement::encodedBlob:
144e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            formData->m_elements.append(FormDataElement(e.m_blobURL));
145e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            break;
146e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#endif
147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return formData.release();
150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
151635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FormData::appendData(const void* data, size_t size)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::data)
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_elements.append(FormDataElement());
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FormDataElement& e = m_elements.last();
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t oldSize = e.m_data.size();
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    e.m_data.grow(oldSize + size);
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(e.m_data.data() + oldSize, data, size);
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FormData::appendFile(const String& filename, bool shouldGenerateFile)
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
164dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#if ENABLE(BLOB)
1655ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_elements.append(FormDataElement(filename, 0, BlobDataItem::toEndOfFile, BlobDataItem::doNotCheckFileChange, shouldGenerateFile));
166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#else
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_elements.append(FormDataElement(filename, shouldGenerateFile));
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
171dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#if ENABLE(BLOB)
172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile)
173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_elements.append(FormDataElement(filename, start, length, expectedModificationTime, shouldGenerateFile));
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
176e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
177e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid FormData::appendBlob(const KURL& blobURL)
178e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
179e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    m_elements.append(FormDataElement(blobURL));
180e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (isMultiPartForm)
18606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        m_boundary = FormDataBuilder::generateUniqueBoundaryString();
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    Vector<char> encodedData;
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    const Vector<FormDataList::Item>& items = list.items();
191545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    size_t formDataListSize = items.size();
192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(!(formDataListSize % 2));
193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (size_t i = 0; i < formDataListSize; i += 2) {
1945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        const FormDataList::Item& key = items[i];
1955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        const FormDataList::Item& value = items[i + 1];
196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (isMultiPartForm) {
197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            Vector<char> header;
1985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());
199dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            bool shouldGenerateFile = false;
201967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
2025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            // If the current type is blob, then we also need to include the filename
2035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (value.blob()) {
2045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                String name;
2055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (value.blob()->isFile()) {
2065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    // For file blob, use the filename (or relative path if it is present) as the name.
2075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    File* file = static_cast<File*>(value.blob());
2085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(DIRECTORY_UPLOAD)
2095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();
210967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#else
2115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    name = file->name();
2122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#endif
2135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    // Let the application specify a filename if it's going to generate a replacement file for the upload.
2142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    const String& path = file->path();
2152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    if (!path.isEmpty()) {
2162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        if (Page* page = document->page()) {
2172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                            String generatedFileName;
2182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                            shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
2192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                            if (shouldGenerateFile)
2202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                                name = generatedFileName;
2212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                        }
222dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    }
2235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                } else {
2245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    // For non-file blob, use the identifier part of the URL as the name.
2255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    name = "Blob" + BlobURL::getIdentifier(value.blob()->url());
2265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    name = name.replace("-", ""); // For safety, remove '-' from the filename since some servers may not like it.
227dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
228dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
229dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                // We have to include the filename=".." part in the header, even if the filename is empty
2305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);
231dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2324a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
2334a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                String contentType;
2344a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                if (value.blob()->type().isEmpty())
2354a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                    contentType = "application/octet-stream";
2364a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                else
2374a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                    contentType = value.blob()->type();
2384a156157940f51b91eadd76f6c86f862ec0a1da0Ben Murdoch                FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.latin1());
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
24106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            FormDataBuilder::finishMultiPartHeader(header);
242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // Append body
244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            appendData(header.data(), header.size());
2455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (value.blob()) {
2465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                if (value.blob()->isFile()) {
2475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    // Do not add the file if the path is empty.
2485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    if (!static_cast<File*>(value.blob())->path().isEmpty())
2495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                        appendFile(static_cast<File*>(value.blob())->path(), shouldGenerateFile);
2505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                }
2515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if ENABLE(BLOB)
2525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                else
2535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                    appendBlob(value.blob()->url());
2545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#endif
2555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            } else
2565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                appendData(value.data().data(), value.data().length());
257dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            appendData("\r\n", 2);
258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        } else {
259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // Omit the name "isindex" if it's the first form data element.
260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // FIXME: Why is this a good rule? Is this obsolete now?
2615ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            if (encodedData.isEmpty() && key.data() == "isindex")
2625ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            else
2645ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data());
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
266545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (isMultiPartForm)
26906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);
270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
271dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    appendData(encodedData.data(), encodedData.size());
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FormData::flatten(Vector<char>& data) const
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Concatenate all the byte arrays, but omit any files.
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    data.clear();
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t n = m_elements.size();
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < n; ++i) {
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const FormDataElement& e = m_elements[i];
281545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (e.m_type == FormDataElement::data)
282545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            data.append(e.m_data.data(), static_cast<size_t>(e.m_data.size()));
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString FormData::flattenToString() const
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<char> bytes;
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    flatten(bytes);
290cad810f21b803229eb11403f9209855525a25d57Steve Block    return Latin1Encoding().decode(reinterpret_cast<const char*>(bytes.data()), bytes.size());
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29321939df44de1705786c545cd1bf519d47250322dBen Murdochvoid FormData::generateFiles(Document* document)
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_hasGeneratedFiles);
296545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_hasGeneratedFiles)
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
299545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
30021939df44de1705786c545cd1bf519d47250322dBen Murdoch    Page* page = document->page();
30121939df44de1705786c545cd1bf519d47250322dBen Murdoch    if (!page)
30221939df44de1705786c545cd1bf519d47250322dBen Murdoch        return;
30321939df44de1705786c545cd1bf519d47250322dBen Murdoch    ChromeClient* client = page->chrome()->client();
30421939df44de1705786c545cd1bf519d47250322dBen Murdoch
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t n = m_elements.size();
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < n; ++i) {
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FormDataElement& e = m_elements[i];
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (e.m_type == FormDataElement::encodedFile && e.m_shouldGenerateFile) {
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e.m_generatedFilename = client->generateReplacementFile(e.m_filename);
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_hasGeneratedFiles = true;
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FormData::removeGeneratedFilesIfNeeded()
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_hasGeneratedFiles)
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
319545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t n = m_elements.size();
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < n; ++i) {
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FormDataElement& e = m_elements[i];
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (e.m_type == FormDataElement::encodedFile && !e.m_generatedFilename.isEmpty()) {
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(e.m_shouldGenerateFile);
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String directory = directoryName(e.m_generatedFilename);
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deleteFile(e.m_generatedFilename);
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            deleteEmptyDirectory(directory);
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e.m_generatedFilename = String();
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasGeneratedFiles = false;
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
334cad810f21b803229eb11403f9209855525a25d57Steve Blockstatic void encode(Encoder& encoder, const FormDataElement& element)
335cad810f21b803229eb11403f9209855525a25d57Steve Block{
336cad810f21b803229eb11403f9209855525a25d57Steve Block    encoder.encodeUInt32(element.m_type);
337cad810f21b803229eb11403f9209855525a25d57Steve Block
338cad810f21b803229eb11403f9209855525a25d57Steve Block    switch (element.m_type) {
339cad810f21b803229eb11403f9209855525a25d57Steve Block    case FormDataElement::data:
340cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeBytes(reinterpret_cast<const uint8_t*>(element.m_data.data()), element.m_data.size());
341cad810f21b803229eb11403f9209855525a25d57Steve Block        return;
342cad810f21b803229eb11403f9209855525a25d57Steve Block
343cad810f21b803229eb11403f9209855525a25d57Steve Block    case FormDataElement::encodedFile:
344cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeString(element.m_filename);
345cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeBool(element.m_shouldGenerateFile);
346cad810f21b803229eb11403f9209855525a25d57Steve Block#if ENABLE(BLOB)
347cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeInt64(element.m_fileStart);
348cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeInt64(element.m_fileLength);
349cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeDouble(element.m_expectedFileModificationTime);
350cad810f21b803229eb11403f9209855525a25d57Steve Block#else
351cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeInt64(0);
352cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeInt64(0);
353cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeDouble(0);
354cad810f21b803229eb11403f9209855525a25d57Steve Block#endif
355cad810f21b803229eb11403f9209855525a25d57Steve Block        return;
356cad810f21b803229eb11403f9209855525a25d57Steve Block
357cad810f21b803229eb11403f9209855525a25d57Steve Block#if ENABLE(BLOB)
358cad810f21b803229eb11403f9209855525a25d57Steve Block    case FormDataElement::encodedBlob:
359cad810f21b803229eb11403f9209855525a25d57Steve Block        encoder.encodeString(element.m_blobURL.string());
360cad810f21b803229eb11403f9209855525a25d57Steve Block        return;
361cad810f21b803229eb11403f9209855525a25d57Steve Block#endif
362cad810f21b803229eb11403f9209855525a25d57Steve Block    }
363cad810f21b803229eb11403f9209855525a25d57Steve Block
364cad810f21b803229eb11403f9209855525a25d57Steve Block    ASSERT_NOT_REACHED();
365cad810f21b803229eb11403f9209855525a25d57Steve Block}
366cad810f21b803229eb11403f9209855525a25d57Steve Block
367cad810f21b803229eb11403f9209855525a25d57Steve Blockstatic bool decode(Decoder& decoder, FormDataElement& element)
368cad810f21b803229eb11403f9209855525a25d57Steve Block{
3692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    uint32_t type;
3702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!decoder.decodeUInt32(type))
3712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return false;
372cad810f21b803229eb11403f9209855525a25d57Steve Block
373cad810f21b803229eb11403f9209855525a25d57Steve Block    switch (type) {
374cad810f21b803229eb11403f9209855525a25d57Steve Block    case FormDataElement::data: {
375cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_type = FormDataElement::data;
376cad810f21b803229eb11403f9209855525a25d57Steve Block        Vector<uint8_t> data;
377cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeBytes(data))
378cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
379cad810f21b803229eb11403f9209855525a25d57Steve Block        size_t size = data.size();
380cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_data.resize(size);
381cad810f21b803229eb11403f9209855525a25d57Steve Block        memcpy(element.m_data.data(), data.data(), size);
382cad810f21b803229eb11403f9209855525a25d57Steve Block        return true;
383cad810f21b803229eb11403f9209855525a25d57Steve Block    }
384cad810f21b803229eb11403f9209855525a25d57Steve Block
385cad810f21b803229eb11403f9209855525a25d57Steve Block    case FormDataElement::encodedFile: {
386cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_type = FormDataElement::encodedFile;
387cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeString(element.m_filename))
388cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
389cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeBool(element.m_shouldGenerateFile))
390cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
391cad810f21b803229eb11403f9209855525a25d57Steve Block        int64_t fileStart;
392cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeInt64(fileStart))
393cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
394cad810f21b803229eb11403f9209855525a25d57Steve Block        if (fileStart < 0)
395cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
396cad810f21b803229eb11403f9209855525a25d57Steve Block        int64_t fileLength;
397cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeInt64(fileLength))
398cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
399cad810f21b803229eb11403f9209855525a25d57Steve Block        if (fileLength < fileStart)
400cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
401cad810f21b803229eb11403f9209855525a25d57Steve Block        double expectedFileModificationTime;
402cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeDouble(expectedFileModificationTime))
403cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
404cad810f21b803229eb11403f9209855525a25d57Steve Block#if ENABLE(BLOB)
405cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_fileStart = fileStart;
406cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_fileLength = fileLength;
407cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_expectedFileModificationTime = expectedFileModificationTime;
408cad810f21b803229eb11403f9209855525a25d57Steve Block#endif
409cad810f21b803229eb11403f9209855525a25d57Steve Block        return true;
410cad810f21b803229eb11403f9209855525a25d57Steve Block    }
411cad810f21b803229eb11403f9209855525a25d57Steve Block
412cad810f21b803229eb11403f9209855525a25d57Steve Block#if ENABLE(BLOB)
413cad810f21b803229eb11403f9209855525a25d57Steve Block    case FormDataElement::encodedBlob:
414cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_type = FormDataElement::encodedBlob;
415cad810f21b803229eb11403f9209855525a25d57Steve Block        String blobURLString;
416cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decoder.decodeString(blobURLString))
417cad810f21b803229eb11403f9209855525a25d57Steve Block            return false;
418cad810f21b803229eb11403f9209855525a25d57Steve Block        element.m_blobURL = KURL(KURL(), blobURLString);
419cad810f21b803229eb11403f9209855525a25d57Steve Block        return true;
420cad810f21b803229eb11403f9209855525a25d57Steve Block#endif
421cad810f21b803229eb11403f9209855525a25d57Steve Block    }
422cad810f21b803229eb11403f9209855525a25d57Steve Block
423cad810f21b803229eb11403f9209855525a25d57Steve Block    return false;
424cad810f21b803229eb11403f9209855525a25d57Steve Block}
425cad810f21b803229eb11403f9209855525a25d57Steve Block
426cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid FormData::encodeForBackForward(Encoder& encoder) const
427cad810f21b803229eb11403f9209855525a25d57Steve Block{
428cad810f21b803229eb11403f9209855525a25d57Steve Block    encoder.encodeBool(m_alwaysStream);
429cad810f21b803229eb11403f9209855525a25d57Steve Block
430cad810f21b803229eb11403f9209855525a25d57Steve Block    encoder.encodeBytes(reinterpret_cast<const uint8_t*>(m_boundary.data()), m_boundary.size());
431cad810f21b803229eb11403f9209855525a25d57Steve Block
432cad810f21b803229eb11403f9209855525a25d57Steve Block    size_t size = m_elements.size();
433cad810f21b803229eb11403f9209855525a25d57Steve Block    encoder.encodeUInt64(size);
434cad810f21b803229eb11403f9209855525a25d57Steve Block    for (size_t i = 0; i < size; ++i)
435cad810f21b803229eb11403f9209855525a25d57Steve Block        encode(encoder, m_elements[i]);
436cad810f21b803229eb11403f9209855525a25d57Steve Block
437cad810f21b803229eb11403f9209855525a25d57Steve Block    encoder.encodeBool(m_hasGeneratedFiles);
438cad810f21b803229eb11403f9209855525a25d57Steve Block
4392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    encoder.encodeInt64(m_identifier);
440cad810f21b803229eb11403f9209855525a25d57Steve Block}
441cad810f21b803229eb11403f9209855525a25d57Steve Block
442cad810f21b803229eb11403f9209855525a25d57Steve BlockPassRefPtr<FormData> FormData::decodeForBackForward(Decoder& decoder)
443cad810f21b803229eb11403f9209855525a25d57Steve Block{
444cad810f21b803229eb11403f9209855525a25d57Steve Block    RefPtr<FormData> data = FormData::create();
445cad810f21b803229eb11403f9209855525a25d57Steve Block
446cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!decoder.decodeBool(data->m_alwaysStream))
447cad810f21b803229eb11403f9209855525a25d57Steve Block        return 0;
448cad810f21b803229eb11403f9209855525a25d57Steve Block
449cad810f21b803229eb11403f9209855525a25d57Steve Block    Vector<uint8_t> boundary;
450cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!decoder.decodeBytes(boundary))
451cad810f21b803229eb11403f9209855525a25d57Steve Block        return 0;
452cad810f21b803229eb11403f9209855525a25d57Steve Block    size_t size = boundary.size();
453cad810f21b803229eb11403f9209855525a25d57Steve Block    data->m_boundary.resize(size);
454cad810f21b803229eb11403f9209855525a25d57Steve Block    memcpy(data->m_boundary.data(), boundary.data(), size);
455cad810f21b803229eb11403f9209855525a25d57Steve Block
456cad810f21b803229eb11403f9209855525a25d57Steve Block    uint64_t elementsSize;
457cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!decoder.decodeUInt64(elementsSize))
458cad810f21b803229eb11403f9209855525a25d57Steve Block        return 0;
459cad810f21b803229eb11403f9209855525a25d57Steve Block    for (size_t i = 0; i < elementsSize; ++i) {
460cad810f21b803229eb11403f9209855525a25d57Steve Block        FormDataElement element;
461cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!decode(decoder, element))
462cad810f21b803229eb11403f9209855525a25d57Steve Block            return 0;
463cad810f21b803229eb11403f9209855525a25d57Steve Block        data->m_elements.append(element);
464cad810f21b803229eb11403f9209855525a25d57Steve Block    }
465cad810f21b803229eb11403f9209855525a25d57Steve Block
466cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!decoder.decodeBool(data->m_hasGeneratedFiles))
467cad810f21b803229eb11403f9209855525a25d57Steve Block        return 0;
468cad810f21b803229eb11403f9209855525a25d57Steve Block
469cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!decoder.decodeInt64(data->m_identifier))
470cad810f21b803229eb11403f9209855525a25d57Steve Block        return 0;
471cad810f21b803229eb11403f9209855525a25d57Steve Block
472cad810f21b803229eb11403f9209855525a25d57Steve Block    return data.release();
473cad810f21b803229eb11403f9209855525a25d57Steve Block}
474cad810f21b803229eb11403f9209855525a25d57Steve Block
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
476