058a74fc8e4a218bd34ffa5a7dd83486a0a04488
[WebKit-https.git] / Source / WebKit2 / Shared / WebCoreArgumentCoders.cpp
1 /*
2  * Copyright (C) 2011 Apple 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 INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebCoreArgumentCoders.h"
28
29 #include "ShareableBitmap.h"
30 #include <WebCore/AuthenticationChallenge.h>
31 #include <WebCore/Cookie.h>
32 #include <WebCore/Credential.h>
33 #include <WebCore/Cursor.h>
34 #include <WebCore/DatabaseDetails.h>
35 #include <WebCore/DictationAlternative.h>
36 #include <WebCore/DragSession.h>
37 #include <WebCore/Editor.h>
38 #include <WebCore/FileChooser.h>
39 #include <WebCore/GraphicsContext.h>
40 #include <WebCore/GraphicsLayer.h>
41 #include <WebCore/Image.h>
42 #include <WebCore/KURL.h>
43 #include <WebCore/PluginData.h>
44 #include <WebCore/ProtectionSpace.h>
45 #include <WebCore/ResourceError.h>
46 #include <WebCore/ResourceRequest.h>
47 #include <WebCore/ResourceResponse.h>
48 #include <WebCore/TextCheckerClient.h>
49 #include <WebCore/UserScript.h>
50 #include <WebCore/UserStyleSheet.h>
51 #include <WebCore/ViewportArguments.h>
52 #include <WebCore/WindowFeatures.h>
53 #include <wtf/text/StringHash.h>
54
55 using namespace WebCore;
56 using namespace WebKit;
57
58 namespace CoreIPC {
59
60 void ArgumentCoder<AffineTransform>::encode(ArgumentEncoder& encoder, const AffineTransform& affineTransform)
61 {
62     SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
63 }
64
65 bool ArgumentCoder<AffineTransform>::decode(ArgumentDecoder* decoder, AffineTransform& affineTransform)
66 {
67     return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
68 }
69
70
71 void ArgumentCoder<FloatPoint>::encode(ArgumentEncoder& encoder, const FloatPoint& floatPoint)
72 {
73     SimpleArgumentCoder<FloatPoint>::encode(encoder, floatPoint);
74 }
75
76 bool ArgumentCoder<FloatPoint>::decode(ArgumentDecoder* decoder, FloatPoint& floatPoint)
77 {
78     return SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint);
79 }
80
81
82 void ArgumentCoder<FloatRect>::encode(ArgumentEncoder& encoder, const FloatRect& floatRect)
83 {
84     SimpleArgumentCoder<FloatRect>::encode(encoder, floatRect);
85 }
86
87 bool ArgumentCoder<FloatRect>::decode(ArgumentDecoder* decoder, FloatRect& floatRect)
88 {
89     return SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect);
90 }
91
92
93 void ArgumentCoder<FloatSize>::encode(ArgumentEncoder& encoder, const FloatSize& floatSize)
94 {
95     SimpleArgumentCoder<FloatSize>::encode(encoder, floatSize);
96 }
97
98 bool ArgumentCoder<FloatSize>::decode(ArgumentDecoder* decoder, FloatSize& floatSize)
99 {
100     return SimpleArgumentCoder<FloatSize>::decode(decoder, floatSize);
101 }
102
103
104 void ArgumentCoder<IntPoint>::encode(ArgumentEncoder& encoder, const IntPoint& intPoint)
105 {
106     SimpleArgumentCoder<IntPoint>::encode(encoder, intPoint);
107 }
108
109 bool ArgumentCoder<IntPoint>::decode(ArgumentDecoder* decoder, IntPoint& intPoint)
110 {
111     return SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint);
112 }
113
114
115 void ArgumentCoder<IntRect>::encode(ArgumentEncoder& encoder, const IntRect& intRect)
116 {
117     SimpleArgumentCoder<IntRect>::encode(encoder, intRect);
118 }
119
120 bool ArgumentCoder<IntRect>::decode(ArgumentDecoder* decoder, IntRect& intRect)
121 {
122     return SimpleArgumentCoder<IntRect>::decode(decoder, intRect);
123 }
124
125
126 void ArgumentCoder<IntSize>::encode(ArgumentEncoder& encoder, const IntSize& intSize)
127 {
128     SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
129 }
130
131 bool ArgumentCoder<IntSize>::decode(ArgumentDecoder* decoder, IntSize& intSize)
132 {
133     return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
134 }
135
136
137 void ArgumentCoder<ViewportAttributes>::encode(ArgumentEncoder& encoder, const ViewportAttributes& viewportAttributes)
138 {
139     SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
140 }
141
142 bool ArgumentCoder<ViewportAttributes>::decode(ArgumentDecoder* decoder, ViewportAttributes& viewportAttributes)
143 {
144     return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
145 }
146
147
148 void ArgumentCoder<MimeClassInfo>::encode(ArgumentEncoder& encoder, const MimeClassInfo& mimeClassInfo)
149 {
150     encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions;
151 }
152
153 bool ArgumentCoder<MimeClassInfo>::decode(ArgumentDecoder* decoder, MimeClassInfo& mimeClassInfo)
154 {
155     if (!decoder->decode(mimeClassInfo.type))
156         return false;
157     if (!decoder->decode(mimeClassInfo.desc))
158         return false;
159     if (!decoder->decode(mimeClassInfo.extensions))
160         return false;
161
162     return true;
163 }
164
165
166 void ArgumentCoder<PluginInfo>::encode(ArgumentEncoder& encoder, const PluginInfo& pluginInfo)
167 {
168     encoder << pluginInfo.name << pluginInfo.file << pluginInfo.desc << pluginInfo.mimes;
169 }
170     
171 bool ArgumentCoder<PluginInfo>::decode(ArgumentDecoder* decoder, PluginInfo& pluginInfo)
172 {
173     if (!decoder->decode(pluginInfo.name))
174         return false;
175     if (!decoder->decode(pluginInfo.file))
176         return false;
177     if (!decoder->decode(pluginInfo.desc))
178         return false;
179     if (!decoder->decode(pluginInfo.mimes))
180         return false;
181
182     return true;
183 }
184
185
186 void ArgumentCoder<HTTPHeaderMap>::encode(ArgumentEncoder& encoder, const HTTPHeaderMap& headerMap)
187 {
188     encoder << static_cast<const HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap);
189 }
190
191 bool ArgumentCoder<HTTPHeaderMap>::decode(ArgumentDecoder* decoder, HTTPHeaderMap& headerMap)
192 {
193     return decoder->decode(static_cast<HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap));
194 }
195
196
197 void ArgumentCoder<AuthenticationChallenge>::encode(ArgumentEncoder& encoder, const AuthenticationChallenge& challenge)
198 {
199     encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error() << challenge.identifier();
200 }
201
202 bool ArgumentCoder<AuthenticationChallenge>::decode(ArgumentDecoder* decoder, AuthenticationChallenge& challenge)
203 {    
204     ProtectionSpace protectionSpace;
205     if (!decoder->decode(protectionSpace))
206         return false;
207
208     Credential proposedCredential;
209     if (!decoder->decode(proposedCredential))
210         return false;
211
212     unsigned previousFailureCount;    
213     if (!decoder->decode(previousFailureCount))
214         return false;
215
216     ResourceResponse failureResponse;
217     if (!decoder->decode(failureResponse))
218         return false;
219
220     ResourceError error;
221     if (!decoder->decode(error))
222         return false;
223     
224     uint64_t identifier;
225     if (!decoder->decode(identifier))
226         return false;
227     
228     challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error, identifier);
229     return true;
230 }
231
232
233 void ArgumentCoder<ProtectionSpace>::encode(ArgumentEncoder& encoder, const ProtectionSpace& space)
234 {
235     encoder << space.host() << space.port() << space.realm();
236     encoder.encodeEnum(space.authenticationScheme());
237     encoder.encodeEnum(space.serverType());
238 }
239
240 bool ArgumentCoder<ProtectionSpace>::decode(ArgumentDecoder* decoder, ProtectionSpace& space)
241 {
242     String host;
243     if (!decoder->decode(host))
244         return false;
245
246     int port;
247     if (!decoder->decode(port))
248         return false;
249
250     String realm;
251     if (!decoder->decode(realm))
252         return false;
253     
254     ProtectionSpaceAuthenticationScheme authenticationScheme;
255     if (!decoder->decodeEnum(authenticationScheme))
256         return false;
257
258     ProtectionSpaceServerType serverType;
259     if (!decoder->decodeEnum(serverType))
260         return false;
261
262     space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
263     return true;
264 }
265
266 void ArgumentCoder<Credential>::encode(ArgumentEncoder& encoder, const Credential& credential)
267 {
268     encoder << credential.user() << credential.password();
269     encoder.encodeEnum(credential.persistence());
270 }
271
272 bool ArgumentCoder<Credential>::decode(ArgumentDecoder* decoder, Credential& credential)
273 {
274     String user;
275     if (!decoder->decode(user))
276         return false;
277
278     String password;
279     if (!decoder->decode(password))
280         return false;
281
282     CredentialPersistence persistence;
283     if (!decoder->decodeEnum(persistence))
284         return false;
285     
286     credential = Credential(user, password, persistence);
287     return true;
288 }
289
290 static void encodeImage(ArgumentEncoder& encoder, Image* image)
291 {
292     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), ShareableBitmap::SupportsAlpha);
293     bitmap->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
294
295     ShareableBitmap::Handle handle;
296     bitmap->createHandle(handle);
297
298     encoder << handle;
299 }
300
301 static bool decodeImage(ArgumentDecoder* decoder, RefPtr<Image>& image)
302 {
303     ShareableBitmap::Handle handle;
304     if (!decoder->decode(handle))
305         return false;
306     
307     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
308     if (!bitmap)
309         return false;
310     image = bitmap->createImage();
311     if (!image)
312         return false;
313     return true;
314 }
315
316 void ArgumentCoder<Cursor>::encode(ArgumentEncoder& encoder, const Cursor& cursor)
317 {
318     encoder.encodeEnum(cursor.type());
319         
320     if (cursor.type() != Cursor::Custom)
321         return;
322
323     if (cursor.image()->isNull()) {
324         encoder << false; // There is no valid image being encoded.
325         return;
326     }
327
328     encoder << true;
329     encodeImage(encoder, cursor.image());
330     encoder << cursor.hotSpot();
331 }
332
333 bool ArgumentCoder<Cursor>::decode(ArgumentDecoder* decoder, Cursor& cursor)
334 {
335     Cursor::Type type;
336     if (!decoder->decodeEnum(type))
337         return false;
338
339     if (type > Cursor::Custom)
340         return false;
341
342     if (type != Cursor::Custom) {
343         const Cursor& cursorReference = Cursor::fromType(type);
344         // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
345         // This will avoid having to re-create the platform cursors over and over.
346         (void)cursorReference.platformCursor();
347
348         cursor = cursorReference;
349         return true;
350     }
351
352     bool isValidImagePresent;
353     if (!decoder->decode(isValidImagePresent))
354         return false;
355
356     if (!isValidImagePresent) {
357         cursor = Cursor(Image::nullImage(), IntPoint());
358         return true;
359     }
360
361     RefPtr<Image> image;
362     if (!decodeImage(decoder, image))
363         return false;
364
365     IntPoint hotSpot;
366     if (!decoder->decode(hotSpot))
367         return false;
368
369     if (!image->rect().contains(hotSpot))
370         return false;
371
372     cursor = Cursor(image.get(), hotSpot);
373     return true;
374 }
375
376 void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
377 {
378     if (kShouldSerializeWebCoreData) {
379         encoder << resourceRequest.url().string();
380         encoder << resourceRequest.httpMethod();
381         encoder << resourceRequest.httpHeaderFields();
382
383         // FIXME: Do not encode HTTP message body.
384         // 1. It can be large and thus costly to send across.
385         // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all.
386         FormData* httpBody = resourceRequest.httpBody();
387         encoder << static_cast<bool>(httpBody);
388         if (httpBody)
389             encoder << httpBody->flattenToString();
390
391         encoder << resourceRequest.firstPartyForCookies().string();
392     }
393
394     encodePlatformData(encoder, resourceRequest);
395 }
396
397 bool ArgumentCoder<ResourceRequest>::decode(ArgumentDecoder* decoder, ResourceRequest& resourceRequest)
398 {
399     if (kShouldSerializeWebCoreData) {
400         ResourceRequest request;
401
402         String url;
403         if (!decoder->decode(url))
404             return false;
405         request.setURL(KURL(KURL(), url));
406
407         String httpMethod;
408         if (!decoder->decode(httpMethod))
409             return false;
410         request.setHTTPMethod(httpMethod);
411
412         HTTPHeaderMap headers;
413         if (!decoder->decode(headers))
414             return false;
415         request.addHTTPHeaderFields(headers);
416
417         bool hasHTTPBody;
418         if (!decoder->decode(hasHTTPBody))
419             return false;
420         if (hasHTTPBody) {
421             String httpBody;
422             if (!decoder->decode(httpBody))
423                 return false;
424             request.setHTTPBody(FormData::create(httpBody.utf8()));
425         }
426
427         String firstPartyForCookies;
428         if (!decoder->decode(firstPartyForCookies))
429             return false;
430         request.setFirstPartyForCookies(KURL(KURL(), firstPartyForCookies));
431
432         resourceRequest = request;
433     }
434
435     return decodePlatformData(decoder, resourceRequest);
436 }
437
438 void ArgumentCoder<ResourceResponse>::encode(ArgumentEncoder& encoder, const ResourceResponse& resourceResponse)
439 {
440     if (kShouldSerializeWebCoreData) {
441         bool responseIsNull = resourceResponse.isNull();
442         encoder << responseIsNull;
443         if (responseIsNull)
444             return;
445
446         encoder << resourceResponse.url().string();
447         encoder << static_cast<int32_t>(resourceResponse.httpStatusCode());
448         encoder << resourceResponse.httpHeaderFields();
449
450         encoder << resourceResponse.mimeType();
451         encoder << resourceResponse.textEncodingName();
452         encoder << static_cast<int64_t>(resourceResponse.expectedContentLength());
453         encoder << resourceResponse.httpStatusText();
454         encoder << resourceResponse.suggestedFilename();
455     }
456
457     encodePlatformData(encoder, resourceResponse);
458 }
459
460 bool ArgumentCoder<ResourceResponse>::decode(ArgumentDecoder* decoder, ResourceResponse& resourceResponse)
461 {
462     if (kShouldSerializeWebCoreData) {
463         bool responseIsNull;
464         if (!decoder->decode(responseIsNull))
465             return false;
466         if (responseIsNull) {
467             resourceResponse = ResourceResponse();
468             return true;
469         }
470
471         ResourceResponse response;
472
473         String url;
474         if (!decoder->decode(url))
475             return false;
476         response.setURL(KURL(KURL(), url));
477
478         int32_t httpStatusCode;
479         if (!decoder->decode(httpStatusCode))
480             return false;
481         response.setHTTPStatusCode(httpStatusCode);
482
483         HTTPHeaderMap headers;
484         if (!decoder->decode(headers))
485             return false;
486         for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it)
487             response.setHTTPHeaderField(it->key, it->value);
488
489         String mimeType;
490         if (!decoder->decode(mimeType))
491             return false;
492         response.setMimeType(mimeType);
493
494         String textEncodingName;
495         if (!decoder->decode(textEncodingName))
496             return false;
497         response.setTextEncodingName(textEncodingName);
498
499         int64_t contentLength;
500         if (!decoder->decode(contentLength))
501             return false;
502         response.setExpectedContentLength(contentLength);
503
504         String httpStatusText;
505         if (!decoder->decode(httpStatusText))
506             return false;
507         response.setHTTPStatusText(httpStatusText);
508
509         String suggestedFilename;
510         if (!decoder->decode(suggestedFilename))
511             return false;
512         response.setSuggestedFilename(suggestedFilename);
513
514         resourceResponse = response;
515     }
516
517     return decodePlatformData(decoder, resourceResponse);
518 }
519
520 void ArgumentCoder<ResourceError>::encode(ArgumentEncoder& encoder, const ResourceError& resourceError)
521 {
522     if (kShouldSerializeWebCoreData) {
523         bool errorIsNull = resourceError.isNull();
524         encoder << errorIsNull;
525         if (errorIsNull)
526             return;
527
528         encoder << resourceError.domain();
529         encoder << resourceError.errorCode();
530         encoder << resourceError.failingURL();
531         encoder << resourceError.localizedDescription();
532         encoder << resourceError.isCancellation();
533         encoder << resourceError.isTimeout();
534     }
535
536     encodePlatformData(encoder, resourceError);
537 }
538
539 bool ArgumentCoder<ResourceError>::decode(ArgumentDecoder* decoder, ResourceError& resourceError)
540 {
541     if (kShouldSerializeWebCoreData) {
542         bool errorIsNull;
543         if (!decoder->decode(errorIsNull))
544             return false;
545         if (errorIsNull) {
546             resourceError = ResourceError();
547             return true;
548         }
549
550         String domain;
551         if (!decoder->decode(domain))
552             return false;
553
554         int errorCode;
555         if (!decoder->decode(errorCode))
556             return false;
557
558         String failingURL;
559         if (!decoder->decode(failingURL))
560             return false;
561
562         String localizedDescription;
563         if (!decoder->decode(localizedDescription))
564             return false;
565
566         bool isCancellation;
567         if (!decoder->decode(isCancellation))
568             return false;
569
570         bool isTimeout;
571         if (!decoder->decode(isTimeout))
572             return false;
573
574         resourceError = ResourceError(domain, errorCode, failingURL, localizedDescription);
575         resourceError.setIsCancellation(isCancellation);
576         resourceError.setIsTimeout(isTimeout);
577     }
578
579     return decodePlatformData(decoder, resourceError);
580 }
581
582 void ArgumentCoder<WindowFeatures>::encode(ArgumentEncoder& encoder, const WindowFeatures& windowFeatures)
583 {
584     encoder << windowFeatures.x;
585     encoder << windowFeatures.y;
586     encoder << windowFeatures.width;
587     encoder << windowFeatures.height;
588     encoder << windowFeatures.xSet;
589     encoder << windowFeatures.ySet;
590     encoder << windowFeatures.widthSet;
591     encoder << windowFeatures.heightSet;
592     encoder << windowFeatures.menuBarVisible;
593     encoder << windowFeatures.statusBarVisible;
594     encoder << windowFeatures.toolBarVisible;
595     encoder << windowFeatures.locationBarVisible;
596     encoder << windowFeatures.scrollbarsVisible;
597     encoder << windowFeatures.resizable;
598     encoder << windowFeatures.fullscreen;
599     encoder << windowFeatures.dialog;
600 }
601
602 bool ArgumentCoder<WindowFeatures>::decode(ArgumentDecoder* decoder, WindowFeatures& windowFeatures)
603 {
604     if (!decoder->decode(windowFeatures.x))
605         return false;
606     if (!decoder->decode(windowFeatures.y))
607         return false;
608     if (!decoder->decode(windowFeatures.width))
609         return false;
610     if (!decoder->decode(windowFeatures.height))
611         return false;
612     if (!decoder->decode(windowFeatures.xSet))
613         return false;
614     if (!decoder->decode(windowFeatures.ySet))
615         return false;
616     if (!decoder->decode(windowFeatures.widthSet))
617         return false;
618     if (!decoder->decode(windowFeatures.heightSet))
619         return false;
620     if (!decoder->decode(windowFeatures.menuBarVisible))
621         return false;
622     if (!decoder->decode(windowFeatures.statusBarVisible))
623         return false;
624     if (!decoder->decode(windowFeatures.toolBarVisible))
625         return false;
626     if (!decoder->decode(windowFeatures.locationBarVisible))
627         return false;
628     if (!decoder->decode(windowFeatures.scrollbarsVisible))
629         return false;
630     if (!decoder->decode(windowFeatures.resizable))
631         return false;
632     if (!decoder->decode(windowFeatures.fullscreen))
633         return false;
634     if (!decoder->decode(windowFeatures.dialog))
635         return false;
636     return true;
637 }
638
639
640 void ArgumentCoder<Color>::encode(ArgumentEncoder& encoder, const Color& color)
641 {
642     if (!color.isValid()) {
643         encoder << false;
644         return;
645     }
646
647     encoder << true;
648     encoder << color.rgb();
649 }
650
651 bool ArgumentCoder<Color>::decode(ArgumentDecoder* decoder, Color& color)
652 {
653     bool isValid;
654     if (!decoder->decode(isValid))
655         return false;
656
657     if (!isValid) {
658         color = Color();
659         return true;
660     }
661
662     RGBA32 rgba;
663     if (!decoder->decode(rgba))
664         return false;
665
666     color = Color(rgba);
667     return true;
668 }
669
670
671 void ArgumentCoder<CompositionUnderline>::encode(ArgumentEncoder& encoder, const CompositionUnderline& underline)
672 {
673     encoder << underline.startOffset;
674     encoder << underline.endOffset;
675     encoder << underline.thick;
676     encoder << underline.color;
677 }
678
679 bool ArgumentCoder<CompositionUnderline>::decode(ArgumentDecoder* decoder, CompositionUnderline& underline)
680 {
681     if (!decoder->decode(underline.startOffset))
682         return false;
683     if (!decoder->decode(underline.endOffset))
684         return false;
685     if (!decoder->decode(underline.thick))
686         return false;
687     if (!decoder->decode(underline.color))
688         return false;
689
690     return true;
691 }
692
693
694 void ArgumentCoder<Cookie>::encode(ArgumentEncoder& encoder, const Cookie& cookie)
695 {
696     encoder << cookie.name;
697     encoder << cookie.value;
698     encoder << cookie.domain;
699     encoder << cookie.path;
700     encoder << cookie.expires;
701     encoder << cookie.httpOnly;
702     encoder << cookie.secure;
703     encoder << cookie.session;
704 }
705
706 bool ArgumentCoder<Cookie>::decode(ArgumentDecoder* decoder, Cookie& cookie)
707 {
708     if (!decoder->decode(cookie.name))
709         return false;
710     if (!decoder->decode(cookie.value))
711         return false;
712     if (!decoder->decode(cookie.domain))
713         return false;
714     if (!decoder->decode(cookie.path))
715         return false;
716     if (!decoder->decode(cookie.expires))
717         return false;
718     if (!decoder->decode(cookie.httpOnly))
719         return false;
720     if (!decoder->decode(cookie.secure))
721         return false;
722     if (!decoder->decode(cookie.session))
723         return false;
724
725     return true;
726 }
727
728
729 #if ENABLE(SQL_DATABASE)
730 void ArgumentCoder<DatabaseDetails>::encode(ArgumentEncoder& encoder, const DatabaseDetails& details)
731 {
732     encoder << details.name();
733     encoder << details.displayName();
734     encoder << details.expectedUsage();
735     encoder << details.currentUsage();
736 }
737     
738 bool ArgumentCoder<DatabaseDetails>::decode(ArgumentDecoder* decoder, DatabaseDetails& details)
739 {
740     String name;
741     if (!decoder->decode(name))
742         return false;
743
744     String displayName;
745     if (!decoder->decode(displayName))
746         return false;
747
748     uint64_t expectedUsage;
749     if (!decoder->decode(expectedUsage))
750         return false;
751
752     uint64_t currentUsage;
753     if (!decoder->decode(currentUsage))
754         return false;
755     
756     details = DatabaseDetails(name, displayName, expectedUsage, currentUsage);
757     return true;
758 }
759 #endif
760
761 void ArgumentCoder<DictationAlternative>::encode(ArgumentEncoder& encoder, const DictationAlternative& dictationAlternative)
762 {
763     encoder << dictationAlternative.rangeStart;
764     encoder << dictationAlternative.rangeLength;
765     encoder << dictationAlternative.dictationContext;
766 }
767
768 bool ArgumentCoder<DictationAlternative>::decode(ArgumentDecoder* decoder, DictationAlternative& dictationAlternative)
769 {
770     if (!decoder->decode(dictationAlternative.rangeStart))
771         return false;
772     if (!decoder->decode(dictationAlternative.rangeLength))
773         return false;
774     if (!decoder->decode(dictationAlternative.dictationContext))
775         return false;
776     return true;
777 }
778
779
780 void ArgumentCoder<FileChooserSettings>::encode(ArgumentEncoder& encoder, const FileChooserSettings& settings)
781 {
782     encoder << settings.allowsMultipleFiles;
783 #if ENABLE(DIRECTORY_UPLOAD)
784     encoder << settings.allowsDirectoryUpload;
785 #endif
786     encoder << settings.acceptMIMETypes;
787     encoder << settings.selectedFiles;
788 #if ENABLE(MEDIA_CAPTURE)
789     encoder << settings.capture;
790 #endif
791 }
792
793 bool ArgumentCoder<FileChooserSettings>::decode(ArgumentDecoder* decoder, FileChooserSettings& settings)
794 {
795     if (!decoder->decode(settings.allowsMultipleFiles))
796         return false;
797 #if ENABLE(DIRECTORY_UPLOAD)
798     if (!decoder->decode(settings.allowsDirectoryUpload))
799         return false;
800 #endif
801     if (!decoder->decode(settings.acceptMIMETypes))
802         return false;
803     if (!decoder->decode(settings.selectedFiles))
804         return false;
805 #if ENABLE(MEDIA_CAPTURE)
806     if (!decoder->decode(settings.capture))
807         return false;
808 #endif
809
810     return true;
811 }
812
813
814 void ArgumentCoder<GrammarDetail>::encode(ArgumentEncoder& encoder, const GrammarDetail& detail)
815 {
816     encoder << detail.location;
817     encoder << detail.length;
818     encoder << detail.guesses;
819     encoder << detail.userDescription;
820 }
821
822 bool ArgumentCoder<GrammarDetail>::decode(ArgumentDecoder* decoder, GrammarDetail& detail)
823 {
824     if (!decoder->decode(detail.location))
825         return false;
826     if (!decoder->decode(detail.length))
827         return false;
828     if (!decoder->decode(detail.guesses))
829         return false;
830     if (!decoder->decode(detail.userDescription))
831         return false;
832
833     return true;
834 }
835
836
837 void ArgumentCoder<TextCheckingResult>::encode(ArgumentEncoder& encoder, const TextCheckingResult& result)
838 {
839     encoder.encodeEnum(result.type);
840     encoder << result.location;
841     encoder << result.length;
842     encoder << result.details;
843     encoder << result.replacement;
844 }
845
846 bool ArgumentCoder<TextCheckingResult>::decode(ArgumentDecoder* decoder, TextCheckingResult& result)
847 {
848     if (!decoder->decodeEnum(result.type))
849         return false;
850     if (!decoder->decode(result.location))
851         return false;
852     if (!decoder->decode(result.length))
853         return false;
854     if (!decoder->decode(result.details))
855         return false;
856     if (!decoder->decode(result.replacement))
857         return false;
858     return true;
859 }
860
861 void ArgumentCoder<DragSession>::encode(ArgumentEncoder& encoder, const DragSession& result)
862 {
863     encoder.encodeEnum(result.operation);
864     encoder << result.mouseIsOverFileInput;
865     encoder << result.numberOfItemsToBeAccepted;
866 }
867
868 bool ArgumentCoder<DragSession>::decode(ArgumentDecoder* decoder, DragSession& result)
869 {
870     if (!decoder->decodeEnum(result.operation))
871         return false;
872     if (!decoder->decode(result.mouseIsOverFileInput))
873         return false;
874     if (!decoder->decode(result.numberOfItemsToBeAccepted))
875         return false;
876     return true;
877 }
878
879 void ArgumentCoder<KURL>::encode(ArgumentEncoder& encoder, const KURL& result)
880 {
881     encoder << result.string();
882 }
883     
884 bool ArgumentCoder<KURL>::decode(ArgumentDecoder* decoder, KURL& result)
885 {
886     String urlAsString;
887     if (!decoder->decode(urlAsString))
888         return false;
889     result = KURL(WebCore::ParsedURLString, urlAsString);
890     return true;
891 }
892
893 void ArgumentCoder<WebCore::UserStyleSheet>::encode(ArgumentEncoder& encoder, const WebCore::UserStyleSheet& userStyleSheet)
894 {
895     encoder << userStyleSheet.source();
896     encoder << userStyleSheet.url();
897     encoder << userStyleSheet.whitelist();
898     encoder << userStyleSheet.blacklist();
899     encoder.encodeEnum(userStyleSheet.injectedFrames());
900     encoder.encodeEnum(userStyleSheet.level());
901 }
902
903 bool ArgumentCoder<WebCore::UserStyleSheet>::decode(ArgumentDecoder* decoder, WebCore::UserStyleSheet& userStyleSheet)
904 {
905     String source;
906     if (!decoder->decode(source))
907         return false;
908
909     KURL url;
910     if (!decoder->decode(url))
911         return false;
912
913     Vector<String> whitelist;
914     if (!decoder->decode(whitelist))
915         return false;
916
917     Vector<String> blacklist;
918     if (!decoder->decode(blacklist))
919         return false;
920
921     WebCore::UserContentInjectedFrames injectedFrames;
922     if (!decoder->decodeEnum(injectedFrames))
923         return false;
924
925     WebCore::UserStyleLevel level;
926     if (!decoder->decodeEnum(level))
927         return false;
928
929     userStyleSheet = WebCore::UserStyleSheet(source, url, whitelist, blacklist, injectedFrames, level);
930     return true;
931 }
932
933 void ArgumentCoder<WebCore::UserScript>::encode(ArgumentEncoder& encoder, const WebCore::UserScript& userScript)
934 {
935     encoder << userScript.source();
936     encoder << userScript.url();
937     encoder << userScript.whitelist();
938     encoder << userScript.blacklist();
939     encoder.encodeEnum(userScript.injectionTime());
940     encoder.encodeEnum(userScript.injectedFrames());
941 }
942
943 bool ArgumentCoder<WebCore::UserScript>::decode(ArgumentDecoder* decoder, WebCore::UserScript& userScript)
944 {
945     String source;
946     if (!decoder->decode(source))
947         return false;
948
949     KURL url;
950     if (!decoder->decode(url))
951         return false;
952
953     Vector<String> whitelist;
954     if (!decoder->decode(whitelist))
955         return false;
956
957     Vector<String> blacklist;
958     if (!decoder->decode(blacklist))
959         return false;
960
961     WebCore::UserScriptInjectionTime injectionTime;
962     if (!decoder->decodeEnum(injectionTime))
963         return false;
964
965     WebCore::UserContentInjectedFrames injectedFrames;
966     if (!decoder->decodeEnum(injectedFrames))
967         return false;
968
969     userScript = WebCore::UserScript(source, url, whitelist, blacklist, injectionTime, injectedFrames);
970     return true;
971 }
972
973 } // namespace CoreIPC