3049360be6c70bbce8fe9ef75cffefb8cb006322
[WebKit-https.git] / WebCore / kwq / KWQKJobClasses.mm
1 /*
2  * Copyright (C) 2004 Apple Computer, 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "KWQLogging.h"
27
28 #import "KWQExceptions.h"
29 #import "KWQKJobClasses.h"
30 #import "KWQLoader.h"
31 #import "KWQResourceLoader.h"
32 #import "KWQString.h"
33 #import "KWQFoundationExtras.h"
34
35 #import "formdata.h"
36
37 using khtml::FormData;
38
39 namespace KIO {
40
41     // The allocations and releases in TransferJobPrivate are
42     // definitely Cocoa-exception-free (either simple Foundation
43     // classes or our own KWQResourceLoader which avoides doing work
44     // in dealloc
45
46 class TransferJobPrivate
47 {
48 public:
49     TransferJobPrivate(const KURL& kurl)
50         : status(0)
51         , metaData(KWQRetainNSRelease([[NSMutableDictionary alloc] initWithCapacity:17]))
52         , URL(kurl)
53         , loader(nil)
54         , method("GET")
55         , response(0)
56         , assembledResponseHeaders(true)
57         , retrievedCharset(true)
58     {
59     }
60
61     TransferJobPrivate(const KURL& kurl, const FormData &_postData)
62         : status(0)
63         , metaData(KWQRetainNSRelease([[NSMutableDictionary alloc] initWithCapacity:17]))
64         , URL(kurl)
65         , loader(nil)
66         , method("POST")
67         , postData(_postData)
68         , response(0)
69         , assembledResponseHeaders(true)
70         , retrievedCharset(true)
71     {
72     }
73
74     ~TransferJobPrivate()
75     {
76         KWQReleaseResponse(response);
77         KWQRelease(metaData);
78         KWQRelease(loader);
79     }
80
81     int status;
82     NSMutableDictionary *metaData;
83     KURL URL;
84     KWQResourceLoader *loader;
85     QString method;
86     FormData postData;
87
88     void *response;
89     bool assembledResponseHeaders;
90     bool retrievedCharset;
91     QString responseHeaders;
92 };
93
94 TransferJob::TransferJob(const KURL &url, bool reload)
95     : d(new TransferJobPrivate(url)),
96       m_data(this, SIGNAL(data(KIO::Job*, const char*, int))),
97       m_redirection(this, SIGNAL(redirection(KIO::Job*, const KURL&))),
98       m_result(this, SIGNAL(result(KIO::Job*))),
99       m_receivedResponse(this, SIGNAL(receivedResponse(KIO::Job*, void *)))
100 {
101 }
102
103 TransferJob::TransferJob(const KURL &url, const FormData &postData)
104     : d(new TransferJobPrivate(url, postData)),
105       m_data(this, SIGNAL(data(KIO::Job*, const char*, int))),
106       m_redirection(this, SIGNAL(redirection(KIO::Job*, const KURL&))),
107       m_result(this, SIGNAL(result(KIO::Job*))),
108       m_receivedResponse(this, SIGNAL(receivedResponse(KIO::Job*, void *)))
109 {
110 }
111
112 TransferJob::~TransferJob()
113 {
114     // This will cancel the handle, and who knows what that could do
115     KWQ_BLOCK_EXCEPTIONS;
116     [d->loader jobWillBeDeallocated];
117     KWQ_UNBLOCK_EXCEPTIONS;
118     delete d;
119 }
120
121 bool TransferJob::isErrorPage() const
122 {
123     return d->status != 0;
124 }
125
126 int TransferJob::error() const
127 {
128     return d->status;
129 }
130
131 void TransferJob::setError(int e)
132 {
133     d->status = e;
134 }
135
136 QString TransferJob::errorText() const
137 {
138     LOG(NotYetImplemented, "not yet implemented");
139     return QString::null;
140 }
141
142 void TransferJob::assembleResponseHeaders() const
143 {
144     if (!d->assembledResponseHeaders) {
145         d->responseHeaders = QString::fromNSString((NSString *)KWQResponseHeaderString(d->response));
146         d->assembledResponseHeaders = true;
147     }
148 }
149
150 void TransferJob::retrieveCharset() const
151 {
152     if (!d->retrievedCharset) {
153         NSString *charset = (NSString *)KWQResponseTextEncodingName(d->response);
154         if (charset) {
155             [d->metaData setObject:charset forKey:@"charset"];
156         }
157         d->retrievedCharset = true;
158     }
159 }
160
161 QString TransferJob::queryMetaData(const QString &key) const
162 {
163     if (key == "HTTP-Headers") {
164         assembleResponseHeaders();
165         return d->responseHeaders;
166     } 
167
168     if (key == "charset") {
169         // this will put it in the regular metadata dictionary
170         retrieveCharset();
171     }
172
173     NSString *value = [d->metaData objectForKey:key.getNSString()]; 
174     return value ? QString::fromNSString(value) : QString::null;
175 }
176
177 void TransferJob::addMetaData(const QString &key, const QString &value)
178 {
179     [d->metaData setObject:value.getNSString() forKey:key.getNSString()];
180 }
181
182 void TransferJob::addMetaData(const QMap<QString, QString> &keysAndValues)
183 {
184     QMapConstIterator<QString, QString> it = keysAndValues.begin();
185     QMapConstIterator<QString, QString> end = keysAndValues.end();
186     while (it != end) {
187         [d->metaData setObject:it.data().getNSString() forKey:it.key().getNSString()];
188         ++it;
189     }
190 }
191
192 void TransferJob::kill()
193 {
194     delete this;
195 }
196
197 void TransferJob::setLoader(KWQResourceLoader *loader)
198 {
199     KWQRetain(loader);
200     KWQRelease(d->loader);
201     d->loader = loader;
202 }
203
204 KURL TransferJob::url() const
205 {
206     return d->URL;
207 }
208
209 FormData TransferJob::postData() const
210 {
211     return d->postData;
212 }
213
214 QString TransferJob::method() const
215 {
216     return d->method;
217 }
218
219 void TransferJob::emitData(const char *data, int size)
220 {
221     m_data.call(this, data, size);
222 }
223
224 void TransferJob::emitRedirection(const KURL &url)
225 {
226     m_redirection.call(this, url);
227 }
228
229 void TransferJob::emitResult()
230 {
231     m_result.call(this);
232 }
233
234 void TransferJob::emitReceivedResponse(void *response)
235 {
236     d->assembledResponseHeaders = false;
237     d->retrievedCharset = false;
238     d->response = response;
239     KWQRetainResponse(d->response);
240
241     m_receivedResponse.call(this, response);
242 }
243
244 } // namespace KIO