Changeset 60799 in webkit


Ignore:
Timestamp:
Jun 7, 2010 1:55:00 PM (14 years ago)
Author:
kinuko@chromium.org
Message:

2010-06-07 Kinuko Yasuda <kinuko@chromium.org>

Reviewed by Jian Li.

Refactor FormData and Blob for better support of Blobs synthesized by BlobBuilder.
https://bugs.webkit.org/show_bug.cgi?id=39083

Replace FormDataList::Item list with BlobItemList to get it compiled
with the refactoring in FormDataList.

  • src/WebSearchableFormData.cpp: (WebCore::HasSuitableTextElement):

2010-06-07 Kinuko Yasuda <kinuko@chromium.org>

Reviewed by Jian Li.

Refactor FormData and Blob for better support of Blobs synthesized by BlobBuilder.
https://bugs.webkit.org/show_bug.cgi?id=39083

  • Introduces a new class BlobItem as a basic component of Blob and FormDataList.
  • File would become a special type of Blob that contains only one FileBlobItem.
  • Fix the dependency violation in FormData so that the files under platform/ do not include any html/ files.

The patch doesn't support the latest File API changes (e.g. type,
url and slice's type parameters) and should not change any of its
existing behaviors.

The existing tests should be able to be used for regression.

  • CMakeLists.txt:
  • GNUmakefile.am:
  • WebCore.gypi:
  • WebCore.pro:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • html/Blob.cpp: (WebCore::Blob::Blob): (WebCore::Blob::size): (WebCore::Blob::path): (WebCore::Blob::append): (WebCore::Blob::slice):
  • html/Blob.h: (WebCore::Blob::create): (WebCore::Blob::type): (WebCore::Blob::items): (WebCore::Blob::Blob):
  • html/File.cpp: (WebCore::File::File): (WebCore::File::name):
  • html/File.h: (WebCore::File::fileName):
  • html/FileReader.cpp: (WebCore::FileReader::readAsBinaryString): (WebCore::FileReader::readAsText):
  • html/FileStream.cpp: (WebCore::FileStream::openForRead):
  • html/FormDataList.cpp: (WebCore::FormDataList::appendString): Moved the line ending fix logic to StringBlobItem::convertToCString. (WebCore::FormDataList::appendBlob):
  • html/FormDataList.h: (WebCore::FormDataList::items):
  • html/HTMLFormElement.cpp: (WebCore::HTMLFormElement::createFormData):
  • html/HTMLProgressElement.cpp:
  • platform/BlobItem.cpp: Added.
  • platform/BlobItem.h: Added.
  • platform/network/FormData.cpp: (WebCore::FormDataElement::FormDataElement): (WebCore::FormData::create): (WebCore::FormData::createMultiPart): (WebCore::FormData::deepCopy): (WebCore::FormData::appendData): (WebCore::FormData::appendString): (WebCore::FormData::appendFile): (WebCore::FormData::appendFileRange): (WebCore::FormData::appendItems): (WebCore::FormData::appendItem): (WebCore::FormData::appendKeyValuePairItems):
  • platform/network/FormData.h: (WebCore::operator!=):
  • platform/network/mac/FormDataStreamMac.mm: (WebCore::closeCurrentStream): (WebCore::advanceCurrentStream): (WebCore::formCreate): (WebCore::formRead): (WebCore::setHTTPBody):
  • xml/XMLHttpRequest.cpp: (WebCore::XMLHttpRequest::send):
Location:
trunk
Files:
2 added
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/CMakeLists.txt

    r60776 r60799  
    11231123
    11241124    platform/Arena.cpp
     1125    platform/BlobItem.cpp
    11251126    platform/ContentType.cpp
    11261127    platform/ContextMenu.cpp
  • trunk/WebCore/ChangeLog

    r60798 r60799  
     12010-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
    1782010-06-07  Vangelis Kokkevis  <vangelis@chromium.org>
    279
  • trunk/WebCore/GNUmakefile.am

    r60793 r60799  
    15601560        WebCore/platform/Arena.h \
    15611561        WebCore/platform/AutodrainedPool.h \
     1562        WebCore/platform/BlobItem.cpp \
     1563        WebCore/platform/BlobItem.h \
    15621564        WebCore/platform/ContentType.cpp \
    15631565        WebCore/platform/ContentType.h \
  • trunk/WebCore/WebCore.gypi

    r60776 r60799  
    28812881            'platform/Arena.h',
    28822882            'platform/AutodrainedPool.h',
     2883            'platform/BlobItem.cpp',
     2884            'platform/BlobItem.h',
    28832885            'platform/ContentType.cpp',
    28842886            'platform/ContentType.h',
  • trunk/WebCore/WebCore.pro

    r60776 r60799  
    816816    platform/animation/AnimationList.cpp \
    817817    platform/Arena.cpp \
     818    platform/BlobItem.cpp \
    818819    platform/text/Base64.cpp \
    819820    platform/text/BidiContext.cpp \
     
    15651566    platform/animation/AnimationList.h \
    15661567    platform/Arena.h \
     1568    platform/BlobItem.h \
    15671569    platform/ContentType.h \
    15681570    platform/ContextMenu.h \
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r60776 r60799  
    2237022370                        </File>
    2237122371                        <File
     22372                                RelativePath="..\platform\BlobItem.cpp"
     22373                                >
     22374                        </File>
     22375                        <File
     22376                                RelativePath="..\platform\BlobItem.h"
     22377                                >
     22378                        </File>
     22379                        <File
    2237222380                                RelativePath="..\platform\ContentType.cpp"
    2237322381                                >
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r60776 r60799  
    22812281                895253DF116C4F0600CABF00 /* FileThreadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 895253DE116C4F0600CABF00 /* FileThreadTask.h */; };
    22822282                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, ); }; };
    22832285                9302B0BD0D79F82900C7EE83 /* PageGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */; };
    22842286                9302B0BF0D79F82C00C7EE83 /* PageGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 9302B0BE0D79F82C00C7EE83 /* PageGroup.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    78897891                8F934D831189F1EE00508D5D /* JSMainThreadExecState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMainThreadExecState.h; sourceTree = "<group>"; };
    78907892                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>"; };
    78917895                9302B0BC0D79F82900C7EE83 /* PageGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageGroup.cpp; sourceTree = "<group>"; };
    78927896                9302B0BE0D79F82C00C7EE83 /* PageGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageGroup.h; sourceTree = "<group>"; };
     
    1586315867                                BCFB2F75097A2E1A00BA703D /* Arena.h */,
    1586415868                                51E1ECB10C91C55600DC255B /* AutodrainedPool.h */,
     15869                                8988E10C11A3508B00DB732E /* BlobItem.cpp */,
     15870                                8988E10D11A3508B00DB732E /* BlobItem.h */,
    1586515871                                BCC8CFCA0986CD2400140BF2 /* ColorData.gperf */,
    1586615872                                41D015C90F4B5C71004A662F /* ContentType.cpp */,
     
    1690016906                                A89943280B42338800D7C802 /* BitmapImage.h in Headers */,
    1690116907                                2EAFAF0F10E2AF2D007ED3D6 /* Blob.h in Headers */,
     16908                                8988E10F11A3508B00DB732E /* BlobItem.h in Headers */,
    1690216909                                93F199BE08245E59001E9ABC /* BlockExceptions.h in Headers */,
    1690316910                                BC5EB5E10E81BE8700B25965 /* BorderData.h in Headers */,
     
    1973319740                                A89943290B42338800D7C802 /* BitmapImage.cpp in Sources */,
    1973419741                                2EAFAF0E10E2AF2D007ED3D6 /* Blob.cpp in Sources */,
     19742                                8988E10E11A3508B00DB732E /* BlobItem.cpp in Sources */,
    1973519743                                93F19AE108245E59001E9ABC /* BlockExceptions.mm in Sources */,
    1973619744                                BCEA4854097D93020094C9E4 /* break_lines.cpp in Sources */,
  • trunk/WebCore/html/Blob.cpp

    r55676 r60799  
    3232#include "Blob.h"
    3333
     34#include "BlobItem.h"
    3435#include "FileSystem.h"
    3536
    3637namespace WebCore {
    3738
    38 #if ENABLE(BLOB_SLICE)
    39 const int Blob::toEndOfFile = -1;
    40 const double Blob::doNotCheckFileChange = 0;
    41 #endif
    42 
    4339Blob::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 #endif
    5240{
     41    // Note: this doesn't initialize the type unlike File(path).
     42    append(FileBlobItem::create(path));
    5343}
    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 #endif
    6744
    6845unsigned long long Blob::size() const
     
    7047    // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to
    7148    // 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
     55const String& Blob::path() const
     56{
     57    ASSERT(m_items.size() == 1 && m_items[0]->toFileBlobItem());
     58    return m_items[0]->toFileBlobItem()->path();
     59}
     60
     61void Blob::append(PassRefPtr<BlobItem> item)
     62{
     63    m_items.append(item);
    8064}
    8165
     
    8367PassRefPtr<Blob> Blob::slice(long long start, long long length) const
    8468{
    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         } else
    99             snapshotModificationTime = modificationTime;
    100     }
    101 
    102     // Clamp the range if it exceeds the size limit.
    10369    if (start < 0)
    10470        start = 0;
     
    10672        length = 0;
    10773
    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) {
    10977        start = 0;
    11078        length = 0;
    111     } else if (start + length > snapshotSize)
    112         length = snapshotSize - start;
     79    } else if (static_cast<unsigned long long>(start + length) > totalSize)
     80        length = totalSize - start;
    11381
    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();
    11592}
    116 #endif
     93#endif // ENABLE(BLOB_SLICE)
    11794
    11895} // namespace WebCore
  • trunk/WebCore/html/Blob.h

    r57695 r60799  
    3232#define Blob_h
    3333
    34 #include "ExceptionCode.h"
     34#include "BlobItem.h"
    3535#include "PlatformString.h"
    36 #include <time.h>
    3736#include <wtf/PassRefPtr.h>
    3837#include <wtf/RefCounted.h>
     38#include <wtf/Vector.h>
    3939
    4040namespace WebCore {
     
    4242class Blob : public RefCounted<Blob> {
    4343public:
    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    }
    4848
     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.
    4952    static PassRefPtr<Blob> create(const String& path)
    5053    {
     
    5457    virtual ~Blob() { }
    5558
     59    unsigned long long size() const;
     60    const String& type() const { return m_type; }
    5661    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; }
    5768
    5869#if ENABLE(BLOB_SLICE)
     
    6071#endif
    6172
    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
     73protected:
     74    Blob() { }
    6975
    70 protected:
     76    // FIXME: Deprecated constructor.  See also the comment for Blob::create(path).
    7177    Blob(const String& path);
    7278
    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;
    9781};
    9882
  • trunk/WebCore/html/File.cpp

    r55257 r60799  
    3434File::File(const String& path)
    3535    : Blob(path)
    36     , m_name(pathGetFileName(path))
    3736{
    3837    // 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('.');
    4040    if (index != -1)
    41         m_type = MIMETypeRegistry::getMIMETypeForExtension(m_name.substring(index + 1));
     41        m_type = MIMETypeRegistry::getMIMETypeForExtension(fileName.substring(index + 1));
     42}
     43
     44const String& File::name() const
     45{
     46    return items().at(0)->toFileBlobItem()->name();
    4247}
    4348
  • trunk/WebCore/html/File.h

    r57695 r60799  
    4242    virtual bool isFile() const { return true; }
    4343
    44     const String& name() const { return m_name; }
    45     const String& type() const { return m_type; }
     44    const String& name() const;
    4645
    4746    // FIXME: obsolete attributes. To be removed.
    48     const String& fileName() const { return m_name; }
     47    const String& fileName() const { return name(); }
    4948    unsigned long long fileSize() const { return size(); }
    5049
    5150private:
    5251    File(const String& path);
    53 
    54     String m_name;
    55     String m_type;
    5652};
    5753
  • trunk/WebCore/html/FileReader.cpp

    r59797 r60799  
    8686void FileReader::readAsBinaryString(Blob* fileBlob)
    8787{
     88    // FIXME: needs to handle non-file blobs.
    8889    LOG(FileAPI, "FileReader: reading as binary: %s\n", fileBlob->path().utf8().data());
    8990
     
    9394void FileReader::readAsText(Blob* fileBlob, const String& encoding)
    9495{
     96    // FIXME: needs to handle non-file blobs.
    9597    LOG(FileAPI, "FileReader: reading as text: %s\n", fileBlob->path().utf8().data());
    9698
  • trunk/WebCore/html/FileStream.cpp

    r60325 r60799  
    7373        return;
    7474
     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
    7584    // Check if the file exists by querying its modification time. We choose not to call fileExists() in order to save an
    7685    // extra file system call when the modification time is needed to check the validity of the sliced file blob.
     
    7887    // openFile() could not tell use the failure reason.
    7988    time_t currentModificationTime;
    80     if (!getFileModificationTime(blob->path(), currentModificationTime)) {
     89    if (!getFileModificationTime(fileItem->path(), currentModificationTime)) {
    8190        m_client->didFail(NOT_FOUND_ERR);
    8291        return;
     
    8493
    8594    // Open the file blob.
    86     m_handle = openFile(blob->path(), OpenForRead);
     95    m_handle = openFile(fileItem->path(), OpenForRead);
    8796    if (!isHandleValid(m_handle)) {
    8897        m_client->didFail(NOT_READABLE_ERR);
     
    91100
    92101#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) {
    102106            m_client->didFail(NOT_READABLE_ERR);
    103107            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            }
    104116        }
    105117    }
     
    107119
    108120    // 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 #else
    114121    m_totalBytesToRead = blob->size();
    115 #endif
    116 
    117122    m_client->didGetSize(m_totalBytesToRead);
    118123}
  • trunk/WebCore/html/FormDataList.cpp

    r37589 r60799  
    2929}
    3030
     31void FormDataList::appendString(const String& s)
     32{
     33    m_items.append(StringBlobItem::create(s, EndingCRLF, m_encoding));
     34}
     35
    3136void FormDataList::appendString(const CString& s)
    3237{
    33     m_list.append(s);
     38    m_items.append(StringBlobItem::create(s));
    3439}
    3540
    36 // Change plain CR and plain LF to CRLF pairs.
    37 static CString fixLineBreaks(const CString& s)
     41void FormDataList::appendBlob(const String& key, PassRefPtr<Blob> blob)
    3842{
    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));
    8947}
    9048
  • trunk/WebCore/html/FormDataList.h

    r57726 r60799  
    4747        appendString(String::number(value));
    4848    }
    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>);
    5450
    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; }
    7052    const TextEncoding& encoding() const { return m_encoding; }
    7153
     
    7557
    7658    TextEncoding m_encoding;
    77     Vector<Item> m_list;
     59    BlobItemList m_items;
    7860};
    7961
  • trunk/WebCore/html/HTMLFormElement.cpp

    r60418 r60799  
    210210    }
    211211
    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());
    213213
    214214    result->setIdentifier(generateFormDataIdentifier());
  • trunk/WebCore/html/HTMLMeterElement.cpp

    r59773 r60799  
    2525#include "Attribute.h"
    2626#include "EventNames.h"
     27#include "ExceptionCode.h"
    2728#include "FormDataList.h"
    2829#include "HTMLFormElement.h"
  • trunk/WebCore/html/HTMLProgressElement.cpp

    r59773 r60799  
    2525#include "Attribute.h"
    2626#include "EventNames.h"
     27#include "ExceptionCode.h"
    2728#include "FormDataList.h"
    2829#include "HTMLFormElement.h"
  • trunk/WebCore/platform/network/FormData.cpp

    r58336 r60799  
    2020
    2121#include "config.h"
     22
    2223#include "FormData.h"
    2324
    24 #include "Blob.h"
     25#include "BlobItem.h"
    2526#include "Chrome.h"
    2627#include "ChromeClient.h"
    27 #include "DOMFormData.h"
    2828#include "Document.h"
    29 #include "File.h"
    3029#include "FileSystem.h"
    3130#include "FormDataBuilder.h"
     
    3332#include "Page.h"
    3433#include "TextEncoding.h"
    35 #include "UUID.h"
    3634
    3735namespace WebCore {
     36
     37#if ENABLE(BLOB_SLICE)
     38const long long FormDataElement::toEndOfFile = -1;
     39const double FormDataElement::doNotCheckFileChange = 0;
     40#endif
    3841
    3942inline FormData::FormData()
     
    97100}
    98101
    99 PassRefPtr<FormData> FormData::create(const DOMFormData& domFormData)
    100 {
    101     RefPtr<FormData> result = create();
    102     result->appendDOMFormData(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->appendDOMFormData(domFormData, true, document);
     102PassRefPtr<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
     109PassRefPtr<FormData> FormData::createMultiPart(const BlobItemList& items, const TextEncoding& encoding, Document* document)
     110{
     111    RefPtr<FormData> result = create();
     112    result->appendKeyValuePairItems(items, encoding, true, document);
    110113    return result.release();
    111114}
     
    155158{
    156159#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));
    158161#else
    159162    m_elements.append(FormDataElement(filename, shouldGenerateFile));
     
    161164}
    162165
     166void 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
     172void 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
    163198#if ENABLE(BLOB_SLICE)
    164199void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile)
     
    168203#endif
    169204
    170 void FormData::appendDOMFormData(const DOMFormData& domFormData, bool isMultiPartForm, Document* document)
     205void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
    171206{
    172207    FormDataBuilder formDataBuilder;
     
    175210
    176211    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();
    181214    ASSERT(!(formDataListSize % 2));
    182215    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);
    185219        if (isMultiPartForm) {
    186220            Vector<char> header;
    187             formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key.data());
     221            formDataBuilder.beginMultiPartHeader(header, m_boundary.data(), key->cstr());
    188222
    189223            bool shouldGenerateFile = false;
    190224            // 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();
    206229
    207230                // Let the application specify a filename if it's going to generate a replacement file for the upload.
     
    218241                formDataBuilder.addFilenameToMultiPartHeader(header, encoding, fileName);
    219242
    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()) {
    223246#else
    224247                if (!fileName.isEmpty()) {
     
    238261            // Append body
    239262            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);
    249264            appendData("\r\n", 2);
    250265        } else {
    251266            // Omit the name "isindex" if it's the first form data element.
    252267            // 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());
    255273            else
    256                 formDataBuilder.addKeyValuePairAsFormData(encodedData, key.data(), value.data());
    257         }
    258     } 
     274                formDataBuilder.addKeyValuePairAsFormData(encodedData, key->cstr(), stringValue->cstr());
     275        }
     276    }
    259277
    260278    if (isMultiPartForm)
     
    271289    for (size_t i = 0; i < n; ++i) {
    272290        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()));
    279293    }
    280294}
     
    290304{
    291305    ASSERT(!m_hasGeneratedFiles);
    292    
     306
    293307    if (m_hasGeneratedFiles)
    294308        return;
    295    
     309
    296310    Page* page = document->page();
    297311    if (!page)
     
    313327    if (!m_hasGeneratedFiles)
    314328        return;
    315        
     329
    316330    size_t n = m_elements.size();
    317331    for (size_t i = 0; i < n; ++i) {
  • trunk/WebCore/platform/network/FormData.h

    r58336 r60799  
    2727namespace WebCore {
    2828
    29 class DOMFormData;
     29class BlobItem;
    3030class Document;
     31class TextEncoding;
     32typedef Vector<RefPtr<BlobItem> > BlobItemList;
    3133
    3234class FormDataElement {
     
    3436    FormDataElement() : m_type(data) { }
    3537    FormDataElement(const Vector<char>& array) : m_type(data), m_data(array) { }
     38
    3639#if ENABLE(BLOB_SLICE)
    3740    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) { }
     
    5053    String m_generatedFilename;
    5154    bool m_shouldGenerateFile;
     55
     56#if ENABLE(BLOB_SLICE)
     57    static const long long toEndOfFile;
     58    static const double doNotCheckFileChange;
     59#endif
    5260};
    5361
     
    5664    if (&a == &b)
    5765        return true;
    58    
     66
    5967    if (a.m_type != b.m_type)
    6068        return false;
     
    7078    return true;
    7179}
    72  
     80
    7381inline bool operator!=(const FormDataElement& a, const FormDataElement& b)
    7482{
    7583    return !(a == b);
    7684}
    77  
     85
    7886class FormData : public RefCounted<FormData> {
    7987public:
     
    8290    static PassRefPtr<FormData> create(const WTF::CString&);
    8391    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*);
    8694    PassRefPtr<FormData> copy() const;
    8795    PassRefPtr<FormData> deepCopy() const;
    8896    ~FormData();
    89    
     97
    9098    void appendData(const void* data, size_t);
     99    void appendItems(const BlobItemList&);
    91100    void appendFile(const String& filename, bool shouldGenerateFile = false);
    92101#if ENABLE(BLOB_SLICE)
     
    116125    FormData(const FormData&);
    117126
    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*);
    119129
    120130    Vector<FormDataElement> m_elements;
     131
    121132    int64_t m_identifier;
    122133    bool m_hasGeneratedFiles;
     
    132143inline bool operator!=(const FormData& a, const FormData& b)
    133144{
    134     return a.elements() != b.elements();
     145    return !(a == b);
    135146}
    136147
  • trunk/WebCore/platform/network/mac/FormDataStreamMac.mm

    r57695 r60799  
    3232#import "FormDataStreamMac.h"
    3333
    34 #import "Blob.h"
    3534#import "FileSystem.h"
    3635#import "FormData.h"
     
    143142        form->currentStream = NULL;
    144143#if ENABLE(BLOB_SLICE)
    145         form->currentStreamRangeLength = Blob::toEndOfFile;
     144        form->currentStreamRangeLength = FormDataElement::toEndOfFile;
    146145#endif
    147146    }
     
    152151}
    153152
    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.
    155154static bool advanceCurrentStream(FormStreamFields* form)
    156155{
     
    162161    // Create the new stream.
    163162    FormDataElement& nextInput = form->remainingElements.last();
     163
    164164    if (nextInput.m_type == FormDataElement::data) {
    165165        size_t size = nextInput.m_data.size();
     
    170170#if ENABLE(BLOB_SLICE)
    171171        // 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) {
    173173            time_t fileModificationTime;
    174174            if (!getFileModificationTime(nextInput.m_filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModificationTime))
     
    176176        }
    177177#endif
    178 
    179178        const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename;
    180179        RetainPtr<CFStringRef> filename(AdoptCF, path.createCFString());
    181180        RetainPtr<CFURLRef> fileURL(AdoptCF, CFURLCreateWithFileSystemPath(0, filename.get(), kCFURLPOSIXPathStyle, FALSE));
    182181        form->currentStream = CFReadStreamCreateWithFile(0, fileURL.get());
     182        if (!form->currentStream) {
     183            // The file must have been removed or become unreadable.
     184            return false;
     185        }
    183186#if ENABLE(BLOB_SLICE)
    184187        if (nextInput.m_fileStart > 0) {
     
    223226    newInfo->currentStream = NULL;
    224227#if ENABLE(BLOB_SLICE)
    225     newInfo->currentStreamRangeLength = Blob::toEndOfFile;
     228    newInfo->currentStreamRangeLength = FormDataElement::toEndOfFile;
    226229#endif
    227230    newInfo->currentData = 0;
     
    271274        CFIndex bytesToRead = bufferLength;
    272275#if ENABLE(BLOB_SLICE)
    273         if (form->currentStreamRangeLength != Blob::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
     276        if (form->currentStreamRangeLength != FormDataElement::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
    274277            bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength);
    275278#endif
     
    284287            form->bytesSent += bytesRead;
    285288#if ENABLE(BLOB_SLICE)
    286             if (form->currentStreamRangeLength != Blob::toEndOfFile)
     289            if (form->currentStreamRangeLength != FormDataElement::toEndOfFile)
    287290                form->currentStreamRangeLength -= bytesRead;
    288291#endif
     
    401404#if ENABLE(BLOB_SLICE)
    402405            // 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) {
    404407                length += element.m_fileLength;
    405408                continue;
  • trunk/WebCore/xml/XMLHttpRequest.cpp

    r58841 r60799  
    479479        // FIXME: add support for uploading bundles.
    480480        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());
    486482    }
    487483
     
    495491
    496492    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());
    498494
    499495        // 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  
     12010-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
    1142010-06-07  Andrei Popescu  <andreip@google.com>
    215
  • trunk/WebKit/chromium/src/WebSearchableFormData.cpp

    r60420 r60799  
    188188          continue;
    189189
    190       const Vector<FormDataList::Item>& itemList = dataList.list();
    191       if (isTextElement && !itemList.isEmpty()) {
     190      const BlobItemList& items = dataList.items();
     191      if (isTextElement && !items.isEmpty()) {
    192192          if (textElement) {
    193193              // The auto-complete bar only knows how to fill in one value.
     
    197197          textElement = static_cast<HTMLInputElement*>(formElement);
    198198      }
    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);
    200202          // Handle ISINDEX / <input name=isindex> specially, but only if it's
    201203          // the first entry.
    202           if (!encodedString->isEmpty() || j->data() != "isindex") {
     204          if (!encodedString->isEmpty() || item->cstr() != "isindex") {
    203205              if (!encodedString->isEmpty())
    204206                  encodedString->append('&');
    205               FormDataBuilder::encodeStringAsFormData(*encodedString, j->data());
     207              FormDataBuilder::encodeStringAsFormData(*encodedString, item->cstr());
    206208              encodedString->append('=');
    207209          }
     
    210212              encodedString->append("{searchTerms}", 13);
    211213          else
    212               FormDataBuilder::encodeStringAsFormData(*encodedString, j->data());
     214              FormDataBuilder::encodeStringAsFormData(*encodedString, item->cstr());
    213215      }
    214216    }
Note: See TracChangeset for help on using the changeset viewer.