[GTK] invalid application of 'sizeof' to incomplete type
[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/FilterOperation.h>
40 #include <WebCore/FilterOperations.h>
41 #include <WebCore/GraphicsContext.h>
42 #include <WebCore/GraphicsLayer.h>
43 #include <WebCore/Image.h>
44 #include <WebCore/Length.h>
45 #include <WebCore/PluginData.h>
46 #include <WebCore/ProtectionSpace.h>
47 #include <WebCore/ResourceError.h>
48 #include <WebCore/ResourceRequest.h>
49 #include <WebCore/ResourceResponse.h>
50 #include <WebCore/TextCheckerClient.h>
51 #include <WebCore/TransformationMatrix.h>
52 #include <WebCore/URL.h>
53 #include <WebCore/UserScript.h>
54 #include <WebCore/UserStyleSheet.h>
55 #include <WebCore/ViewportArguments.h>
56 #include <WebCore/WindowFeatures.h>
57 #include <wtf/text/CString.h>
58 #include <wtf/text/StringHash.h>
59
60 using namespace WebCore;
61 using namespace WebKit;
62
63 namespace CoreIPC {
64
65 void ArgumentCoder<AffineTransform>::encode(ArgumentEncoder& encoder, const AffineTransform& affineTransform)
66 {
67     SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
68 }
69
70 bool ArgumentCoder<AffineTransform>::decode(ArgumentDecoder& decoder, AffineTransform& affineTransform)
71 {
72     return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
73 }
74
75
76 void ArgumentCoder<TransformationMatrix>::encode(ArgumentEncoder& encoder, const TransformationMatrix& transformationMatrix)
77 {
78     SimpleArgumentCoder<TransformationMatrix>::encode(encoder, transformationMatrix);
79 }
80
81 bool ArgumentCoder<TransformationMatrix>::decode(ArgumentDecoder& decoder, TransformationMatrix& transformationMatrix)
82 {
83     return SimpleArgumentCoder<TransformationMatrix>::decode(decoder, transformationMatrix);
84 }
85
86
87 void ArgumentCoder<FloatPoint>::encode(ArgumentEncoder& encoder, const FloatPoint& floatPoint)
88 {
89     SimpleArgumentCoder<FloatPoint>::encode(encoder, floatPoint);
90 }
91
92 bool ArgumentCoder<FloatPoint>::decode(ArgumentDecoder& decoder, FloatPoint& floatPoint)
93 {
94     return SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint);
95 }
96
97
98 void ArgumentCoder<FloatPoint3D>::encode(ArgumentEncoder& encoder, const FloatPoint3D& floatPoint)
99 {
100     SimpleArgumentCoder<FloatPoint3D>::encode(encoder, floatPoint);
101 }
102
103 bool ArgumentCoder<FloatPoint3D>::decode(ArgumentDecoder& decoder, FloatPoint3D& floatPoint)
104 {
105     return SimpleArgumentCoder<FloatPoint3D>::decode(decoder, floatPoint);
106 }
107
108
109 void ArgumentCoder<FloatRect>::encode(ArgumentEncoder& encoder, const FloatRect& floatRect)
110 {
111     SimpleArgumentCoder<FloatRect>::encode(encoder, floatRect);
112 }
113
114 bool ArgumentCoder<FloatRect>::decode(ArgumentDecoder& decoder, FloatRect& floatRect)
115 {
116     return SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect);
117 }
118
119
120 void ArgumentCoder<FloatSize>::encode(ArgumentEncoder& encoder, const FloatSize& floatSize)
121 {
122     SimpleArgumentCoder<FloatSize>::encode(encoder, floatSize);
123 }
124
125 bool ArgumentCoder<FloatSize>::decode(ArgumentDecoder& decoder, FloatSize& floatSize)
126 {
127     return SimpleArgumentCoder<FloatSize>::decode(decoder, floatSize);
128 }
129
130
131 void ArgumentCoder<IntPoint>::encode(ArgumentEncoder& encoder, const IntPoint& intPoint)
132 {
133     SimpleArgumentCoder<IntPoint>::encode(encoder, intPoint);
134 }
135
136 bool ArgumentCoder<IntPoint>::decode(ArgumentDecoder& decoder, IntPoint& intPoint)
137 {
138     return SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint);
139 }
140
141
142 void ArgumentCoder<IntRect>::encode(ArgumentEncoder& encoder, const IntRect& intRect)
143 {
144     SimpleArgumentCoder<IntRect>::encode(encoder, intRect);
145 }
146
147 bool ArgumentCoder<IntRect>::decode(ArgumentDecoder& decoder, IntRect& intRect)
148 {
149     return SimpleArgumentCoder<IntRect>::decode(decoder, intRect);
150 }
151
152
153 void ArgumentCoder<IntSize>::encode(ArgumentEncoder& encoder, const IntSize& intSize)
154 {
155     SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
156 }
157
158 bool ArgumentCoder<IntSize>::decode(ArgumentDecoder& decoder, IntSize& intSize)
159 {
160     return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
161 }
162
163
164 void ArgumentCoder<Length>::encode(ArgumentEncoder& encoder, const Length& length)
165 {
166     SimpleArgumentCoder<Length>::encode(encoder, length);
167 }
168
169 bool ArgumentCoder<Length>::decode(ArgumentDecoder& decoder, Length& length)
170 {
171     return SimpleArgumentCoder<Length>::decode(decoder, length);
172 }
173
174
175 void ArgumentCoder<ViewportAttributes>::encode(ArgumentEncoder& encoder, const ViewportAttributes& viewportAttributes)
176 {
177     SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
178 }
179
180 bool ArgumentCoder<ViewportAttributes>::decode(ArgumentDecoder& decoder, ViewportAttributes& viewportAttributes)
181 {
182     return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
183 }
184
185
186 void ArgumentCoder<MimeClassInfo>::encode(ArgumentEncoder& encoder, const MimeClassInfo& mimeClassInfo)
187 {
188     encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions;
189 }
190
191 bool ArgumentCoder<MimeClassInfo>::decode(ArgumentDecoder& decoder, MimeClassInfo& mimeClassInfo)
192 {
193     if (!decoder.decode(mimeClassInfo.type))
194         return false;
195     if (!decoder.decode(mimeClassInfo.desc))
196         return false;
197     if (!decoder.decode(mimeClassInfo.extensions))
198         return false;
199
200     return true;
201 }
202
203
204 void ArgumentCoder<PluginInfo>::encode(ArgumentEncoder& encoder, const PluginInfo& pluginInfo)
205 {
206     encoder << pluginInfo.name << pluginInfo.file << pluginInfo.desc << pluginInfo.mimes << pluginInfo.isApplicationPlugin;
207 }
208     
209 bool ArgumentCoder<PluginInfo>::decode(ArgumentDecoder& decoder, PluginInfo& pluginInfo)
210 {
211     if (!decoder.decode(pluginInfo.name))
212         return false;
213     if (!decoder.decode(pluginInfo.file))
214         return false;
215     if (!decoder.decode(pluginInfo.desc))
216         return false;
217     if (!decoder.decode(pluginInfo.mimes))
218         return false;
219     if (!decoder.decode(pluginInfo.isApplicationPlugin))
220         return false;
221
222     return true;
223 }
224
225
226 void ArgumentCoder<HTTPHeaderMap>::encode(ArgumentEncoder& encoder, const HTTPHeaderMap& headerMap)
227 {
228     encoder << static_cast<const HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap);
229 }
230
231 bool ArgumentCoder<HTTPHeaderMap>::decode(ArgumentDecoder& decoder, HTTPHeaderMap& headerMap)
232 {
233     return decoder.decode(static_cast<HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap));
234 }
235
236
237 void ArgumentCoder<AuthenticationChallenge>::encode(ArgumentEncoder& encoder, const AuthenticationChallenge& challenge)
238 {
239     encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error();
240 }
241
242 bool ArgumentCoder<AuthenticationChallenge>::decode(ArgumentDecoder& decoder, AuthenticationChallenge& challenge)
243 {    
244     ProtectionSpace protectionSpace;
245     if (!decoder.decode(protectionSpace))
246         return false;
247
248     Credential proposedCredential;
249     if (!decoder.decode(proposedCredential))
250         return false;
251
252     unsigned previousFailureCount;    
253     if (!decoder.decode(previousFailureCount))
254         return false;
255
256     ResourceResponse failureResponse;
257     if (!decoder.decode(failureResponse))
258         return false;
259
260     ResourceError error;
261     if (!decoder.decode(error))
262         return false;
263     
264     challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
265     return true;
266 }
267
268
269 void ArgumentCoder<ProtectionSpace>::encode(ArgumentEncoder& encoder, const ProtectionSpace& space)
270 {
271     encoder << space.host() << space.port() << space.realm();
272     encoder.encodeEnum(space.authenticationScheme());
273     encoder.encodeEnum(space.serverType());
274 }
275
276 bool ArgumentCoder<ProtectionSpace>::decode(ArgumentDecoder& decoder, ProtectionSpace& space)
277 {
278     String host;
279     if (!decoder.decode(host))
280         return false;
281
282     int port;
283     if (!decoder.decode(port))
284         return false;
285
286     String realm;
287     if (!decoder.decode(realm))
288         return false;
289     
290     ProtectionSpaceAuthenticationScheme authenticationScheme;
291     if (!decoder.decodeEnum(authenticationScheme))
292         return false;
293
294     ProtectionSpaceServerType serverType;
295     if (!decoder.decodeEnum(serverType))
296         return false;
297
298     space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
299     return true;
300 }
301
302 void ArgumentCoder<Credential>::encode(ArgumentEncoder& encoder, const Credential& credential)
303 {
304     encoder << credential.user() << credential.password();
305     encoder.encodeEnum(credential.persistence());
306 }
307
308 bool ArgumentCoder<Credential>::decode(ArgumentDecoder& decoder, Credential& credential)
309 {
310     String user;
311     if (!decoder.decode(user))
312         return false;
313
314     String password;
315     if (!decoder.decode(password))
316         return false;
317
318     CredentialPersistence persistence;
319     if (!decoder.decodeEnum(persistence))
320         return false;
321     
322     credential = Credential(user, password, persistence);
323     return true;
324 }
325
326 static void encodeImage(ArgumentEncoder& encoder, Image* image)
327 {
328     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), ShareableBitmap::SupportsAlpha);
329     bitmap->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
330
331     ShareableBitmap::Handle handle;
332     bitmap->createHandle(handle);
333
334     encoder << handle;
335 }
336
337 static bool decodeImage(ArgumentDecoder& decoder, RefPtr<Image>& image)
338 {
339     ShareableBitmap::Handle handle;
340     if (!decoder.decode(handle))
341         return false;
342     
343     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
344     if (!bitmap)
345         return false;
346     image = bitmap->createImage();
347     if (!image)
348         return false;
349     return true;
350 }
351
352 #if !PLATFORM(IOS)
353 void ArgumentCoder<Cursor>::encode(ArgumentEncoder& encoder, const Cursor& cursor)
354 {
355     encoder.encodeEnum(cursor.type());
356         
357     if (cursor.type() != Cursor::Custom)
358         return;
359
360     if (cursor.image()->isNull()) {
361         encoder << false; // There is no valid image being encoded.
362         return;
363     }
364
365     encoder << true;
366     encodeImage(encoder, cursor.image());
367     encoder << cursor.hotSpot();
368 }
369
370 bool ArgumentCoder<Cursor>::decode(ArgumentDecoder& decoder, Cursor& cursor)
371 {
372     Cursor::Type type;
373     if (!decoder.decodeEnum(type))
374         return false;
375
376     if (type > Cursor::Custom)
377         return false;
378
379     if (type != Cursor::Custom) {
380         const Cursor& cursorReference = Cursor::fromType(type);
381         // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
382         // This will avoid having to re-create the platform cursors over and over.
383         (void)cursorReference.platformCursor();
384
385         cursor = cursorReference;
386         return true;
387     }
388
389     bool isValidImagePresent;
390     if (!decoder.decode(isValidImagePresent))
391         return false;
392
393     if (!isValidImagePresent) {
394         cursor = Cursor(Image::nullImage(), IntPoint());
395         return true;
396     }
397
398     RefPtr<Image> image;
399     if (!decodeImage(decoder, image))
400         return false;
401
402     IntPoint hotSpot;
403     if (!decoder.decode(hotSpot))
404         return false;
405
406     if (!image->rect().contains(hotSpot))
407         return false;
408
409     cursor = Cursor(image.get(), hotSpot);
410     return true;
411 }
412 #endif
413
414 void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
415 {
416     if (kShouldSerializeWebCoreData) {
417         encoder << resourceRequest.url().string();
418         encoder << resourceRequest.httpMethod();
419         encoder << resourceRequest.httpHeaderFields();
420
421         // FIXME: Do not encode HTTP message body.
422         // 1. It can be large and thus costly to send across.
423         // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all.
424         FormData* httpBody = resourceRequest.httpBody();
425         encoder << static_cast<bool>(httpBody);
426         if (httpBody)
427             encoder << httpBody->flattenToString();
428
429         encoder << resourceRequest.firstPartyForCookies().string();
430     }
431
432 #if ENABLE(CACHE_PARTITIONING)
433     encoder << resourceRequest.cachePartition();
434 #endif
435
436     encodePlatformData(encoder, resourceRequest);
437 }
438
439 bool ArgumentCoder<ResourceRequest>::decode(ArgumentDecoder& decoder, ResourceRequest& resourceRequest)
440 {
441     if (kShouldSerializeWebCoreData) {
442         ResourceRequest request;
443
444         String url;
445         if (!decoder.decode(url))
446             return false;
447         request.setURL(URL(URL(), url));
448
449         String httpMethod;
450         if (!decoder.decode(httpMethod))
451             return false;
452         request.setHTTPMethod(httpMethod);
453
454         HTTPHeaderMap headers;
455         if (!decoder.decode(headers))
456             return false;
457         request.addHTTPHeaderFields(headers);
458
459         bool hasHTTPBody;
460         if (!decoder.decode(hasHTTPBody))
461             return false;
462         if (hasHTTPBody) {
463             String httpBody;
464             if (!decoder.decode(httpBody))
465                 return false;
466             request.setHTTPBody(FormData::create(httpBody.utf8()));
467         }
468
469         String firstPartyForCookies;
470         if (!decoder.decode(firstPartyForCookies))
471             return false;
472         request.setFirstPartyForCookies(URL(URL(), firstPartyForCookies));
473
474         resourceRequest = request;
475     }
476
477 #if ENABLE(CACHE_PARTITIONING)
478     String cachePartition;
479     if (!decoder.decode(cachePartition))
480         return false;
481     resourceRequest.setCachePartition(cachePartition);
482 #endif
483
484     return decodePlatformData(decoder, resourceRequest);
485 }
486
487 void ArgumentCoder<ResourceResponse>::encode(ArgumentEncoder& encoder, const ResourceResponse& resourceResponse)
488 {
489 #if PLATFORM(MAC)
490     bool shouldSerializeWebCoreData = !resourceResponse.platformResponseIsUpToDate();
491     encoder << shouldSerializeWebCoreData;
492 #else
493     bool shouldSerializeWebCoreData = true;
494 #endif
495
496     encodePlatformData(encoder, resourceResponse);
497
498     if (shouldSerializeWebCoreData) {
499         bool responseIsNull = resourceResponse.isNull();
500         encoder << responseIsNull;
501         if (responseIsNull)
502             return;
503
504         encoder << resourceResponse.url().string();
505         encoder << static_cast<int32_t>(resourceResponse.httpStatusCode());
506         encoder << resourceResponse.httpHeaderFields();
507
508         encoder << resourceResponse.mimeType();
509         encoder << resourceResponse.textEncodingName();
510         encoder << static_cast<int64_t>(resourceResponse.expectedContentLength());
511         encoder << resourceResponse.httpStatusText();
512         encoder << resourceResponse.suggestedFilename();
513     }
514 }
515
516 bool ArgumentCoder<ResourceResponse>::decode(ArgumentDecoder& decoder, ResourceResponse& resourceResponse)
517 {
518 #if PLATFORM(MAC)
519     bool hasSerializedWebCoreData;
520     if (!decoder.decode(hasSerializedWebCoreData))
521         return false;
522 #else
523     bool hasSerializedWebCoreData = true;
524 #endif
525
526     ResourceResponse response;
527
528     if (!decodePlatformData(decoder, response))
529         return false;
530
531     if (hasSerializedWebCoreData) {
532         bool responseIsNull;
533         if (!decoder.decode(responseIsNull))
534             return false;
535         if (responseIsNull) {
536             resourceResponse = ResourceResponse();
537             return true;
538         }
539
540         String url;
541         if (!decoder.decode(url))
542             return false;
543         response.setURL(URL(URL(), url));
544
545         int32_t httpStatusCode;
546         if (!decoder.decode(httpStatusCode))
547             return false;
548         response.setHTTPStatusCode(httpStatusCode);
549
550         HTTPHeaderMap headers;
551         if (!decoder.decode(headers))
552             return false;
553         for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it)
554             response.setHTTPHeaderField(it->key, it->value);
555
556         String mimeType;
557         if (!decoder.decode(mimeType))
558             return false;
559         response.setMimeType(mimeType);
560
561         String textEncodingName;
562         if (!decoder.decode(textEncodingName))
563             return false;
564         response.setTextEncodingName(textEncodingName);
565
566         int64_t contentLength;
567         if (!decoder.decode(contentLength))
568             return false;
569         response.setExpectedContentLength(contentLength);
570
571         String httpStatusText;
572         if (!decoder.decode(httpStatusText))
573             return false;
574         response.setHTTPStatusText(httpStatusText);
575
576         String suggestedFilename;
577         if (!decoder.decode(suggestedFilename))
578             return false;
579         response.setSuggestedFilename(suggestedFilename);
580     }
581
582     resourceResponse = response;
583
584     return true;
585 }
586
587 void ArgumentCoder<ResourceError>::encode(ArgumentEncoder& encoder, const ResourceError& resourceError)
588 {
589     if (kShouldSerializeWebCoreData) {
590         bool errorIsNull = resourceError.isNull();
591         encoder << errorIsNull;
592         if (errorIsNull)
593             return;
594
595         encoder << resourceError.domain();
596         encoder << resourceError.errorCode();
597         encoder << resourceError.failingURL();
598         encoder << resourceError.localizedDescription();
599         encoder << resourceError.isCancellation();
600         encoder << resourceError.isTimeout();
601     }
602
603     encodePlatformData(encoder, resourceError);
604 }
605
606 bool ArgumentCoder<ResourceError>::decode(ArgumentDecoder& decoder, ResourceError& resourceError)
607 {
608     if (kShouldSerializeWebCoreData) {
609         bool errorIsNull;
610         if (!decoder.decode(errorIsNull))
611             return false;
612         if (errorIsNull) {
613             resourceError = ResourceError();
614             return true;
615         }
616
617         String domain;
618         if (!decoder.decode(domain))
619             return false;
620
621         int errorCode;
622         if (!decoder.decode(errorCode))
623             return false;
624
625         String failingURL;
626         if (!decoder.decode(failingURL))
627             return false;
628
629         String localizedDescription;
630         if (!decoder.decode(localizedDescription))
631             return false;
632
633         bool isCancellation;
634         if (!decoder.decode(isCancellation))
635             return false;
636
637         bool isTimeout;
638         if (!decoder.decode(isTimeout))
639             return false;
640
641         resourceError = ResourceError(domain, errorCode, failingURL, localizedDescription);
642         resourceError.setIsCancellation(isCancellation);
643         resourceError.setIsTimeout(isTimeout);
644     }
645
646     return decodePlatformData(decoder, resourceError);
647 }
648
649 void ArgumentCoder<WindowFeatures>::encode(ArgumentEncoder& encoder, const WindowFeatures& windowFeatures)
650 {
651     encoder << windowFeatures.x;
652     encoder << windowFeatures.y;
653     encoder << windowFeatures.width;
654     encoder << windowFeatures.height;
655     encoder << windowFeatures.xSet;
656     encoder << windowFeatures.ySet;
657     encoder << windowFeatures.widthSet;
658     encoder << windowFeatures.heightSet;
659     encoder << windowFeatures.menuBarVisible;
660     encoder << windowFeatures.statusBarVisible;
661     encoder << windowFeatures.toolBarVisible;
662     encoder << windowFeatures.locationBarVisible;
663     encoder << windowFeatures.scrollbarsVisible;
664     encoder << windowFeatures.resizable;
665     encoder << windowFeatures.fullscreen;
666     encoder << windowFeatures.dialog;
667 }
668
669 bool ArgumentCoder<WindowFeatures>::decode(ArgumentDecoder& decoder, WindowFeatures& windowFeatures)
670 {
671     if (!decoder.decode(windowFeatures.x))
672         return false;
673     if (!decoder.decode(windowFeatures.y))
674         return false;
675     if (!decoder.decode(windowFeatures.width))
676         return false;
677     if (!decoder.decode(windowFeatures.height))
678         return false;
679     if (!decoder.decode(windowFeatures.xSet))
680         return false;
681     if (!decoder.decode(windowFeatures.ySet))
682         return false;
683     if (!decoder.decode(windowFeatures.widthSet))
684         return false;
685     if (!decoder.decode(windowFeatures.heightSet))
686         return false;
687     if (!decoder.decode(windowFeatures.menuBarVisible))
688         return false;
689     if (!decoder.decode(windowFeatures.statusBarVisible))
690         return false;
691     if (!decoder.decode(windowFeatures.toolBarVisible))
692         return false;
693     if (!decoder.decode(windowFeatures.locationBarVisible))
694         return false;
695     if (!decoder.decode(windowFeatures.scrollbarsVisible))
696         return false;
697     if (!decoder.decode(windowFeatures.resizable))
698         return false;
699     if (!decoder.decode(windowFeatures.fullscreen))
700         return false;
701     if (!decoder.decode(windowFeatures.dialog))
702         return false;
703     return true;
704 }
705
706
707 void ArgumentCoder<Color>::encode(ArgumentEncoder& encoder, const Color& color)
708 {
709     if (!color.isValid()) {
710         encoder << false;
711         return;
712     }
713
714     encoder << true;
715     encoder << color.rgb();
716 }
717
718 bool ArgumentCoder<Color>::decode(ArgumentDecoder& decoder, Color& color)
719 {
720     bool isValid;
721     if (!decoder.decode(isValid))
722         return false;
723
724     if (!isValid) {
725         color = Color();
726         return true;
727     }
728
729     RGBA32 rgba;
730     if (!decoder.decode(rgba))
731         return false;
732
733     color = Color(rgba);
734     return true;
735 }
736
737
738 void ArgumentCoder<CompositionUnderline>::encode(ArgumentEncoder& encoder, const CompositionUnderline& underline)
739 {
740     encoder << underline.startOffset;
741     encoder << underline.endOffset;
742     encoder << underline.thick;
743     encoder << underline.color;
744 }
745
746 bool ArgumentCoder<CompositionUnderline>::decode(ArgumentDecoder& decoder, CompositionUnderline& underline)
747 {
748     if (!decoder.decode(underline.startOffset))
749         return false;
750     if (!decoder.decode(underline.endOffset))
751         return false;
752     if (!decoder.decode(underline.thick))
753         return false;
754     if (!decoder.decode(underline.color))
755         return false;
756
757     return true;
758 }
759
760
761 void ArgumentCoder<Cookie>::encode(ArgumentEncoder& encoder, const Cookie& cookie)
762 {
763     encoder << cookie.name;
764     encoder << cookie.value;
765     encoder << cookie.domain;
766     encoder << cookie.path;
767     encoder << cookie.expires;
768     encoder << cookie.httpOnly;
769     encoder << cookie.secure;
770     encoder << cookie.session;
771 }
772
773 bool ArgumentCoder<Cookie>::decode(ArgumentDecoder& decoder, Cookie& cookie)
774 {
775     if (!decoder.decode(cookie.name))
776         return false;
777     if (!decoder.decode(cookie.value))
778         return false;
779     if (!decoder.decode(cookie.domain))
780         return false;
781     if (!decoder.decode(cookie.path))
782         return false;
783     if (!decoder.decode(cookie.expires))
784         return false;
785     if (!decoder.decode(cookie.httpOnly))
786         return false;
787     if (!decoder.decode(cookie.secure))
788         return false;
789     if (!decoder.decode(cookie.session))
790         return false;
791
792     return true;
793 }
794
795
796 #if ENABLE(SQL_DATABASE)
797 void ArgumentCoder<DatabaseDetails>::encode(ArgumentEncoder& encoder, const DatabaseDetails& details)
798 {
799     encoder << details.name();
800     encoder << details.displayName();
801     encoder << details.expectedUsage();
802     encoder << details.currentUsage();
803 }
804     
805 bool ArgumentCoder<DatabaseDetails>::decode(ArgumentDecoder& decoder, DatabaseDetails& details)
806 {
807     String name;
808     if (!decoder.decode(name))
809         return false;
810
811     String displayName;
812     if (!decoder.decode(displayName))
813         return false;
814
815     uint64_t expectedUsage;
816     if (!decoder.decode(expectedUsage))
817         return false;
818
819     uint64_t currentUsage;
820     if (!decoder.decode(currentUsage))
821         return false;
822     
823     details = DatabaseDetails(name, displayName, expectedUsage, currentUsage);
824     return true;
825 }
826
827 #endif
828
829 #if PLATFORM(IOS)
830
831 static void encodeSharedBuffer(ArgumentEncoder& encoder, SharedBuffer* buffer)
832 {
833     SharedMemory::Handle handle;
834     encoder << (buffer ? static_cast<uint64_t>(buffer->size()): 0);
835     if (buffer) {
836         RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(buffer->size());
837         memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
838         sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly);
839         encoder << handle;
840     }
841 }
842
843 static bool decodeSharedBuffer(ArgumentDecoder& decoder, RefPtr<SharedBuffer>& buffer)
844 {
845     uint64_t bufferSize = 0;
846     if (!decoder.decode(bufferSize))
847         return false;
848
849     if (bufferSize) {
850         SharedMemory::Handle handle;
851         if (!decoder.decode(handle))
852             return false;
853
854         RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly);
855         buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), bufferSize);
856     }
857
858     return true;
859 }
860
861 void ArgumentCoder<PasteboardWebContent>::encode(ArgumentEncoder& encoder, const WebCore::PasteboardWebContent& content)
862 {
863     encoder << content.canSmartCopyOrDelete;
864     encoder << content.dataInStringFormat;
865
866     encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get());
867     encodeSharedBuffer(encoder, content.dataInRTFDFormat.get());
868     encodeSharedBuffer(encoder, content.dataInRTFFormat.get());
869
870     encoder << content.clientTypes;
871     encoder << static_cast<uint64_t>(content.clientData.size());
872     for (size_t i = 0; i < content.clientData.size(); i++)
873         encodeSharedBuffer(encoder, content.clientData[i].get());
874 }
875
876 bool ArgumentCoder<PasteboardWebContent>::decode(ArgumentDecoder& decoder, WebCore::PasteboardWebContent& content)
877 {
878     if (!decoder.decode(content.canSmartCopyOrDelete))
879         return false;
880     if (!decoder.decode(content.dataInStringFormat))
881         return false;
882     if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat))
883         return false;
884     if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat))
885         return false;
886     if (!decodeSharedBuffer(decoder, content.dataInRTFFormat))
887         return false;
888     if (!decoder.decode(content.clientTypes))
889         return false;
890     uint64_t clientDataSize;
891     if (!decoder.decode(clientDataSize))
892         return false;
893     if (clientDataSize)
894         content.clientData.resize(clientDataSize);
895     for (size_t i = 0; i < clientDataSize; i++)
896         decodeSharedBuffer(decoder, content.clientData[i]);
897     return true;
898 }
899
900 void ArgumentCoder<PasteboardImage>::encode(ArgumentEncoder& encoder, const WebCore::PasteboardImage& pasteboardImage)
901 {
902     encodeImage(encoder, pasteboardImage.image.get());
903     encoder << pasteboardImage.url.url;
904     encoder << pasteboardImage.url.title;
905     encoder << pasteboardImage.resourceMIMEType;
906     if (pasteboardImage.resourceData)
907         encodeSharedBuffer(encoder, pasteboardImage.resourceData.get());
908 }
909
910 bool ArgumentCoder<PasteboardImage>::decode(ArgumentDecoder& decoder, WebCore::PasteboardImage& pasteboardImage)
911 {
912     if (!decodeImage(decoder, pasteboardImage.image))
913         return false;
914     if (!decoder.decode(pasteboardImage.url.url))
915         return false;
916     if (!decoder.decode(pasteboardImage.url.title))
917         return false;
918     if (!decoder.decode(pasteboardImage.resourceMIMEType))
919         return false;
920     if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData))
921         return false;
922     return true;
923 }
924
925 #endif
926
927 void ArgumentCoder<DictationAlternative>::encode(ArgumentEncoder& encoder, const DictationAlternative& dictationAlternative)
928 {
929     encoder << dictationAlternative.rangeStart;
930     encoder << dictationAlternative.rangeLength;
931     encoder << dictationAlternative.dictationContext;
932 }
933
934 bool ArgumentCoder<DictationAlternative>::decode(ArgumentDecoder& decoder, DictationAlternative& dictationAlternative)
935 {
936     if (!decoder.decode(dictationAlternative.rangeStart))
937         return false;
938     if (!decoder.decode(dictationAlternative.rangeLength))
939         return false;
940     if (!decoder.decode(dictationAlternative.dictationContext))
941         return false;
942     return true;
943 }
944
945
946 void ArgumentCoder<FileChooserSettings>::encode(ArgumentEncoder& encoder, const FileChooserSettings& settings)
947 {
948     encoder << settings.allowsMultipleFiles;
949 #if ENABLE(DIRECTORY_UPLOAD)
950     encoder << settings.allowsDirectoryUpload;
951 #endif
952     encoder << settings.acceptMIMETypes;
953     encoder << settings.selectedFiles;
954 #if ENABLE(MEDIA_CAPTURE)
955     encoder << settings.capture;
956 #endif
957 }
958
959 bool ArgumentCoder<FileChooserSettings>::decode(ArgumentDecoder& decoder, FileChooserSettings& settings)
960 {
961     if (!decoder.decode(settings.allowsMultipleFiles))
962         return false;
963 #if ENABLE(DIRECTORY_UPLOAD)
964     if (!decoder.decode(settings.allowsDirectoryUpload))
965         return false;
966 #endif
967     if (!decoder.decode(settings.acceptMIMETypes))
968         return false;
969     if (!decoder.decode(settings.selectedFiles))
970         return false;
971 #if ENABLE(MEDIA_CAPTURE)
972     if (!decoder.decode(settings.capture))
973         return false;
974 #endif
975
976     return true;
977 }
978
979
980 void ArgumentCoder<GrammarDetail>::encode(ArgumentEncoder& encoder, const GrammarDetail& detail)
981 {
982     encoder << detail.location;
983     encoder << detail.length;
984     encoder << detail.guesses;
985     encoder << detail.userDescription;
986 }
987
988 bool ArgumentCoder<GrammarDetail>::decode(ArgumentDecoder& decoder, GrammarDetail& detail)
989 {
990     if (!decoder.decode(detail.location))
991         return false;
992     if (!decoder.decode(detail.length))
993         return false;
994     if (!decoder.decode(detail.guesses))
995         return false;
996     if (!decoder.decode(detail.userDescription))
997         return false;
998
999     return true;
1000 }
1001
1002 void ArgumentCoder<TextCheckingRequestData>::encode(ArgumentEncoder& encoder, const TextCheckingRequestData& request)
1003 {
1004     encoder << request.sequence();
1005     encoder << request.text();
1006     encoder << request.mask();
1007     encoder.encodeEnum(request.processType());
1008 }
1009
1010 bool ArgumentCoder<TextCheckingRequestData>::decode(ArgumentDecoder& decoder, TextCheckingRequestData& request)
1011 {
1012     int sequence;
1013     if (!decoder.decode(sequence))
1014         return false;
1015
1016     String text;
1017     if (!decoder.decode(text))
1018         return false;
1019
1020     TextCheckingTypeMask mask;
1021     if (!decoder.decode(mask))
1022         return false;
1023
1024     TextCheckingProcessType processType;
1025     if (!decoder.decodeEnum(processType))
1026         return false;
1027
1028     request = TextCheckingRequestData(sequence, text, mask, processType);
1029     return true;
1030 }
1031
1032 void ArgumentCoder<TextCheckingResult>::encode(ArgumentEncoder& encoder, const TextCheckingResult& result)
1033 {
1034     encoder.encodeEnum(result.type);
1035     encoder << result.location;
1036     encoder << result.length;
1037     encoder << result.details;
1038     encoder << result.replacement;
1039 }
1040
1041 bool ArgumentCoder<TextCheckingResult>::decode(ArgumentDecoder& decoder, TextCheckingResult& result)
1042 {
1043     if (!decoder.decodeEnum(result.type))
1044         return false;
1045     if (!decoder.decode(result.location))
1046         return false;
1047     if (!decoder.decode(result.length))
1048         return false;
1049     if (!decoder.decode(result.details))
1050         return false;
1051     if (!decoder.decode(result.replacement))
1052         return false;
1053     return true;
1054 }
1055
1056 void ArgumentCoder<DragSession>::encode(ArgumentEncoder& encoder, const DragSession& result)
1057 {
1058     encoder.encodeEnum(result.operation);
1059     encoder << result.mouseIsOverFileInput;
1060     encoder << result.numberOfItemsToBeAccepted;
1061 }
1062
1063 bool ArgumentCoder<DragSession>::decode(ArgumentDecoder& decoder, DragSession& result)
1064 {
1065     if (!decoder.decodeEnum(result.operation))
1066         return false;
1067     if (!decoder.decode(result.mouseIsOverFileInput))
1068         return false;
1069     if (!decoder.decode(result.numberOfItemsToBeAccepted))
1070         return false;
1071     return true;
1072 }
1073
1074 void ArgumentCoder<URL>::encode(ArgumentEncoder& encoder, const URL& result)
1075 {
1076     encoder << result.string();
1077 }
1078     
1079 bool ArgumentCoder<URL>::decode(ArgumentDecoder& decoder, URL& result)
1080 {
1081     String urlAsString;
1082     if (!decoder.decode(urlAsString))
1083         return false;
1084     result = URL(WebCore::ParsedURLString, urlAsString);
1085     return true;
1086 }
1087
1088 void ArgumentCoder<WebCore::UserStyleSheet>::encode(ArgumentEncoder& encoder, const WebCore::UserStyleSheet& userStyleSheet)
1089 {
1090     encoder << userStyleSheet.source();
1091     encoder << userStyleSheet.url();
1092     encoder << userStyleSheet.whitelist();
1093     encoder << userStyleSheet.blacklist();
1094     encoder.encodeEnum(userStyleSheet.injectedFrames());
1095     encoder.encodeEnum(userStyleSheet.level());
1096 }
1097
1098 bool ArgumentCoder<WebCore::UserStyleSheet>::decode(ArgumentDecoder& decoder, WebCore::UserStyleSheet& userStyleSheet)
1099 {
1100     String source;
1101     if (!decoder.decode(source))
1102         return false;
1103
1104     URL url;
1105     if (!decoder.decode(url))
1106         return false;
1107
1108     Vector<String> whitelist;
1109     if (!decoder.decode(whitelist))
1110         return false;
1111
1112     Vector<String> blacklist;
1113     if (!decoder.decode(blacklist))
1114         return false;
1115
1116     WebCore::UserContentInjectedFrames injectedFrames;
1117     if (!decoder.decodeEnum(injectedFrames))
1118         return false;
1119
1120     WebCore::UserStyleLevel level;
1121     if (!decoder.decodeEnum(level))
1122         return false;
1123
1124     userStyleSheet = WebCore::UserStyleSheet(source, url, whitelist, blacklist, injectedFrames, level);
1125     return true;
1126 }
1127
1128 void ArgumentCoder<WebCore::UserScript>::encode(ArgumentEncoder& encoder, const WebCore::UserScript& userScript)
1129 {
1130     encoder << userScript.source();
1131     encoder << userScript.url();
1132     encoder << userScript.whitelist();
1133     encoder << userScript.blacklist();
1134     encoder.encodeEnum(userScript.injectionTime());
1135     encoder.encodeEnum(userScript.injectedFrames());
1136 }
1137
1138 bool ArgumentCoder<WebCore::UserScript>::decode(ArgumentDecoder& decoder, WebCore::UserScript& userScript)
1139 {
1140     String source;
1141     if (!decoder.decode(source))
1142         return false;
1143
1144     URL url;
1145     if (!decoder.decode(url))
1146         return false;
1147
1148     Vector<String> whitelist;
1149     if (!decoder.decode(whitelist))
1150         return false;
1151
1152     Vector<String> blacklist;
1153     if (!decoder.decode(blacklist))
1154         return false;
1155
1156     WebCore::UserScriptInjectionTime injectionTime;
1157     if (!decoder.decodeEnum(injectionTime))
1158         return false;
1159
1160     WebCore::UserContentInjectedFrames injectedFrames;
1161     if (!decoder.decodeEnum(injectedFrames))
1162         return false;
1163
1164     userScript = WebCore::UserScript(source, url, whitelist, blacklist, injectionTime, injectedFrames);
1165     return true;
1166 }
1167
1168 #if ENABLE(CSS_FILTERS) && !USE(COORDINATED_GRAPHICS)
1169 static void encodeFilterOperation(ArgumentEncoder& encoder, const FilterOperation& filter)
1170 {
1171     encoder.encodeEnum(filter.type());
1172
1173     switch (filter.type()) {
1174     case FilterOperation::REFERENCE: {
1175         const auto& referenceFilter = static_cast<const ReferenceFilterOperation&>(filter);
1176         encoder << referenceFilter.url();
1177         encoder << referenceFilter.fragment();
1178         break;
1179     }
1180     case FilterOperation::GRAYSCALE:
1181     case FilterOperation::SEPIA:
1182     case FilterOperation::SATURATE:
1183     case FilterOperation::HUE_ROTATE:
1184         encoder << static_cast<const BasicColorMatrixFilterOperation&>(filter).amount();
1185         break;
1186     case FilterOperation::INVERT:
1187     case FilterOperation::OPACITY:
1188     case FilterOperation::BRIGHTNESS:
1189     case FilterOperation::CONTRAST:
1190         encoder << static_cast<const BasicComponentTransferFilterOperation&>(filter).amount();
1191         break;
1192     case FilterOperation::BLUR:
1193         encoder << static_cast<const BlurFilterOperation&>(filter).stdDeviation();
1194         break;
1195     case FilterOperation::DROP_SHADOW: {
1196         const auto& dropShadowFilter = static_cast<const DropShadowFilterOperation&>(filter);
1197         encoder << dropShadowFilter.location();
1198         encoder << dropShadowFilter.stdDeviation();
1199         encoder << dropShadowFilter.color();
1200         break;
1201     }
1202 #if ENABLE(CSS_SHADERS)
1203     case FilterOperation::CUSTOM:
1204     case FilterOperation::VALIDATED_CUSTOM:
1205         ASSERT_NOT_REACHED();
1206         break;
1207 #endif
1208     case FilterOperation::PASSTHROUGH:
1209     case FilterOperation::NONE:
1210         break;
1211     };
1212 }
1213
1214 static bool decodeFilterOperation(ArgumentDecoder& decoder, RefPtr<FilterOperation>& filter)
1215 {
1216     FilterOperation::OperationType type;
1217     if (!decoder.decodeEnum(type))
1218         return false;
1219
1220     switch (type) {
1221     case FilterOperation::REFERENCE: {
1222         String url;
1223         String fragment;
1224         if (!decoder.decode(url))
1225             return false;
1226         if (!decoder.decode(fragment))
1227             return false;
1228         filter = ReferenceFilterOperation::create(url, fragment, type);
1229         break;
1230     }
1231     case FilterOperation::GRAYSCALE:
1232     case FilterOperation::SEPIA:
1233     case FilterOperation::SATURATE:
1234     case FilterOperation::HUE_ROTATE: {
1235         double amount;
1236         if (!decoder.decode(amount))
1237             return false;
1238         filter = BasicColorMatrixFilterOperation::create(amount, type);
1239         break;
1240     }
1241     case FilterOperation::INVERT:
1242     case FilterOperation::OPACITY:
1243     case FilterOperation::BRIGHTNESS:
1244     case FilterOperation::CONTRAST: {
1245         double amount;
1246         if (!decoder.decode(amount))
1247             return false;
1248         filter = BasicComponentTransferFilterOperation::create(amount, type);
1249         break;
1250     }
1251     case FilterOperation::BLUR: {
1252         Length stdDeviation;
1253         if (!decoder.decode(stdDeviation))
1254             return false;
1255         filter = BlurFilterOperation::create(stdDeviation, type);
1256         break;
1257     }
1258     case FilterOperation::DROP_SHADOW: {
1259         IntPoint location;
1260         int stdDeviation;
1261         Color color;
1262         if (!decoder.decode(location))
1263             return false;
1264         if (!decoder.decode(stdDeviation))
1265             return false;
1266         if (!decoder.decode(color))
1267             return false;
1268         filter = DropShadowFilterOperation::create(location, stdDeviation, color, type);
1269         break;
1270     }
1271 #if ENABLE(CSS_SHADERS)
1272     case FilterOperation::CUSTOM:
1273     case FilterOperation::VALIDATED_CUSTOM:
1274         ASSERT_NOT_REACHED();
1275         break;
1276 #endif
1277     case FilterOperation::PASSTHROUGH:
1278     case FilterOperation::NONE:
1279         break;
1280     };
1281
1282     return true;
1283 }
1284
1285
1286 void ArgumentCoder<FilterOperations>::encode(ArgumentEncoder& encoder, const FilterOperations& filters)
1287 {
1288     encoder << static_cast<uint64_t>(filters.size());
1289
1290     for (const auto& filter : filters.operations())
1291         encodeFilterOperation(encoder, *filter);
1292 }
1293
1294 bool ArgumentCoder<FilterOperations>::decode(ArgumentDecoder& decoder, FilterOperations& filters)
1295 {
1296     uint64_t filterCount;
1297     if (!decoder.decode(filterCount))
1298         return false;
1299
1300     for (uint64_t i = 0; i < filterCount; ++i) {
1301         RefPtr<FilterOperation> filter;
1302         if (!decodeFilterOperation(decoder, filter))
1303             return false;
1304         filters.operations().append(std::move(filter));
1305     }
1306
1307     return true;
1308 }
1309 #endif // ENABLE(CSS_FILTERS) && !USE(COORDINATED_GRAPHICS)
1310
1311 } // namespace CoreIPC