1/* 2 * Copyright (C) 2004, 2006, 2008, 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Google Inc. All rights reserved. 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22#include "config.h" 23#include "platform/network/FormData.h" 24 25#include "platform/FileMetadata.h" 26#include "platform/network/FormDataBuilder.h" 27#include "wtf/text/CString.h" 28#include "wtf/text/TextEncoding.h" 29 30namespace blink { 31 32inline FormData::FormData() 33 : m_identifier(0) 34 , m_alwaysStream(false) 35 , m_containsPasswordData(false) 36{ 37} 38 39inline FormData::FormData(const FormData& data) 40 : RefCounted<FormData>() 41 , m_elements(data.m_elements) 42 , m_identifier(data.m_identifier) 43 , m_alwaysStream(false) 44 , m_containsPasswordData(data.m_containsPasswordData) 45{ 46} 47 48FormData::~FormData() 49{ 50} 51 52PassRefPtr<FormData> FormData::create() 53{ 54 return adoptRef(new FormData); 55} 56 57PassRefPtr<FormData> FormData::create(const void* data, size_t size) 58{ 59 RefPtr<FormData> result = create(); 60 result->appendData(data, size); 61 return result.release(); 62} 63 64PassRefPtr<FormData> FormData::create(const CString& string) 65{ 66 RefPtr<FormData> result = create(); 67 result->appendData(string.data(), string.length()); 68 return result.release(); 69} 70 71PassRefPtr<FormData> FormData::create(const Vector<char>& vector) 72{ 73 RefPtr<FormData> result = create(); 74 result->appendData(vector.data(), vector.size()); 75 return result.release(); 76} 77 78PassRefPtr<FormData> FormData::copy() const 79{ 80 return adoptRef(new FormData(*this)); 81} 82 83PassRefPtr<FormData> FormData::deepCopy() const 84{ 85 RefPtr<FormData> formData(create()); 86 87 formData->m_alwaysStream = m_alwaysStream; 88 89 size_t n = m_elements.size(); 90 formData->m_elements.reserveInitialCapacity(n); 91 for (size_t i = 0; i < n; ++i) { 92 const FormDataElement& e = m_elements[i]; 93 switch (e.m_type) { 94 case FormDataElement::data: 95 formData->m_elements.uncheckedAppend(FormDataElement(e.m_data)); 96 break; 97 case FormDataElement::encodedFile: 98 formData->m_elements.uncheckedAppend(FormDataElement(e.m_filename, e.m_fileStart, e.m_fileLength, e.m_expectedFileModificationTime)); 99 break; 100 case FormDataElement::encodedBlob: 101 formData->m_elements.uncheckedAppend(FormDataElement(e.m_blobUUID, e.m_optionalBlobDataHandle)); 102 break; 103 case FormDataElement::encodedFileSystemURL: 104 formData->m_elements.uncheckedAppend(FormDataElement(e.m_fileSystemURL, e.m_fileStart, e.m_fileLength, e.m_expectedFileModificationTime)); 105 break; 106 } 107 } 108 return formData.release(); 109} 110 111void FormData::appendData(const void* data, size_t size) 112{ 113 if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::data) 114 m_elements.append(FormDataElement()); 115 FormDataElement& e = m_elements.last(); 116 size_t oldSize = e.m_data.size(); 117 e.m_data.grow(oldSize + size); 118 memcpy(e.m_data.data() + oldSize, data, size); 119} 120 121void FormData::appendFile(const String& filename) 122{ 123 m_elements.append(FormDataElement(filename, 0, BlobDataItem::toEndOfFile, invalidFileTime())); 124} 125 126void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime) 127{ 128 m_elements.append(FormDataElement(filename, start, length, expectedModificationTime)); 129} 130 131void FormData::appendBlob(const String& uuid, PassRefPtr<BlobDataHandle> optionalHandle) 132{ 133 m_elements.append(FormDataElement(uuid, optionalHandle)); 134} 135 136void FormData::appendFileSystemURL(const KURL& url) 137{ 138 m_elements.append(FormDataElement(url, 0, BlobDataItem::toEndOfFile, invalidFileTime())); 139} 140 141void FormData::appendFileSystemURLRange(const KURL& url, long long start, long long length, double expectedModificationTime) 142{ 143 m_elements.append(FormDataElement(url, start, length, expectedModificationTime)); 144} 145 146void FormData::flatten(Vector<char>& data) const 147{ 148 // Concatenate all the byte arrays, but omit any files. 149 data.clear(); 150 size_t n = m_elements.size(); 151 for (size_t i = 0; i < n; ++i) { 152 const FormDataElement& e = m_elements[i]; 153 if (e.m_type == FormDataElement::data) 154 data.append(e.m_data.data(), static_cast<size_t>(e.m_data.size())); 155 } 156} 157 158String FormData::flattenToString() const 159{ 160 Vector<char> bytes; 161 flatten(bytes); 162 return Latin1Encoding().decode(reinterpret_cast<const char*>(bytes.data()), bytes.size()); 163} 164 165unsigned long long FormData::sizeInBytes() const 166{ 167 unsigned size = 0; 168 size_t n = m_elements.size(); 169 for (size_t i = 0; i < n; ++i) { 170 const FormDataElement& e = m_elements[i]; 171 switch (e.m_type) { 172 case FormDataElement::data: 173 size += e.m_data.size(); 174 break; 175 case FormDataElement::encodedFile: 176 size += e.m_fileLength - e.m_fileStart; 177 break; 178 case FormDataElement::encodedBlob: 179 if (e.m_optionalBlobDataHandle) 180 size += e.m_optionalBlobDataHandle->size(); 181 break; 182 case FormDataElement::encodedFileSystemURL: 183 size += e.m_fileLength - e.m_fileStart; 184 break; 185 } 186 } 187 return size; 188} 189 190} // namespace blink 191