1/*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "WebHTTPBody.h"
33
34#include "FormData.h"
35
36using namespace WebCore;
37
38namespace WebKit {
39
40class WebHTTPBodyPrivate : public FormData {
41};
42
43void WebHTTPBody::initialize()
44{
45    assign(static_cast<WebHTTPBodyPrivate*>(FormData::create().releaseRef()));
46}
47
48void WebHTTPBody::reset()
49{
50    assign(0);
51}
52
53void WebHTTPBody::assign(const WebHTTPBody& other)
54{
55    WebHTTPBodyPrivate* p = const_cast<WebHTTPBodyPrivate*>(other.m_private);
56    if (p)
57        p->ref();
58    assign(p);
59}
60
61size_t WebHTTPBody::elementCount() const
62{
63    ASSERT(!isNull());
64    return m_private->elements().size();
65}
66
67bool WebHTTPBody::elementAt(size_t index, Element& result) const
68{
69    ASSERT(!isNull());
70
71    if (index >= m_private->elements().size())
72        return false;
73
74    const FormDataElement& element = m_private->elements()[index];
75
76    result.data.reset();
77    result.filePath.reset();
78    result.fileStart = 0;
79    result.fileLength = 0;
80    result.modificationTime = 0.0;
81    result.blobURL = KURL();
82
83    switch (element.m_type) {
84    case FormDataElement::data:
85        result.type = Element::TypeData;
86        result.data.assign(element.m_data.data(), element.m_data.size());
87        break;
88    case FormDataElement::encodedFile:
89        result.type = Element::TypeFile;
90        result.filePath = element.m_filename;
91#if ENABLE(BLOB)
92        result.fileStart = element.m_fileStart;
93        result.fileLength = element.m_fileLength;
94        result.modificationTime = element.m_expectedFileModificationTime;
95#endif
96        break;
97#if ENABLE(BLOB)
98    case FormDataElement::encodedBlob:
99        result.type = Element::TypeBlob;
100        result.blobURL = element.m_blobURL;
101        break;
102#endif
103    default:
104        ASSERT_NOT_REACHED();
105        return false;
106    }
107
108    return true;
109}
110
111void WebHTTPBody::appendData(const WebData& data)
112{
113    ensureMutable();
114    // FIXME: FormDataElement::m_data should be a SharedBuffer<char>.  Then we
115    // could avoid this buffer copy.
116    m_private->appendData(data.data(), data.size());
117}
118
119void WebHTTPBody::appendFile(const WebString& filePath)
120{
121    ensureMutable();
122    m_private->appendFile(filePath);
123}
124
125void WebHTTPBody::appendFileRange(const WebString& filePath, long long fileStart, long long fileLength, double modificationTime)
126{
127#if ENABLE(BLOB)
128    ensureMutable();
129    m_private->appendFileRange(filePath, fileStart, fileLength, modificationTime);
130#endif
131}
132
133void WebHTTPBody::appendBlob(const WebURL& blobURL)
134{
135#if ENABLE(BLOB)
136    ensureMutable();
137    m_private->appendBlob(blobURL);
138#endif
139}
140
141long long WebHTTPBody::identifier() const
142{
143    ASSERT(!isNull());
144    return m_private->identifier();
145}
146
147void WebHTTPBody::setIdentifier(long long identifier)
148{
149    ensureMutable();
150    return m_private->setIdentifier(identifier);
151}
152
153WebHTTPBody::WebHTTPBody(const PassRefPtr<FormData>& data)
154    : m_private(static_cast<WebHTTPBodyPrivate*>(data.releaseRef()))
155{
156}
157
158WebHTTPBody& WebHTTPBody::operator=(const PassRefPtr<FormData>& data)
159{
160    assign(static_cast<WebHTTPBodyPrivate*>(data.releaseRef()));
161    return *this;
162}
163
164WebHTTPBody::operator PassRefPtr<FormData>() const
165{
166    return m_private;
167}
168
169void WebHTTPBody::assign(WebHTTPBodyPrivate* p)
170{
171    // p is already ref'd for us by the caller
172    if (m_private)
173        m_private->deref();
174    m_private = p;
175}
176
177void WebHTTPBody::ensureMutable()
178{
179    ASSERT(!isNull());
180    if (!m_private->hasOneRef())
181        assign(static_cast<WebHTTPBodyPrivate*>(m_private->copy().releaseRef()));
182}
183
184} // namespace WebKit
185