Changeset 60799 in webkit
- Timestamp:
- Jun 7, 2010 1:55:00 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/CMakeLists.txt
r60776 r60799 1123 1123 1124 1124 platform/Arena.cpp 1125 platform/BlobItem.cpp 1125 1126 platform/ContentType.cpp 1126 1127 platform/ContextMenu.cpp -
trunk/WebCore/ChangeLog
r60798 r60799 1 2010-06-07 Kinuko Yasuda <kinuko@chromium.org> 2 3 Reviewed by Jian Li. 4 5 Refactor FormData and Blob for better support of Blobs synthesized by BlobBuilder. 6 https://bugs.webkit.org/show_bug.cgi?id=39083 7 8 - Introduces a new class BlobItem as a basic component of Blob and FormDataList. 9 - File would become a special type of Blob that contains only one FileBlobItem. 10 - Fix the dependency violation in FormData so that the files under platform/ do not include any html/ files. 11 12 The patch doesn't support the latest File API changes (e.g. type, 13 url and slice's type parameters) and should not change any of its 14 existing behaviors. 15 16 The existing tests should be able to be used for regression. 17 18 * CMakeLists.txt: 19 * GNUmakefile.am: 20 * WebCore.gypi: 21 * WebCore.pro: 22 * WebCore.vcproj/WebCore.vcproj: 23 * WebCore.xcodeproj/project.pbxproj: 24 * html/Blob.cpp: 25 (WebCore::Blob::Blob): 26 (WebCore::Blob::size): 27 (WebCore::Blob::path): 28 (WebCore::Blob::append): 29 (WebCore::Blob::slice): 30 * html/Blob.h: 31 (WebCore::Blob::create): 32 (WebCore::Blob::type): 33 (WebCore::Blob::items): 34 (WebCore::Blob::Blob): 35 * html/File.cpp: 36 (WebCore::File::File): 37 (WebCore::File::name): 38 * html/File.h: 39 (WebCore::File::fileName): 40 * html/FileReader.cpp: 41 (WebCore::FileReader::readAsBinaryString): 42 (WebCore::FileReader::readAsText): 43 * html/FileStream.cpp: 44 (WebCore::FileStream::openForRead): 45 * html/FormDataList.cpp: 46 (WebCore::FormDataList::appendString): Moved the line ending fix logic to StringBlobItem::convertToCString. 47 (WebCore::FormDataList::appendBlob): 48 * html/FormDataList.h: 49 (WebCore::FormDataList::items): 50 * html/HTMLFormElement.cpp: 51 (WebCore::HTMLFormElement::createFormData): 52 * html/HTMLProgressElement.cpp: 53 * platform/BlobItem.cpp: Added. 54 * platform/BlobItem.h: Added. 55 * platform/network/FormData.cpp: 56 (WebCore::FormDataElement::FormDataElement): 57 (WebCore::FormData::create): 58 (WebCore::FormData::createMultiPart): 59 (WebCore::FormData::deepCopy): 60 (WebCore::FormData::appendData): 61 (WebCore::FormData::appendString): 62 (WebCore::FormData::appendFile): 63 (WebCore::FormData::appendFileRange): 64 (WebCore::FormData::appendItems): 65 (WebCore::FormData::appendItem): 66 (WebCore::FormData::appendKeyValuePairItems): 67 * platform/network/FormData.h: 68 (WebCore::operator!=): 69 * platform/network/mac/FormDataStreamMac.mm: 70 (WebCore::closeCurrentStream): 71 (WebCore::advanceCurrentStream): 72 (WebCore::formCreate): 73 (WebCore::formRead): 74 (WebCore::setHTTPBody): 75 * xml/XMLHttpRequest.cpp: 76 (WebCore::XMLHttpRequest::send): 77 1 78 2010-06-07 Vangelis Kokkevis <vangelis@chromium.org> 2 79 -
trunk/WebCore/GNUmakefile.am
r60793 r60799 1560 1560 WebCore/platform/Arena.h \ 1561 1561 WebCore/platform/AutodrainedPool.h \ 1562 WebCore/platform/BlobItem.cpp \ 1563 WebCore/platform/BlobItem.h \ 1562 1564 WebCore/platform/ContentType.cpp \ 1563 1565 WebCore/platform/ContentType.h \ -
trunk/WebCore/WebCore.gypi
r60776 r60799 2881 2881 'platform/Arena.h', 2882 2882 'platform/AutodrainedPool.h', 2883 'platform/BlobItem.cpp', 2884 'platform/BlobItem.h', 2883 2885 'platform/ContentType.cpp', 2884 2886 'platform/ContentType.h', -
trunk/WebCore/WebCore.pro
r60776 r60799 816 816 platform/animation/AnimationList.cpp \ 817 817 platform/Arena.cpp \ 818 platform/BlobItem.cpp \ 818 819 platform/text/Base64.cpp \ 819 820 platform/text/BidiContext.cpp \ … … 1565 1566 platform/animation/AnimationList.h \ 1566 1567 platform/Arena.h \ 1568 platform/BlobItem.h \ 1567 1569 platform/ContentType.h \ 1568 1570 platform/ContextMenu.h \ -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r60776 r60799 22370 22370 </File> 22371 22371 <File 22372 RelativePath="..\platform\BlobItem.cpp" 22373 > 22374 </File> 22375 <File 22376 RelativePath="..\platform\BlobItem.h" 22377 > 22378 </File> 22379 <File 22372 22380 RelativePath="..\platform\ContentType.cpp" 22373 22381 > -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r60776 r60799 2281 2281 895253DF116C4F0600CABF00 /* FileThreadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 895253DE116C4F0600CABF00 /* FileThreadTask.h */; }; 2282 2282 8FAC774D119872CB0015AE94 /* JSMainThreadExecState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F934D841189F1EE00508D5D /* JSMainThreadExecState.cpp */; }; 2283 8988E10E11A3508B00DB732E /* BlobItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8988E10C11A3508B00DB732E /* BlobItem.cpp */; }; 2284 8988E10F11A3508B00DB732E /* BlobItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 8988E10D11A3508B00DB732E /* BlobItem.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2283 2285 9302B0BD0D79F82900C7EE83 /* PageGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */; }; 2284 2286 9302B0BF0D79F82C00C7EE83 /* PageGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 9302B0BE0D79F82C00C7EE83 /* PageGroup.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 7889 7891 8F934D831189F1EE00508D5D /* JSMainThreadExecState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMainThreadExecState.h; sourceTree = "<group>"; }; 7890 7892 8F934D841189F1EE00508D5D /* JSMainThreadExecState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMainThreadExecState.cpp; sourceTree = "<group>"; }; 7893 8988E10C11A3508B00DB732E /* BlobItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlobItem.cpp; sourceTree = "<group>"; }; 7894 8988E10D11A3508B00DB732E /* BlobItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobItem.h; sourceTree = "<group>"; }; 7891 7895 9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageGroup.cpp; sourceTree = "<group>"; }; 7892 7896 9302B0BE0D79F82C00C7EE83 /* PageGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageGroup.h; sourceTree = "<group>"; }; … … 15863 15867 BCFB2F75097A2E1A00BA703D /* Arena.h */, 15864 15868 51E1ECB10C91C55600DC255B /* AutodrainedPool.h */, 15869 8988E10C11A3508B00DB732E /* BlobItem.cpp */, 15870 8988E10D11A3508B00DB732E /* BlobItem.h */, 15865 15871 BCC8CFCA0986CD2400140BF2 /* ColorData.gperf */, 15866 15872 41D015C90F4B5C71004A662F /* ContentType.cpp */, … … 16900 16906 A89943280B42338800D7C802 /* BitmapImage.h in Headers */, 16901 16907 2EAFAF0F10E2AF2D007ED3D6 /* Blob.h in Headers */, 16908 8988E10F11A3508B00DB732E /* BlobItem.h in Headers */, 16902 16909 93F199BE08245E59001E9ABC /* BlockExceptions.h in Headers */, 16903 16910 BC5EB5E10E81BE8700B25965 /* BorderData.h in Headers */, … … 19733 19740 A89943290B42338800D7C802 /* BitmapImage.cpp in Sources */, 19734 19741 2EAFAF0E10E2AF2D007ED3D6 /* Blob.cpp in Sources */, 19742 8988E10E11A3508B00DB732E /* BlobItem.cpp in Sources */, 19735 19743 93F19AE108245E59001E9ABC /* BlockExceptions.mm in Sources */, 19736 19744 BCEA4854097D93020094C9E4 /* break_lines.cpp in Sources */, -
trunk/WebCore/html/Blob.cpp
r55676 r60799 32 32 #include "Blob.h" 33 33 34 #include "BlobItem.h" 34 35 #include "FileSystem.h" 35 36 36 37 namespace WebCore { 37 38 38 #if ENABLE(BLOB_SLICE)39 const int Blob::toEndOfFile = -1;40 const double Blob::doNotCheckFileChange = 0;41 #endif42 43 39 Blob::Blob(const String& path) 44 : m_path(path)45 #if ENABLE(BLOB_SLICE)46 , m_start(0)47 , m_length(toEndOfFile)48 , m_snapshotCaptured(false)49 , m_snapshotSize(0)50 , m_snapshotModificationTime(doNotCheckFileChange)51 #endif52 40 { 41 // Note: this doesn't initialize the type unlike File(path). 42 append(FileBlobItem::create(path)); 53 43 } 54 55 #if ENABLE(BLOB_SLICE)56 Blob::Blob(const String& path, long long start, long long length, long long snapshotSize, double snapshotModificationTime)57 : m_path(path)58 , m_start(start)59 , m_length(length)60 , m_snapshotCaptured(true)61 , m_snapshotSize(snapshotSize)62 , m_snapshotModificationTime(snapshotModificationTime)63 {64 ASSERT(start >= 0 && length >= 0 && start + length <= snapshotSize && snapshotModificationTime);65 }66 #endif67 44 68 45 unsigned long long Blob::size() const … … 70 47 // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to 71 48 // come up with an exception to throw if file size is not represetable. 72 #if ENABLE(BLOB_SLICE) 73 if (m_snapshotCaptured) 74 return m_length; 75 #endif 76 long long size; 77 if (!getFileSize(m_path, size)) 78 return 0; 79 return static_cast<unsigned long long>(size); 49 unsigned long long size = 0; 50 for (size_t i = 0; i < m_items.size(); ++i) 51 size += m_items[i]->size(); 52 return size; 53 } 54 55 const String& Blob::path() const 56 { 57 ASSERT(m_items.size() == 1 && m_items[0]->toFileBlobItem()); 58 return m_items[0]->toFileBlobItem()->path(); 59 } 60 61 void Blob::append(PassRefPtr<BlobItem> item) 62 { 63 m_items.append(item); 80 64 } 81 65 … … 83 67 PassRefPtr<Blob> Blob::slice(long long start, long long length) const 84 68 { 85 // When we slice a file for the first time, we obtain a snapshot of the file by capturing its current size and modification time.86 // The modification time will be used to verify if the file has been changed or not, when the underlying data are accessed.87 long long snapshotSize;88 double snapshotModificationTime;89 if (m_snapshotCaptured) {90 snapshotSize = m_snapshotSize;91 snapshotModificationTime = m_snapshotModificationTime;92 } else {93 // If we fail to retrieve the size or modification time, probably due to that the file has been deleted, an empty blob will be returned.94 time_t modificationTime;95 if (!getFileSize(m_path, snapshotSize) || !getFileModificationTime(m_path, modificationTime)) {96 snapshotSize = 0;97 snapshotModificationTime = 0;98 } else99 snapshotModificationTime = modificationTime;100 }101 102 // Clamp the range if it exceeds the size limit.103 69 if (start < 0) 104 70 start = 0; … … 106 72 length = 0; 107 73 108 if (start > snapshotSize) { 74 // Clamp the range if it exceeds the size limit. 75 unsigned long long totalSize = size(); 76 if (static_cast<unsigned long long>(start) > totalSize) { 109 77 start = 0; 110 78 length = 0; 111 } else if (sta rt + length > snapshotSize)112 length = snapshotSize - start;79 } else if (static_cast<unsigned long long>(start + length) > totalSize) 80 length = totalSize - start; 113 81 114 return adoptRef(new Blob(m_path, m_start + start, length, snapshotSize, snapshotModificationTime)); 82 size_t i = 0; 83 RefPtr<Blob> blob = Blob::create(); 84 for (; i < m_items.size() && static_cast<unsigned long long>(start) >= m_items[i]->size(); ++i) 85 start -= m_items[i]->size(); 86 for (; length > 0 && i < m_items.size(); ++i) { 87 blob->m_items.append(m_items[i]->slice(start, length)); 88 length -= blob->m_items.last()->size(); 89 start = 0; 90 } 91 return blob.release(); 115 92 } 116 #endif 93 #endif // ENABLE(BLOB_SLICE) 117 94 118 95 } // namespace WebCore -
trunk/WebCore/html/Blob.h
r57695 r60799 32 32 #define Blob_h 33 33 34 #include " ExceptionCode.h"34 #include "BlobItem.h" 35 35 #include "PlatformString.h" 36 #include <time.h>37 36 #include <wtf/PassRefPtr.h> 38 37 #include <wtf/RefCounted.h> 38 #include <wtf/Vector.h> 39 39 40 40 namespace WebCore { … … 42 42 class Blob : public RefCounted<Blob> { 43 43 public: 44 #if ENABLE(BLOB_SLICE)45 static const int toEndOfFile;46 static const double doNotCheckFileChange;47 #endif 44 static PassRefPtr<Blob> create() 45 { 46 return adoptRef(new Blob()); 47 } 48 48 49 // FIXME: Deprecated method. This is called only from 50 // bindings/v8/SerializedScriptValue.cpp and the usage in it will become invalid once 51 // BlobBuilder is introduced. 49 52 static PassRefPtr<Blob> create(const String& path) 50 53 { … … 54 57 virtual ~Blob() { } 55 58 59 unsigned long long size() const; 60 const String& type() const { return m_type; } 56 61 virtual bool isFile() const { return false; } 62 63 // FIXME: Deprecated method. 64 const String& path() const; 65 66 void append(PassRefPtr<BlobItem>); 67 const BlobItemList& items() const { return m_items; } 57 68 58 69 #if ENABLE(BLOB_SLICE) … … 60 71 #endif 61 72 62 const String& path() const { return m_path; } 63 unsigned long long size() const; 64 #if ENABLE(BLOB_SLICE) 65 long long start() const { return m_start; } 66 long long length() const { return m_length; } 67 double modificationTime() const { return m_snapshotModificationTime; } 68 #endif 73 protected: 74 Blob() { } 69 75 70 protected: 76 // FIXME: Deprecated constructor. See also the comment for Blob::create(path). 71 77 Blob(const String& path); 72 78 73 private: 74 #if ENABLE(BLOB_SLICE) 75 Blob(const String& path, long long start, long long length, long long snapshotSize, double snapshotModificationTime); 76 #endif 77 78 // The underlying path of the file-based blob. 79 String m_path; 80 81 #if ENABLE(BLOB_SLICE) 82 // The starting position of the file-based blob. 83 long long m_start; 84 85 // The length of the file-based blob. The value of -1 means to the end of the file. 86 long long m_length; 87 88 // A flag to tell if a snapshot has been captured. 89 bool m_snapshotCaptured; 90 91 // The size of the file when a snapshot is captured. It can be 0 if the file is empty. 92 long long m_snapshotSize; 93 94 // The last modification time of the file when a snapshot is captured. The value of 0 also means that the snapshot is not captured. 95 double m_snapshotModificationTime; 96 #endif 79 BlobItemList m_items; 80 String m_type; 97 81 }; 98 82 -
trunk/WebCore/html/File.cpp
r55257 r60799 34 34 File::File(const String& path) 35 35 : Blob(path) 36 , m_name(pathGetFileName(path))37 36 { 38 37 // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure. 39 int index = m_name.reverseFind('.'); 38 const String& fileName = name(); 39 int index = fileName.reverseFind('.'); 40 40 if (index != -1) 41 m_type = MIMETypeRegistry::getMIMETypeForExtension(m_name.substring(index + 1)); 41 m_type = MIMETypeRegistry::getMIMETypeForExtension(fileName.substring(index + 1)); 42 } 43 44 const String& File::name() const 45 { 46 return items().at(0)->toFileBlobItem()->name(); 42 47 } 43 48 -
trunk/WebCore/html/File.h
r57695 r60799 42 42 virtual bool isFile() const { return true; } 43 43 44 const String& name() const { return m_name; } 45 const String& type() const { return m_type; } 44 const String& name() const; 46 45 47 46 // FIXME: obsolete attributes. To be removed. 48 const String& fileName() const { return m_name; }47 const String& fileName() const { return name(); } 49 48 unsigned long long fileSize() const { return size(); } 50 49 51 50 private: 52 51 File(const String& path); 53 54 String m_name;55 String m_type;56 52 }; 57 53 -
trunk/WebCore/html/FileReader.cpp
r59797 r60799 86 86 void FileReader::readAsBinaryString(Blob* fileBlob) 87 87 { 88 // FIXME: needs to handle non-file blobs. 88 89 LOG(FileAPI, "FileReader: reading as binary: %s\n", fileBlob->path().utf8().data()); 89 90 … … 93 94 void FileReader::readAsText(Blob* fileBlob, const String& encoding) 94 95 { 96 // FIXME: needs to handle non-file blobs. 95 97 LOG(FileAPI, "FileReader: reading as text: %s\n", fileBlob->path().utf8().data()); 96 98 -
trunk/WebCore/html/FileStream.cpp
r60325 r60799 73 73 return; 74 74 75 // FIXME: Need to handle multiple items that may include non-file ones when BlobBuilder is introduced. 76 ASSERT(blob->items().size() >= 1); 77 const FileBlobItem* fileItem = blob->items().at(0)->toFileBlobItem(); 78 if (!fileItem) { 79 ASSERT(false); 80 m_client->didFail(NOT_READABLE_ERR); 81 return; 82 } 83 75 84 // Check if the file exists by querying its modification time. We choose not to call fileExists() in order to save an 76 85 // extra file system call when the modification time is needed to check the validity of the sliced file blob. … … 78 87 // openFile() could not tell use the failure reason. 79 88 time_t currentModificationTime; 80 if (!getFileModificationTime( blob->path(), currentModificationTime)) {89 if (!getFileModificationTime(fileItem->path(), currentModificationTime)) { 81 90 m_client->didFail(NOT_FOUND_ERR); 82 91 return; … … 84 93 85 94 // Open the file blob. 86 m_handle = openFile( blob->path(), OpenForRead);95 m_handle = openFile(fileItem->path(), OpenForRead); 87 96 if (!isHandleValid(m_handle)) { 88 97 m_client->didFail(NOT_READABLE_ERR); … … 91 100 92 101 #if ENABLE(BLOB_SLICE) 93 // Check the modificationt time for the possible file change. 94 if (blob->modificationTime() != Blob::doNotCheckFileChange && static_cast<time_t>(blob->modificationTime()) != currentModificationTime) { 95 m_client->didFail(NOT_READABLE_ERR); 96 return; 97 } 98 99 // Jump to the beginning position if the file has been sliced. 100 if (blob->start() > 0) { 101 if (!seekFile(m_handle, blob->start(), SeekFromBeginning)) { 102 const FileRangeBlobItem* fileRangeItem = fileItem->toFileRangeBlobItem(); 103 if (fileRangeItem) { 104 // Check the modificationt time for the possible file change. 105 if (static_cast<time_t>(fileRangeItem->snapshotModificationTime()) != currentModificationTime) { 102 106 m_client->didFail(NOT_READABLE_ERR); 103 107 return; 108 } 109 110 // Jump to the beginning position if the file has been sliced. 111 if (fileRangeItem->start() > 0) { 112 if (seekFile(m_handle, fileRangeItem->start(), SeekFromBeginning) < 0) { 113 m_client->didFail(NOT_READABLE_ERR); 114 return; 115 } 104 116 } 105 117 } … … 107 119 108 120 // Get the size. 109 #if ENABLE(BLOB_SLICE)110 m_totalBytesToRead = blob->length();111 if (m_totalBytesToRead == Blob::toEndOfFile)112 m_totalBytesToRead = blob->size() - blob->start();113 #else114 121 m_totalBytesToRead = blob->size(); 115 #endif116 117 122 m_client->didGetSize(m_totalBytesToRead); 118 123 } -
trunk/WebCore/html/FormDataList.cpp
r37589 r60799 29 29 } 30 30 31 void FormDataList::appendString(const String& s) 32 { 33 m_items.append(StringBlobItem::create(s, EndingCRLF, m_encoding)); 34 } 35 31 36 void FormDataList::appendString(const CString& s) 32 37 { 33 m_ list.append(s);38 m_items.append(StringBlobItem::create(s)); 34 39 } 35 40 36 // Change plain CR and plain LF to CRLF pairs. 37 static CString fixLineBreaks(const CString& s) 41 void FormDataList::appendBlob(const String& key, PassRefPtr<Blob> blob) 38 42 { 39 // Compute the length. 40 unsigned newLen = 0; 41 const char* p = s.data(); 42 while (char c = *p++) { 43 if (c == '\r') { 44 // Safe to look ahead because of trailing '\0'. 45 if (*p != '\n') { 46 // Turn CR into CRLF. 47 newLen += 2; 48 } 49 } else if (c == '\n') { 50 // Turn LF into CRLF. 51 newLen += 2; 52 } else { 53 // Leave other characters alone. 54 newLen += 1; 55 } 56 } 57 if (newLen == s.length()) { 58 return s; 59 } 60 61 // Make a copy of the string. 62 p = s.data(); 63 char* q; 64 CString result = CString::newUninitialized(newLen, q); 65 while (char c = *p++) { 66 if (c == '\r') { 67 // Safe to look ahead because of trailing '\0'. 68 if (*p != '\n') { 69 // Turn CR into CRLF. 70 *q++ = '\r'; 71 *q++ = '\n'; 72 } 73 } else if (c == '\n') { 74 // Turn LF into CRLF. 75 *q++ = '\r'; 76 *q++ = '\n'; 77 } else { 78 // Leave other characters alone. 79 *q++ = c; 80 } 81 } 82 return result; 83 } 84 85 void FormDataList::appendString(const String& s) 86 { 87 CString cstr = fixLineBreaks(m_encoding.encode(s.characters(), s.length(), EntitiesForUnencodables)); 88 m_list.append(cstr); 43 appendString(key); 44 const BlobItemList& items = blob->items(); 45 for (size_t i = 0; i < items.size(); ++i) 46 m_items.append(items.at(i)); 89 47 } 90 48 -
trunk/WebCore/html/FormDataList.h
r57726 r60799 47 47 appendString(String::number(value)); 48 48 } 49 void appendBlob(const String& key, PassRefPtr<Blob> blob) 50 { 51 appendString(key); 52 m_list.append(blob); 53 } 49 void appendBlob(const String& key, PassRefPtr<Blob>); 54 50 55 class Item { 56 public: 57 Item() { } 58 Item(const WTF::CString& data) : m_data(data) { } 59 Item(PassRefPtr<Blob> blob) : m_blob(blob) { } 60 61 const WTF::CString& data() const { return m_data; } 62 Blob* blob() const { return m_blob.get(); } 63 64 private: 65 WTF::CString m_data; 66 RefPtr<Blob> m_blob; 67 }; 68 69 const Vector<Item>& list() const { return m_list; } 51 const BlobItemList& items() const { return m_items; } 70 52 const TextEncoding& encoding() const { return m_encoding; } 71 53 … … 75 57 76 58 TextEncoding m_encoding; 77 Vector<Item> m_list;59 BlobItemList m_items; 78 60 }; 79 61 -
trunk/WebCore/html/HTMLFormElement.cpp
r60418 r60799 210 210 } 211 211 212 RefPtr<FormData> result = (m_formDataBuilder.isMultiPartForm()) ? FormData::createMultiPart( *domFormData, document()) : FormData::create(*domFormData);212 RefPtr<FormData> result = (m_formDataBuilder.isMultiPartForm()) ? FormData::createMultiPart(domFormData->items(), domFormData->encoding(), document()) : FormData::create(domFormData->items(), domFormData->encoding()); 213 213 214 214 result->setIdentifier(generateFormDataIdentifier()); -
trunk/WebCore/html/HTMLMeterElement.cpp
r59773 r60799 25 25 #include "Attribute.h" 26 26 #include "EventNames.h" 27 #include "ExceptionCode.h" 27 28 #include "FormDataList.h" 28 29 #include "HTMLFormElement.h" -
trunk/WebCore/html/HTMLProgressElement.cpp
r59773 r60799 25 25 #include "Attribute.h" 26 26 #include "EventNames.h" 27 #include "ExceptionCode.h" 27 28 #include "FormDataList.h" 28 29 #include "HTMLFormElement.h" -
trunk/WebCore/platform/network/FormData.cpp
r58336 r60799 20 20 21 21 #include "config.h" 22 22 23 #include "FormData.h" 23 24 24 #include "Blob .h"25 #include "BlobItem.h" 25 26 #include "Chrome.h" 26 27 #include "ChromeClient.h" 27 #include "DOMFormData.h"28 28 #include "Document.h" 29 #include "File.h"30 29 #include "FileSystem.h" 31 30 #include "FormDataBuilder.h" … … 33 32 #include "Page.h" 34 33 #include "TextEncoding.h" 35 #include "UUID.h"36 34 37 35 namespace WebCore { 36 37 #if ENABLE(BLOB_SLICE) 38 const long long FormDataElement::toEndOfFile = -1; 39 const double FormDataElement::doNotCheckFileChange = 0; 40 #endif 38 41 39 42 inline FormData::FormData() … … 97 100 } 98 101 99 PassRefPtr<FormData> FormData::create(const DOMFormData& domFormData)100 { 101 RefPtr<FormData> result = create(); 102 result->append DOMFormData(domFormData, false, 0);103 return result.release(); 104 } 105 106 PassRefPtr<FormData> FormData::createMultiPart(const DOMFormData& domFormData, Document* document)107 { 108 RefPtr<FormData> result = create(); 109 result->append DOMFormData(domFormData, true, document);102 PassRefPtr<FormData> FormData::create(const BlobItemList& items, const TextEncoding& encoding) 103 { 104 RefPtr<FormData> result = create(); 105 result->appendKeyValuePairItems(items, encoding, false, 0); 106 return result.release(); 107 } 108 109 PassRefPtr<FormData> FormData::createMultiPart(const BlobItemList& items, const TextEncoding& encoding, Document* document) 110 { 111 RefPtr<FormData> result = create(); 112 result->appendKeyValuePairItems(items, encoding, true, document); 110 113 return result.release(); 111 114 } … … 155 158 { 156 159 #if ENABLE(BLOB_SLICE) 157 m_elements.append(FormDataElement(filename, 0, Blob::toEndOfFile, Blob::doNotCheckFileChange, shouldGenerateFile));160 m_elements.append(FormDataElement(filename, 0, FormDataElement::toEndOfFile, FormDataElement::doNotCheckFileChange, shouldGenerateFile)); 158 161 #else 159 162 m_elements.append(FormDataElement(filename, shouldGenerateFile)); … … 161 164 } 162 165 166 void FormData::appendItems(const BlobItemList& items) 167 { 168 for (BlobItemList::const_iterator iter(items.begin()); iter != items.end(); ++iter) 169 appendItem(iter->get(), false); 170 } 171 172 void FormData::appendItem(const BlobItem* item, bool shouldGenerateFile) 173 { 174 const DataBlobItem* dataItem = item->toDataBlobItem(); 175 if (dataItem) { 176 appendData(dataItem->data(), static_cast<size_t>(dataItem->size())); 177 return; 178 } 179 180 const FileBlobItem* fileItem = item->toFileBlobItem(); 181 ASSERT(fileItem); 182 if (fileItem->path().isEmpty()) { 183 // If the path is empty do not add the item. 184 return; 185 } 186 187 #if ENABLE(BLOB_SLICE) 188 const FileRangeBlobItem* fileRangeItem = item->toFileRangeBlobItem(); 189 if (fileRangeItem) { 190 appendFileRange(fileItem->path(), fileRangeItem->start(), fileRangeItem->size(), fileRangeItem->snapshotModificationTime(), shouldGenerateFile); 191 return; 192 } 193 #endif 194 195 appendFile(fileItem->path(), shouldGenerateFile); 196 } 197 163 198 #if ENABLE(BLOB_SLICE) 164 199 void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile) … … 168 203 #endif 169 204 170 void FormData::append DOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document)205 void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEncoding& encoding, bool isMultiPartForm, Document* document) 171 206 { 172 207 FormDataBuilder formDataBuilder; … … 175 210 176 211 Vector<char> encodedData; 177 TextEncoding encoding = domFormData.encoding(); 178 179 const Vector<FormDataList::Item>& list = domFormData.list(); 180 size_t formDataListSize = list.size(); 212 213 size_t formDataListSize = items.size(); 181 214 ASSERT(!(formDataListSize % 2)); 182 215 for (size_t i = 0; i < formDataListSize; i += 2) { 183 const FormDataList::Item& key = list[i]; 184 const FormDataList::Item& value = list[i + 1]; 216 const StringBlobItem* key = items[i]->toStringBlobItem(); 217 const BlobItem* value = items[i + 1].get(); 218 ASSERT(key); 185 219 if (isMultiPartForm) { 186 220 Vector<char> header; 187 formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key .data());221 formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key->cstr()); 188 222 189 223 bool shouldGenerateFile = false; 190 224 // If the current type is FILE, then we also need to include the filename 191 if (value.blob()) { 192 const String& path = value.blob()->path(); 193 #if ENABLE(BLOB_SLICE) 194 String fileName; 195 if (value.blob()->isFile()) 196 fileName = static_cast<File*>(value.blob())->fileName(); 197 else { 198 // If a blob is sliced from a file, it does not have the filename. In this case, let's produce a unique filename. 199 fileName = "Blob" + createCanonicalUUIDString(); 200 fileName.replace("-", ""); // For safty, remove '-' from the filename snce some servers may not like it. 201 } 202 #else 203 ASSERT(value.blob()->isFile()); 204 String fileName = static_cast<File*>(value.blob())->fileName(); 205 #endif 225 const FileBlobItem* fileItem = value->toFileBlobItem(); 226 if (fileItem) { 227 const String& path = fileItem->path(); 228 String fileName = fileItem->name(); 206 229 207 230 // Let the application specify a filename if it's going to generate a replacement file for the upload. … … 218 241 formDataBuilder.addFilenameToMultiPartHeader(header, encoding, fileName); 219 242 220 // If a blob is sliced from a file, do not add the content type.221 #if ENABLE(BLOB_SLICE) 222 if (!fileName.isEmpty() && value.blob()->isFile()) {243 // If the item is sliced from a file, do not add the content type. 244 #if ENABLE(BLOB_SLICE) 245 if (!fileName.isEmpty() && !value->toFileRangeBlobItem()) { 223 246 #else 224 247 if (!fileName.isEmpty()) { … … 238 261 // Append body 239 262 appendData(header.data(), header.size()); 240 if (size_t dataSize = value.data().length()) 241 appendData(value.data().data(), dataSize); 242 else if (value.blob() && !value.blob()->path().isEmpty()) 243 #if ENABLE(BLOB_SLICE) 244 appendFileRange(value.blob()->path(), value.blob()->start(), value.blob()->length(), value.blob()->modificationTime(), shouldGenerateFile); 245 #else 246 appendFile(value.blob()->path(), shouldGenerateFile); 247 #endif 248 263 appendItem(value, shouldGenerateFile); 249 264 appendData("\r\n", 2); 250 265 } else { 251 266 // Omit the name "isindex" if it's the first form data element. 252 267 // FIXME: Why is this a good rule? Is this obsolete now? 253 if (encodedData.isEmpty() && key.data() == "isindex") 254 FormDataBuilder::encodeStringAsFormData(encodedData, value.data()); 268 const StringBlobItem* stringValue = value->toStringBlobItem(); 269 if (!stringValue) 270 continue; 271 if (encodedData.isEmpty() && key->cstr() == "isindex") 272 FormDataBuilder::encodeStringAsFormData(encodedData, stringValue->cstr()); 255 273 else 256 formDataBuilder.addKeyValuePairAsFormData(encodedData, key .data(), value.data());257 } 258 } 274 formDataBuilder.addKeyValuePairAsFormData(encodedData, key->cstr(), stringValue->cstr()); 275 } 276 } 259 277 260 278 if (isMultiPartForm) … … 271 289 for (size_t i = 0; i < n; ++i) { 272 290 const FormDataElement& e = m_elements[i]; 273 if (e.m_type == FormDataElement::data) { 274 size_t oldSize = data.size(); 275 size_t delta = e.m_data.size(); 276 data.grow(oldSize + delta); 277 memcpy(data.data() + oldSize, e.m_data.data(), delta); 278 } 291 if (e.m_type == FormDataElement::data) 292 data.append(e.m_data.data(), static_cast<size_t>(e.m_data.size())); 279 293 } 280 294 } … … 290 304 { 291 305 ASSERT(!m_hasGeneratedFiles); 292 306 293 307 if (m_hasGeneratedFiles) 294 308 return; 295 309 296 310 Page* page = document->page(); 297 311 if (!page) … … 313 327 if (!m_hasGeneratedFiles) 314 328 return; 315 329 316 330 size_t n = m_elements.size(); 317 331 for (size_t i = 0; i < n; ++i) { -
trunk/WebCore/platform/network/FormData.h
r58336 r60799 27 27 namespace WebCore { 28 28 29 class DOMFormData;29 class BlobItem; 30 30 class Document; 31 class TextEncoding; 32 typedef Vector<RefPtr<BlobItem> > BlobItemList; 31 33 32 34 class FormDataElement { … … 34 36 FormDataElement() : m_type(data) { } 35 37 FormDataElement(const Vector<char>& array) : m_type(data), m_data(array) { } 38 36 39 #if ENABLE(BLOB_SLICE) 37 40 FormDataElement(const String& filename, long long fileStart, long long fileLength, double expectedFileModificationTime, bool shouldGenerateFile) : m_type(encodedFile), m_filename(filename), m_fileStart(fileStart), m_fileLength(fileLength), m_expectedFileModificationTime(expectedFileModificationTime), m_shouldGenerateFile(shouldGenerateFile) { } … … 50 53 String m_generatedFilename; 51 54 bool m_shouldGenerateFile; 55 56 #if ENABLE(BLOB_SLICE) 57 static const long long toEndOfFile; 58 static const double doNotCheckFileChange; 59 #endif 52 60 }; 53 61 … … 56 64 if (&a == &b) 57 65 return true; 58 66 59 67 if (a.m_type != b.m_type) 60 68 return false; … … 70 78 return true; 71 79 } 72 80 73 81 inline bool operator!=(const FormDataElement& a, const FormDataElement& b) 74 82 { 75 83 return !(a == b); 76 84 } 77 85 78 86 class FormData : public RefCounted<FormData> { 79 87 public: … … 82 90 static PassRefPtr<FormData> create(const WTF::CString&); 83 91 static PassRefPtr<FormData> create(const Vector<char>&); 84 static PassRefPtr<FormData> create(const DOMFormData&);85 static PassRefPtr<FormData> createMultiPart(const DOMFormData&, Document*);92 static PassRefPtr<FormData> create(const BlobItemList&, const TextEncoding&); 93 static PassRefPtr<FormData> createMultiPart(const BlobItemList&, const TextEncoding&, Document*); 86 94 PassRefPtr<FormData> copy() const; 87 95 PassRefPtr<FormData> deepCopy() const; 88 96 ~FormData(); 89 97 90 98 void appendData(const void* data, size_t); 99 void appendItems(const BlobItemList&); 91 100 void appendFile(const String& filename, bool shouldGenerateFile = false); 92 101 #if ENABLE(BLOB_SLICE) … … 116 125 FormData(const FormData&); 117 126 118 void appendDOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document); 127 void appendItem(const BlobItem*, bool shouldGenerateFile); 128 void appendKeyValuePairItems(const BlobItemList&, const TextEncoding&, bool isMultiPartForm, Document*); 119 129 120 130 Vector<FormDataElement> m_elements; 131 121 132 int64_t m_identifier; 122 133 bool m_hasGeneratedFiles; … … 132 143 inline bool operator!=(const FormData& a, const FormData& b) 133 144 { 134 return a.elements() != b.elements();145 return !(a == b); 135 146 } 136 147 -
trunk/WebCore/platform/network/mac/FormDataStreamMac.mm
r57695 r60799 32 32 #import "FormDataStreamMac.h" 33 33 34 #import "Blob.h"35 34 #import "FileSystem.h" 36 35 #import "FormData.h" … … 143 142 form->currentStream = NULL; 144 143 #if ENABLE(BLOB_SLICE) 145 form->currentStreamRangeLength = Blob::toEndOfFile;144 form->currentStreamRangeLength = FormDataElement::toEndOfFile; 146 145 #endif 147 146 } … … 152 151 } 153 152 154 // Return false if we cannot advance the stream. Currently the only possible failure is that the underlying file has been changed since File.slice.153 // Return false if we cannot advance the stream. Currently the only possible failure is that the underlying file has been removed or changed since File.slice. 155 154 static bool advanceCurrentStream(FormStreamFields* form) 156 155 { … … 162 161 // Create the new stream. 163 162 FormDataElement& nextInput = form->remainingElements.last(); 163 164 164 if (nextInput.m_type == FormDataElement::data) { 165 165 size_t size = nextInput.m_data.size(); … … 170 170 #if ENABLE(BLOB_SLICE) 171 171 // Check if the file has been changed or not if required. 172 if (nextInput.m_expectedFileModificationTime != Blob::doNotCheckFileChange) {172 if (nextInput.m_expectedFileModificationTime != FormDataElement::doNotCheckFileChange) { 173 173 time_t fileModificationTime; 174 174 if (!getFileModificationTime(nextInput.m_filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModificationTime)) … … 176 176 } 177 177 #endif 178 179 178 const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename; 180 179 RetainPtr<CFStringRef> filename(AdoptCF, path.createCFString()); 181 180 RetainPtr<CFURLRef> fileURL(AdoptCF, CFURLCreateWithFileSystemPath(0, filename.get(), kCFURLPOSIXPathStyle, FALSE)); 182 181 form->currentStream = CFReadStreamCreateWithFile(0, fileURL.get()); 182 if (!form->currentStream) { 183 // The file must have been removed or become unreadable. 184 return false; 185 } 183 186 #if ENABLE(BLOB_SLICE) 184 187 if (nextInput.m_fileStart > 0) { … … 223 226 newInfo->currentStream = NULL; 224 227 #if ENABLE(BLOB_SLICE) 225 newInfo->currentStreamRangeLength = Blob::toEndOfFile;228 newInfo->currentStreamRangeLength = FormDataElement::toEndOfFile; 226 229 #endif 227 230 newInfo->currentData = 0; … … 271 274 CFIndex bytesToRead = bufferLength; 272 275 #if ENABLE(BLOB_SLICE) 273 if (form->currentStreamRangeLength != Blob::toEndOfFile && form->currentStreamRangeLength < bytesToRead)276 if (form->currentStreamRangeLength != FormDataElement::toEndOfFile && form->currentStreamRangeLength < bytesToRead) 274 277 bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength); 275 278 #endif … … 284 287 form->bytesSent += bytesRead; 285 288 #if ENABLE(BLOB_SLICE) 286 if (form->currentStreamRangeLength != Blob::toEndOfFile)289 if (form->currentStreamRangeLength != FormDataElement::toEndOfFile) 287 290 form->currentStreamRangeLength -= bytesRead; 288 291 #endif … … 401 404 #if ENABLE(BLOB_SLICE) 402 405 // If we're sending the file range, use the existing range length for now. We will detect if the file has been changed right before we read the file and abort the operation if necessary. 403 if (element.m_fileLength != Blob::toEndOfFile) {406 if (element.m_fileLength != FormDataElement::toEndOfFile) { 404 407 length += element.m_fileLength; 405 408 continue; -
trunk/WebCore/xml/XMLHttpRequest.cpp
r58841 r60799 479 479 // FIXME: add support for uploading bundles. 480 480 m_requestEntityBody = FormData::create(); 481 #if ENABLE(BLOB_SLICE) 482 m_requestEntityBody->appendFileRange(body->path(), body->start(), body->length(), body->modificationTime()); 483 #else 484 m_requestEntityBody->appendFile(body->path(), false); 485 #endif 481 m_requestEntityBody->appendItems(body->items()); 486 482 } 487 483 … … 495 491 496 492 if (m_method != "GET" && m_method != "HEAD" && m_url.protocolInHTTPFamily()) { 497 m_requestEntityBody = FormData::createMultiPart( *body, document());493 m_requestEntityBody = FormData::createMultiPart(body->items(), body->encoding(), document()); 498 494 499 495 // We need to ask the client to provide the generated file names if needed. When FormData fills the element -
trunk/WebKit/chromium/ChangeLog
r60776 r60799 1 2010-06-07 Kinuko Yasuda <kinuko@chromium.org> 2 3 Reviewed by Jian Li. 4 5 Refactor FormData and Blob for better support of Blobs synthesized by BlobBuilder. 6 https://bugs.webkit.org/show_bug.cgi?id=39083 7 8 Replace FormDataList::Item list with BlobItemList to get it compiled 9 with the refactoring in FormDataList. 10 11 * src/WebSearchableFormData.cpp: 12 (WebCore::HasSuitableTextElement): 13 1 14 2010-06-07 Andrei Popescu <andreip@google.com> 2 15 -
trunk/WebKit/chromium/src/WebSearchableFormData.cpp
r60420 r60799 188 188 continue; 189 189 190 const Vector<FormDataList::Item>& itemList = dataList.list();191 if (isTextElement && !item List.isEmpty()) {190 const BlobItemList& items = dataList.items(); 191 if (isTextElement && !items.isEmpty()) { 192 192 if (textElement) { 193 193 // The auto-complete bar only knows how to fill in one value. … … 197 197 textElement = static_cast<HTMLInputElement*>(formElement); 198 198 } 199 for (Vector<FormDataList::Item>::const_iterator j(itemList.begin()); j != itemList.end(); ++j) { 199 for (BlobItemList::const_iterator j(items.begin()); j != items.end(); ++j) { 200 const StringBlobItem* item = (*j)->toStringBlobItem(); 201 ASSERT(item); 200 202 // Handle ISINDEX / <input name=isindex> specially, but only if it's 201 203 // the first entry. 202 if (!encodedString->isEmpty() || j->data() != "isindex") {204 if (!encodedString->isEmpty() || item->cstr() != "isindex") { 203 205 if (!encodedString->isEmpty()) 204 206 encodedString->append('&'); 205 FormDataBuilder::encodeStringAsFormData(*encodedString, j->data());207 FormDataBuilder::encodeStringAsFormData(*encodedString, item->cstr()); 206 208 encodedString->append('='); 207 209 } … … 210 212 encodedString->append("{searchTerms}", 13); 211 213 else 212 FormDataBuilder::encodeStringAsFormData(*encodedString, j->data());214 FormDataBuilder::encodeStringAsFormData(*encodedString, item->cstr()); 213 215 } 214 216 }
Note: See TracChangeset
for help on using the changeset viewer.