3b0529a4a959a23bd5d040f5fa008ad7b0fec71f
[WebKit-https.git] / Source / WebKit / Shared / WebCoreArgumentCoders.cpp
1 /*
2  * Copyright (C) 2011-2017 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 "DataReference.h"
30 #include "ShareableBitmap.h"
31 #include "SharedBufferDataReference.h"
32 #include <WebCore/AuthenticationChallenge.h>
33 #include <WebCore/BlobPart.h>
34 #include <WebCore/CacheQueryOptions.h>
35 #include <WebCore/CertificateInfo.h>
36 #include <WebCore/CompositionUnderline.h>
37 #include <WebCore/Credential.h>
38 #include <WebCore/Cursor.h>
39 #include <WebCore/DataListSuggestionPicker.h>
40 #include <WebCore/DatabaseDetails.h>
41 #include <WebCore/DictationAlternative.h>
42 #include <WebCore/DictionaryPopupInfo.h>
43 #include <WebCore/DragData.h>
44 #include <WebCore/EventTrackingRegions.h>
45 #include <WebCore/FetchOptions.h>
46 #include <WebCore/FileChooser.h>
47 #include <WebCore/FilterOperation.h>
48 #include <WebCore/FilterOperations.h>
49 #include <WebCore/FontAttributes.h>
50 #include <WebCore/GraphicsContext.h>
51 #include <WebCore/GraphicsLayer.h>
52 #include <WebCore/IDBGetResult.h>
53 #include <WebCore/Image.h>
54 #include <WebCore/JSDOMExceptionHandling.h>
55 #include <WebCore/Length.h>
56 #include <WebCore/LengthBox.h>
57 #include <WebCore/MediaSelectionOption.h>
58 #include <WebCore/Pasteboard.h>
59 #include <WebCore/Path.h>
60 #include <WebCore/PluginData.h>
61 #include <WebCore/PromisedAttachmentInfo.h>
62 #include <WebCore/ProtectionSpace.h>
63 #include <WebCore/RectEdges.h>
64 #include <WebCore/Region.h>
65 #include <WebCore/ResourceError.h>
66 #include <WebCore/ResourceLoadStatistics.h>
67 #include <WebCore/ResourceRequest.h>
68 #include <WebCore/ResourceResponse.h>
69 #include <WebCore/ScrollingConstraints.h>
70 #include <WebCore/ScrollingCoordinator.h>
71 #include <WebCore/SearchPopupMenu.h>
72 #include <WebCore/SecurityOrigin.h>
73 #include <WebCore/SerializedAttachmentData.h>
74 #include <WebCore/ServiceWorkerClientData.h>
75 #include <WebCore/ServiceWorkerClientIdentifier.h>
76 #include <WebCore/ServiceWorkerData.h>
77 #include <WebCore/ShareData.h>
78 #include <WebCore/TextCheckerClient.h>
79 #include <WebCore/TextIndicator.h>
80 #include <WebCore/TimingFunction.h>
81 #include <WebCore/TransformationMatrix.h>
82 #include <WebCore/UserStyleSheet.h>
83 #include <WebCore/ViewportArguments.h>
84 #include <WebCore/WindowFeatures.h>
85 #include <pal/SessionID.h>
86 #include <wtf/URL.h>
87 #include <wtf/text/CString.h>
88 #include <wtf/text/StringHash.h>
89
90 #if PLATFORM(COCOA)
91 #include "ArgumentCodersCF.h"
92 #include "ArgumentCodersMac.h"
93 #endif
94
95 #if PLATFORM(IOS_FAMILY)
96 #include <WebCore/FloatQuad.h>
97 #include <WebCore/InspectorOverlay.h>
98 #include <WebCore/SelectionRect.h>
99 #include <WebCore/SharedBuffer.h>
100 #endif // PLATFORM(IOS_FAMILY)
101
102 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
103 #include <WebCore/MediaPlaybackTargetContext.h>
104 #endif
105
106 #if ENABLE(MEDIA_SESSION)
107 #include <WebCore/MediaSessionMetadata.h>
108 #endif
109
110 #if ENABLE(MEDIA_STREAM)
111 #include <WebCore/CaptureDevice.h>
112 #include <WebCore/MediaConstraints.h>
113 #endif
114
115 namespace IPC {
116 using namespace WebCore;
117 using namespace WebKit;
118
119 static void encodeSharedBuffer(Encoder& encoder, const SharedBuffer* buffer)
120 {
121     SharedMemory::Handle handle;
122     uint64_t bufferSize = buffer ? buffer->size() : 0;
123     encoder << bufferSize;
124     if (!bufferSize)
125         return;
126
127     auto sharedMemoryBuffer = SharedMemory::allocate(buffer->size());
128     memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
129     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
130     encoder << handle;
131 }
132
133 static bool decodeSharedBuffer(Decoder& decoder, RefPtr<SharedBuffer>& buffer)
134 {
135     uint64_t bufferSize = 0;
136     if (!decoder.decode(bufferSize))
137         return false;
138
139     if (!bufferSize)
140         return true;
141
142     SharedMemory::Handle handle;
143     if (!decoder.decode(handle))
144         return false;
145
146     auto sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
147     buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), bufferSize);
148
149     return true;
150 }
151
152 static void encodeTypesAndData(Encoder& encoder, const Vector<String>& types, const Vector<RefPtr<SharedBuffer>>& data)
153 {
154     ASSERT(types.size() == data.size());
155     encoder << types;
156     encoder << static_cast<uint64_t>(data.size());
157     for (auto& buffer : data)
158         encodeSharedBuffer(encoder, buffer.get());
159 }
160
161 static bool decodeTypesAndData(Decoder& decoder, Vector<String>& types, Vector<RefPtr<SharedBuffer>>& data)
162 {
163     if (!decoder.decode(types))
164         return false;
165
166     uint64_t dataSize;
167     if (!decoder.decode(dataSize))
168         return false;
169
170     ASSERT(dataSize == types.size());
171
172     data.resize(dataSize);
173     for (auto& buffer : data)
174         decodeSharedBuffer(decoder, buffer);
175
176     return true;
177 }
178
179 void ArgumentCoder<AffineTransform>::encode(Encoder& encoder, const AffineTransform& affineTransform)
180 {
181     SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
182 }
183
184 bool ArgumentCoder<AffineTransform>::decode(Decoder& decoder, AffineTransform& affineTransform)
185 {
186     return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
187 }
188
189 void ArgumentCoder<CacheQueryOptions>::encode(Encoder& encoder, const CacheQueryOptions& options)
190 {
191     encoder << options.ignoreSearch;
192     encoder << options.ignoreMethod;
193     encoder << options.ignoreVary;
194     encoder << options.cacheName;
195 }
196
197 bool ArgumentCoder<CacheQueryOptions>::decode(Decoder& decoder, CacheQueryOptions& options)
198 {
199     bool ignoreSearch;
200     if (!decoder.decode(ignoreSearch))
201         return false;
202     bool ignoreMethod;
203     if (!decoder.decode(ignoreMethod))
204         return false;
205     bool ignoreVary;
206     if (!decoder.decode(ignoreVary))
207         return false;
208     String cacheName;
209     if (!decoder.decode(cacheName))
210         return false;
211
212     options.ignoreSearch = ignoreSearch;
213     options.ignoreMethod = ignoreMethod;
214     options.ignoreVary = ignoreVary;
215     options.cacheName = WTFMove(cacheName);
216     return true;
217 }
218
219 void ArgumentCoder<DOMCacheEngine::CacheInfo>::encode(Encoder& encoder, const DOMCacheEngine::CacheInfo& info)
220 {
221     encoder << info.identifier;
222     encoder << info.name;
223 }
224
225 auto ArgumentCoder<DOMCacheEngine::CacheInfo>::decode(Decoder& decoder) -> Optional<DOMCacheEngine::CacheInfo>
226 {
227     Optional<uint64_t> identifier;
228     decoder >> identifier;
229     if (!identifier)
230         return WTF::nullopt;
231     
232     Optional<String> name;
233     decoder >> name;
234     if (!name)
235         return WTF::nullopt;
236     
237     return {{ WTFMove(*identifier), WTFMove(*name) }};
238 }
239
240 void ArgumentCoder<DOMCacheEngine::Record>::encode(Encoder& encoder, const DOMCacheEngine::Record& record)
241 {
242     encoder << record.identifier;
243
244     encoder << record.requestHeadersGuard;
245     encoder << record.request;
246     encoder << record.options;
247     encoder << record.referrer;
248
249     encoder << record.responseHeadersGuard;
250     encoder << record.response;
251     encoder << record.updateResponseCounter;
252     encoder << record.responseBodySize;
253
254     WTF::switchOn(record.responseBody, [&](const Ref<SharedBuffer>& buffer) {
255         encoder << true;
256         encodeSharedBuffer(encoder, buffer.ptr());
257     }, [&](const Ref<FormData>& formData) {
258         encoder << false;
259         encoder << true;
260         formData->encode(encoder);
261     }, [&](const std::nullptr_t&) {
262         encoder << false;
263         encoder << false;
264     });
265 }
266
267 Optional<DOMCacheEngine::Record> ArgumentCoder<DOMCacheEngine::Record>::decode(Decoder& decoder)
268 {
269     uint64_t identifier;
270     if (!decoder.decode(identifier))
271         return WTF::nullopt;
272
273     FetchHeaders::Guard requestHeadersGuard;
274     if (!decoder.decode(requestHeadersGuard))
275         return WTF::nullopt;
276
277     WebCore::ResourceRequest request;
278     if (!decoder.decode(request))
279         return WTF::nullopt;
280
281     Optional<WebCore::FetchOptions> options;
282     decoder >> options;
283     if (!options)
284         return WTF::nullopt;
285
286     String referrer;
287     if (!decoder.decode(referrer))
288         return WTF::nullopt;
289
290     FetchHeaders::Guard responseHeadersGuard;
291     if (!decoder.decode(responseHeadersGuard))
292         return WTF::nullopt;
293
294     WebCore::ResourceResponse response;
295     if (!decoder.decode(response))
296         return WTF::nullopt;
297
298     uint64_t updateResponseCounter;
299     if (!decoder.decode(updateResponseCounter))
300         return WTF::nullopt;
301
302     uint64_t responseBodySize;
303     if (!decoder.decode(responseBodySize))
304         return WTF::nullopt;
305
306     WebCore::DOMCacheEngine::ResponseBody responseBody;
307     bool hasSharedBufferBody;
308     if (!decoder.decode(hasSharedBufferBody))
309         return WTF::nullopt;
310
311     if (hasSharedBufferBody) {
312         RefPtr<SharedBuffer> buffer;
313         if (!decodeSharedBuffer(decoder, buffer))
314             return WTF::nullopt;
315         if (buffer)
316             responseBody = buffer.releaseNonNull();
317     } else {
318         bool hasFormDataBody;
319         if (!decoder.decode(hasFormDataBody))
320             return WTF::nullopt;
321         if (hasFormDataBody) {
322             auto formData = FormData::decode(decoder);
323             if (!formData)
324                 return WTF::nullopt;
325             responseBody = formData.releaseNonNull();
326         }
327     }
328
329     return {{ WTFMove(identifier), WTFMove(updateResponseCounter), WTFMove(requestHeadersGuard), WTFMove(request), WTFMove(options.value()), WTFMove(referrer), WTFMove(responseHeadersGuard), WTFMove(response), WTFMove(responseBody), responseBodySize }};
330 }
331
332 void ArgumentCoder<EventTrackingRegions>::encode(Encoder& encoder, const EventTrackingRegions& eventTrackingRegions)
333 {
334     encoder << eventTrackingRegions.asynchronousDispatchRegion;
335     encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions;
336 }
337
338 bool ArgumentCoder<EventTrackingRegions>::decode(Decoder& decoder, EventTrackingRegions& eventTrackingRegions)
339 {
340     Region asynchronousDispatchRegion;
341     if (!decoder.decode(asynchronousDispatchRegion))
342         return false;
343     HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
344     if (!decoder.decode(eventSpecificSynchronousDispatchRegions))
345         return false;
346     eventTrackingRegions.asynchronousDispatchRegion = WTFMove(asynchronousDispatchRegion);
347     eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions);
348     return true;
349 }
350
351 void ArgumentCoder<TransformationMatrix>::encode(Encoder& encoder, const TransformationMatrix& transformationMatrix)
352 {
353     encoder << transformationMatrix.m11();
354     encoder << transformationMatrix.m12();
355     encoder << transformationMatrix.m13();
356     encoder << transformationMatrix.m14();
357
358     encoder << transformationMatrix.m21();
359     encoder << transformationMatrix.m22();
360     encoder << transformationMatrix.m23();
361     encoder << transformationMatrix.m24();
362
363     encoder << transformationMatrix.m31();
364     encoder << transformationMatrix.m32();
365     encoder << transformationMatrix.m33();
366     encoder << transformationMatrix.m34();
367
368     encoder << transformationMatrix.m41();
369     encoder << transformationMatrix.m42();
370     encoder << transformationMatrix.m43();
371     encoder << transformationMatrix.m44();
372 }
373
374 bool ArgumentCoder<TransformationMatrix>::decode(Decoder& decoder, TransformationMatrix& transformationMatrix)
375 {
376     double m11;
377     if (!decoder.decode(m11))
378         return false;
379     double m12;
380     if (!decoder.decode(m12))
381         return false;
382     double m13;
383     if (!decoder.decode(m13))
384         return false;
385     double m14;
386     if (!decoder.decode(m14))
387         return false;
388
389     double m21;
390     if (!decoder.decode(m21))
391         return false;
392     double m22;
393     if (!decoder.decode(m22))
394         return false;
395     double m23;
396     if (!decoder.decode(m23))
397         return false;
398     double m24;
399     if (!decoder.decode(m24))
400         return false;
401
402     double m31;
403     if (!decoder.decode(m31))
404         return false;
405     double m32;
406     if (!decoder.decode(m32))
407         return false;
408     double m33;
409     if (!decoder.decode(m33))
410         return false;
411     double m34;
412     if (!decoder.decode(m34))
413         return false;
414
415     double m41;
416     if (!decoder.decode(m41))
417         return false;
418     double m42;
419     if (!decoder.decode(m42))
420         return false;
421     double m43;
422     if (!decoder.decode(m43))
423         return false;
424     double m44;
425     if (!decoder.decode(m44))
426         return false;
427
428     transformationMatrix.setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
429     return true;
430 }
431
432 void ArgumentCoder<LinearTimingFunction>::encode(Encoder& encoder, const LinearTimingFunction& timingFunction)
433 {
434     encoder.encodeEnum(timingFunction.type());
435 }
436
437 bool ArgumentCoder<LinearTimingFunction>::decode(Decoder&, LinearTimingFunction&)
438 {
439     // Type is decoded by the caller. Nothing else to decode.
440     return true;
441 }
442
443 void ArgumentCoder<CubicBezierTimingFunction>::encode(Encoder& encoder, const CubicBezierTimingFunction& timingFunction)
444 {
445     encoder.encodeEnum(timingFunction.type());
446     
447     encoder << timingFunction.x1();
448     encoder << timingFunction.y1();
449     encoder << timingFunction.x2();
450     encoder << timingFunction.y2();
451     
452     encoder.encodeEnum(timingFunction.timingFunctionPreset());
453 }
454
455 bool ArgumentCoder<CubicBezierTimingFunction>::decode(Decoder& decoder, CubicBezierTimingFunction& timingFunction)
456 {
457     // Type is decoded by the caller.
458     double x1;
459     if (!decoder.decode(x1))
460         return false;
461
462     double y1;
463     if (!decoder.decode(y1))
464         return false;
465
466     double x2;
467     if (!decoder.decode(x2))
468         return false;
469
470     double y2;
471     if (!decoder.decode(y2))
472         return false;
473
474     CubicBezierTimingFunction::TimingFunctionPreset preset;
475     if (!decoder.decodeEnum(preset))
476         return false;
477
478     timingFunction.setValues(x1, y1, x2, y2);
479     timingFunction.setTimingFunctionPreset(preset);
480
481     return true;
482 }
483
484 void ArgumentCoder<StepsTimingFunction>::encode(Encoder& encoder, const StepsTimingFunction& timingFunction)
485 {
486     encoder.encodeEnum(timingFunction.type());
487     
488     encoder << timingFunction.numberOfSteps();
489     encoder << timingFunction.stepAtStart();
490 }
491
492 bool ArgumentCoder<StepsTimingFunction>::decode(Decoder& decoder, StepsTimingFunction& timingFunction)
493 {
494     // Type is decoded by the caller.
495     int numSteps;
496     if (!decoder.decode(numSteps))
497         return false;
498
499     bool stepAtStart;
500     if (!decoder.decode(stepAtStart))
501         return false;
502
503     timingFunction.setNumberOfSteps(numSteps);
504     timingFunction.setStepAtStart(stepAtStart);
505
506     return true;
507 }
508
509 void ArgumentCoder<SpringTimingFunction>::encode(Encoder& encoder, const SpringTimingFunction& timingFunction)
510 {
511     encoder.encodeEnum(timingFunction.type());
512     
513     encoder << timingFunction.mass();
514     encoder << timingFunction.stiffness();
515     encoder << timingFunction.damping();
516     encoder << timingFunction.initialVelocity();
517 }
518
519 bool ArgumentCoder<SpringTimingFunction>::decode(Decoder& decoder, SpringTimingFunction& timingFunction)
520 {
521     // Type is decoded by the caller.
522     double mass;
523     if (!decoder.decode(mass))
524         return false;
525
526     double stiffness;
527     if (!decoder.decode(stiffness))
528         return false;
529
530     double damping;
531     if (!decoder.decode(damping))
532         return false;
533
534     double initialVelocity;
535     if (!decoder.decode(initialVelocity))
536         return false;
537
538     timingFunction.setValues(mass, stiffness, damping, initialVelocity);
539
540     return true;
541 }
542
543 void ArgumentCoder<FloatPoint>::encode(Encoder& encoder, const FloatPoint& floatPoint)
544 {
545     SimpleArgumentCoder<FloatPoint>::encode(encoder, floatPoint);
546 }
547
548 bool ArgumentCoder<FloatPoint>::decode(Decoder& decoder, FloatPoint& floatPoint)
549 {
550     return SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint);
551 }
552
553 Optional<FloatPoint> ArgumentCoder<FloatPoint>::decode(Decoder& decoder)
554 {
555     FloatPoint floatPoint;
556     if (!SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint))
557         return WTF::nullopt;
558     return WTFMove(floatPoint);
559 }
560
561 void ArgumentCoder<FloatPoint3D>::encode(Encoder& encoder, const FloatPoint3D& floatPoint)
562 {
563     SimpleArgumentCoder<FloatPoint3D>::encode(encoder, floatPoint);
564 }
565
566 bool ArgumentCoder<FloatPoint3D>::decode(Decoder& decoder, FloatPoint3D& floatPoint)
567 {
568     return SimpleArgumentCoder<FloatPoint3D>::decode(decoder, floatPoint);
569 }
570
571
572 void ArgumentCoder<FloatRect>::encode(Encoder& encoder, const FloatRect& floatRect)
573 {
574     SimpleArgumentCoder<FloatRect>::encode(encoder, floatRect);
575 }
576
577 bool ArgumentCoder<FloatRect>::decode(Decoder& decoder, FloatRect& floatRect)
578 {
579     return SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect);
580 }
581
582 Optional<FloatRect> ArgumentCoder<FloatRect>::decode(Decoder& decoder)
583 {
584     FloatRect floatRect;
585     if (!SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect))
586         return WTF::nullopt;
587     return WTFMove(floatRect);
588 }
589
590
591 void ArgumentCoder<FloatBoxExtent>::encode(Encoder& encoder, const FloatBoxExtent& floatBoxExtent)
592 {
593     SimpleArgumentCoder<FloatBoxExtent>::encode(encoder, floatBoxExtent);
594 }
595     
596 bool ArgumentCoder<FloatBoxExtent>::decode(Decoder& decoder, FloatBoxExtent& floatBoxExtent)
597 {
598     return SimpleArgumentCoder<FloatBoxExtent>::decode(decoder, floatBoxExtent);
599 }
600     
601
602 void ArgumentCoder<FloatSize>::encode(Encoder& encoder, const FloatSize& floatSize)
603 {
604     SimpleArgumentCoder<FloatSize>::encode(encoder, floatSize);
605 }
606
607 bool ArgumentCoder<FloatSize>::decode(Decoder& decoder, FloatSize& floatSize)
608 {
609     return SimpleArgumentCoder<FloatSize>::decode(decoder, floatSize);
610 }
611
612
613 void ArgumentCoder<FloatRoundedRect>::encode(Encoder& encoder, const FloatRoundedRect& roundedRect)
614 {
615     SimpleArgumentCoder<FloatRoundedRect>::encode(encoder, roundedRect);
616 }
617
618 bool ArgumentCoder<FloatRoundedRect>::decode(Decoder& decoder, FloatRoundedRect& roundedRect)
619 {
620     return SimpleArgumentCoder<FloatRoundedRect>::decode(decoder, roundedRect);
621 }
622
623 #if PLATFORM(IOS_FAMILY)
624 void ArgumentCoder<FloatQuad>::encode(Encoder& encoder, const FloatQuad& floatQuad)
625 {
626     SimpleArgumentCoder<FloatQuad>::encode(encoder, floatQuad);
627 }
628
629 Optional<FloatQuad> ArgumentCoder<FloatQuad>::decode(Decoder& decoder)
630 {
631     FloatQuad floatQuad;
632     if (!SimpleArgumentCoder<FloatQuad>::decode(decoder, floatQuad))
633         return WTF::nullopt;
634     return WTFMove(floatQuad);
635 }
636
637 void ArgumentCoder<ViewportArguments>::encode(Encoder& encoder, const ViewportArguments& viewportArguments)
638 {
639     SimpleArgumentCoder<ViewportArguments>::encode(encoder, viewportArguments);
640 }
641
642 bool ArgumentCoder<ViewportArguments>::decode(Decoder& decoder, ViewportArguments& viewportArguments)
643 {
644     return SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments);
645 }
646
647 Optional<ViewportArguments> ArgumentCoder<ViewportArguments>::decode(Decoder& decoder)
648 {
649     ViewportArguments viewportArguments;
650     if (!SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments))
651         return WTF::nullopt;
652     return WTFMove(viewportArguments);
653 }
654 #endif // PLATFORM(IOS_FAMILY)
655
656
657 void ArgumentCoder<IntPoint>::encode(Encoder& encoder, const IntPoint& intPoint)
658 {
659     SimpleArgumentCoder<IntPoint>::encode(encoder, intPoint);
660 }
661
662 bool ArgumentCoder<IntPoint>::decode(Decoder& decoder, IntPoint& intPoint)
663 {
664     return SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint);
665 }
666
667 Optional<WebCore::IntPoint> ArgumentCoder<IntPoint>::decode(Decoder& decoder)
668 {
669     IntPoint intPoint;
670     if (!SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint))
671         return WTF::nullopt;
672     return WTFMove(intPoint);
673 }
674
675 void ArgumentCoder<IntRect>::encode(Encoder& encoder, const IntRect& intRect)
676 {
677     SimpleArgumentCoder<IntRect>::encode(encoder, intRect);
678 }
679
680 bool ArgumentCoder<IntRect>::decode(Decoder& decoder, IntRect& intRect)
681 {
682     return SimpleArgumentCoder<IntRect>::decode(decoder, intRect);
683 }
684
685 Optional<IntRect> ArgumentCoder<IntRect>::decode(Decoder& decoder)
686 {
687     IntRect rect;
688     if (!decode(decoder, rect))
689         return WTF::nullopt;
690     return WTFMove(rect);
691 }
692
693 void ArgumentCoder<IntSize>::encode(Encoder& encoder, const IntSize& intSize)
694 {
695     SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
696 }
697
698 bool ArgumentCoder<IntSize>::decode(Decoder& decoder, IntSize& intSize)
699 {
700     return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
701 }
702
703 Optional<IntSize> ArgumentCoder<IntSize>::decode(Decoder& decoder)
704 {
705     IntSize intSize;
706     if (!SimpleArgumentCoder<IntSize>::decode(decoder, intSize))
707         return WTF::nullopt;
708     return WTFMove(intSize);
709 }
710
711 void ArgumentCoder<LayoutSize>::encode(Encoder& encoder, const LayoutSize& layoutSize)
712 {
713     SimpleArgumentCoder<LayoutSize>::encode(encoder, layoutSize);
714 }
715
716 bool ArgumentCoder<LayoutSize>::decode(Decoder& decoder, LayoutSize& layoutSize)
717 {
718     return SimpleArgumentCoder<LayoutSize>::decode(decoder, layoutSize);
719 }
720
721
722 void ArgumentCoder<LayoutPoint>::encode(Encoder& encoder, const LayoutPoint& layoutPoint)
723 {
724     SimpleArgumentCoder<LayoutPoint>::encode(encoder, layoutPoint);
725 }
726
727 bool ArgumentCoder<LayoutPoint>::decode(Decoder& decoder, LayoutPoint& layoutPoint)
728 {
729     return SimpleArgumentCoder<LayoutPoint>::decode(decoder, layoutPoint);
730 }
731
732
733 static void pathEncodeApplierFunction(Encoder& encoder, const PathElement& element)
734 {
735     encoder.encodeEnum(element.type);
736
737     switch (element.type) {
738     case PathElementMoveToPoint: // The points member will contain 1 value.
739         encoder << element.points[0];
740         break;
741     case PathElementAddLineToPoint: // The points member will contain 1 value.
742         encoder << element.points[0];
743         break;
744     case PathElementAddQuadCurveToPoint: // The points member will contain 2 values.
745         encoder << element.points[0];
746         encoder << element.points[1];
747         break;
748     case PathElementAddCurveToPoint: // The points member will contain 3 values.
749         encoder << element.points[0];
750         encoder << element.points[1];
751         encoder << element.points[2];
752         break;
753     case PathElementCloseSubpath: // The points member will contain no values.
754         break;
755     }
756 }
757
758 void ArgumentCoder<Path>::encode(Encoder& encoder, const Path& path)
759 {
760     uint64_t numPoints = 0;
761     path.apply([&numPoints](const PathElement&) {
762         ++numPoints;
763     });
764
765     encoder << numPoints;
766
767     path.apply([&encoder](const PathElement& pathElement) {
768         pathEncodeApplierFunction(encoder, pathElement);
769     });
770 }
771
772 bool ArgumentCoder<Path>::decode(Decoder& decoder, Path& path)
773 {
774     uint64_t numPoints;
775     if (!decoder.decode(numPoints))
776         return false;
777     
778     path.clear();
779
780     for (uint64_t i = 0; i < numPoints; ++i) {
781     
782         PathElementType elementType;
783         if (!decoder.decodeEnum(elementType))
784             return false;
785         
786         switch (elementType) {
787         case PathElementMoveToPoint: { // The points member will contain 1 value.
788             FloatPoint point;
789             if (!decoder.decode(point))
790                 return false;
791             path.moveTo(point);
792             break;
793         }
794         case PathElementAddLineToPoint: { // The points member will contain 1 value.
795             FloatPoint point;
796             if (!decoder.decode(point))
797                 return false;
798             path.addLineTo(point);
799             break;
800         }
801         case PathElementAddQuadCurveToPoint: { // The points member will contain 2 values.
802             FloatPoint controlPoint;
803             if (!decoder.decode(controlPoint))
804                 return false;
805
806             FloatPoint endPoint;
807             if (!decoder.decode(endPoint))
808                 return false;
809
810             path.addQuadCurveTo(controlPoint, endPoint);
811             break;
812         }
813         case PathElementAddCurveToPoint: { // The points member will contain 3 values.
814             FloatPoint controlPoint1;
815             if (!decoder.decode(controlPoint1))
816                 return false;
817
818             FloatPoint controlPoint2;
819             if (!decoder.decode(controlPoint2))
820                 return false;
821
822             FloatPoint endPoint;
823             if (!decoder.decode(endPoint))
824                 return false;
825
826             path.addBezierCurveTo(controlPoint1, controlPoint2, endPoint);
827             break;
828         }
829         case PathElementCloseSubpath: // The points member will contain no values.
830             path.closeSubpath();
831             break;
832         }
833     }
834
835     return true;
836 }
837
838 Optional<Path> ArgumentCoder<Path>::decode(Decoder& decoder)
839 {
840     Path path;
841     if (!decode(decoder, path))
842         return WTF::nullopt;
843
844     return path;
845 }
846
847 void ArgumentCoder<RecentSearch>::encode(Encoder& encoder, const RecentSearch& recentSearch)
848 {
849     encoder << recentSearch.string << recentSearch.time;
850 }
851
852 Optional<RecentSearch> ArgumentCoder<RecentSearch>::decode(Decoder& decoder)
853 {
854     Optional<String> string;
855     decoder >> string;
856     if (!string)
857         return WTF::nullopt;
858     
859     Optional<WallTime> time;
860     decoder >> time;
861     if (!time)
862         return WTF::nullopt;
863     
864     return {{ WTFMove(*string), WTFMove(*time) }};
865 }
866
867 template<> struct ArgumentCoder<Region::Span> {
868     static void encode(Encoder&, const Region::Span&);
869     static Optional<Region::Span> decode(Decoder&);
870 };
871
872 void ArgumentCoder<Region::Span>::encode(Encoder& encoder, const Region::Span& span)
873 {
874     encoder << span.y;
875     encoder << (uint64_t)span.segmentIndex;
876 }
877
878 Optional<Region::Span> ArgumentCoder<Region::Span>::decode(Decoder& decoder)
879 {
880     Region::Span span;
881     if (!decoder.decode(span.y))
882         return WTF::nullopt;
883     
884     uint64_t segmentIndex;
885     if (!decoder.decode(segmentIndex))
886         return WTF::nullopt;
887     
888     span.segmentIndex = segmentIndex;
889     return WTFMove(span);
890 }
891
892 void ArgumentCoder<Region>::encode(Encoder& encoder, const Region& region)
893 {
894     encoder.encode(region.shapeSegments());
895     encoder.encode(region.shapeSpans());
896 }
897
898 bool ArgumentCoder<Region>::decode(Decoder& decoder, Region& region)
899 {
900     Vector<int> segments;
901     if (!decoder.decode(segments))
902         return false;
903
904     Vector<Region::Span> spans;
905     if (!decoder.decode(spans))
906         return false;
907     
908     region.setShapeSegments(segments);
909     region.setShapeSpans(spans);
910     region.updateBoundsFromShape();
911     
912     if (!region.isValid())
913         return false;
914
915     return true;
916 }
917
918 void ArgumentCoder<Length>::encode(Encoder& encoder, const Length& length)
919 {
920     SimpleArgumentCoder<Length>::encode(encoder, length);
921 }
922
923 bool ArgumentCoder<Length>::decode(Decoder& decoder, Length& length)
924 {
925     return SimpleArgumentCoder<Length>::decode(decoder, length);
926 }
927
928
929 void ArgumentCoder<ViewportAttributes>::encode(Encoder& encoder, const ViewportAttributes& viewportAttributes)
930 {
931     SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
932 }
933
934 bool ArgumentCoder<ViewportAttributes>::decode(Decoder& decoder, ViewportAttributes& viewportAttributes)
935 {
936     return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
937 }
938
939
940 void ArgumentCoder<MimeClassInfo>::encode(Encoder& encoder, const MimeClassInfo& mimeClassInfo)
941 {
942     encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions;
943 }
944
945 Optional<MimeClassInfo> ArgumentCoder<MimeClassInfo>::decode(Decoder& decoder)
946 {
947     MimeClassInfo mimeClassInfo;
948     if (!decoder.decode(mimeClassInfo.type))
949         return WTF::nullopt;
950     if (!decoder.decode(mimeClassInfo.desc))
951         return WTF::nullopt;
952     if (!decoder.decode(mimeClassInfo.extensions))
953         return WTF::nullopt;
954
955     return WTFMove(mimeClassInfo);
956 }
957
958
959 void ArgumentCoder<PluginInfo>::encode(Encoder& encoder, const PluginInfo& pluginInfo)
960 {
961     encoder << pluginInfo.name;
962     encoder << pluginInfo.file;
963     encoder << pluginInfo.desc;
964     encoder << pluginInfo.mimes;
965     encoder << pluginInfo.isApplicationPlugin;
966     encoder.encodeEnum(pluginInfo.clientLoadPolicy);
967     encoder << pluginInfo.bundleIdentifier;
968 #if PLATFORM(MAC)
969     encoder << pluginInfo.versionString;
970 #endif
971 }
972
973 Optional<WebCore::PluginInfo> ArgumentCoder<PluginInfo>::decode(Decoder& decoder)
974 {
975     PluginInfo pluginInfo;
976     if (!decoder.decode(pluginInfo.name))
977         return WTF::nullopt;
978     if (!decoder.decode(pluginInfo.file))
979         return WTF::nullopt;
980     if (!decoder.decode(pluginInfo.desc))
981         return WTF::nullopt;
982     if (!decoder.decode(pluginInfo.mimes))
983         return WTF::nullopt;
984     if (!decoder.decode(pluginInfo.isApplicationPlugin))
985         return WTF::nullopt;
986     if (!decoder.decodeEnum(pluginInfo.clientLoadPolicy))
987         return WTF::nullopt;
988     if (!decoder.decode(pluginInfo.bundleIdentifier))
989         return WTF::nullopt;
990 #if PLATFORM(MAC)
991     if (!decoder.decode(pluginInfo.versionString))
992         return WTF::nullopt;
993 #endif
994
995     return WTFMove(pluginInfo);
996 }
997
998 void ArgumentCoder<AuthenticationChallenge>::encode(Encoder& encoder, const AuthenticationChallenge& challenge)
999 {
1000     encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error();
1001 }
1002
1003 bool ArgumentCoder<AuthenticationChallenge>::decode(Decoder& decoder, AuthenticationChallenge& challenge)
1004 {    
1005     ProtectionSpace protectionSpace;
1006     if (!decoder.decode(protectionSpace))
1007         return false;
1008
1009     Credential proposedCredential;
1010     if (!decoder.decode(proposedCredential))
1011         return false;
1012
1013     unsigned previousFailureCount;    
1014     if (!decoder.decode(previousFailureCount))
1015         return false;
1016
1017     ResourceResponse failureResponse;
1018     if (!decoder.decode(failureResponse))
1019         return false;
1020
1021     ResourceError error;
1022     if (!decoder.decode(error))
1023         return false;
1024     
1025     challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
1026     return true;
1027 }
1028
1029
1030 void ArgumentCoder<ProtectionSpace>::encode(Encoder& encoder, const ProtectionSpace& space)
1031 {
1032     if (space.encodingRequiresPlatformData()) {
1033         encoder << true;
1034         encodePlatformData(encoder, space);
1035         return;
1036     }
1037
1038     encoder << false;
1039     encoder << space.host() << space.port() << space.realm();
1040     encoder.encodeEnum(space.authenticationScheme());
1041     encoder.encodeEnum(space.serverType());
1042 }
1043
1044 bool ArgumentCoder<ProtectionSpace>::decode(Decoder& decoder, ProtectionSpace& space)
1045 {
1046     bool hasPlatformData;
1047     if (!decoder.decode(hasPlatformData))
1048         return false;
1049
1050     if (hasPlatformData)
1051         return decodePlatformData(decoder, space);
1052
1053     String host;
1054     if (!decoder.decode(host))
1055         return false;
1056
1057     int port;
1058     if (!decoder.decode(port))
1059         return false;
1060
1061     String realm;
1062     if (!decoder.decode(realm))
1063         return false;
1064     
1065     ProtectionSpaceAuthenticationScheme authenticationScheme;
1066     if (!decoder.decodeEnum(authenticationScheme))
1067         return false;
1068
1069     ProtectionSpaceServerType serverType;
1070     if (!decoder.decodeEnum(serverType))
1071         return false;
1072
1073     space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
1074     return true;
1075 }
1076
1077 void ArgumentCoder<Credential>::encode(Encoder& encoder, const Credential& credential)
1078 {
1079     if (credential.encodingRequiresPlatformData()) {
1080         encoder << true;
1081         encodePlatformData(encoder, credential);
1082         return;
1083     }
1084
1085     encoder << false;
1086     encoder << credential.user() << credential.password();
1087     encoder.encodeEnum(credential.persistence());
1088 }
1089
1090 bool ArgumentCoder<Credential>::decode(Decoder& decoder, Credential& credential)
1091 {
1092     bool hasPlatformData;
1093     if (!decoder.decode(hasPlatformData))
1094         return false;
1095
1096     if (hasPlatformData)
1097         return decodePlatformData(decoder, credential);
1098
1099     String user;
1100     if (!decoder.decode(user))
1101         return false;
1102
1103     String password;
1104     if (!decoder.decode(password))
1105         return false;
1106
1107     CredentialPersistence persistence;
1108     if (!decoder.decodeEnum(persistence))
1109         return false;
1110     
1111     credential = Credential(user, password, persistence);
1112     return true;
1113 }
1114
1115 static void encodeImage(Encoder& encoder, Image& image)
1116 {
1117     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(image.size()), { });
1118     bitmap->createGraphicsContext()->drawImage(image, IntPoint());
1119
1120     ShareableBitmap::Handle handle;
1121     bitmap->createHandle(handle);
1122
1123     encoder << handle;
1124 }
1125
1126 static bool decodeImage(Decoder& decoder, RefPtr<Image>& image)
1127 {
1128     ShareableBitmap::Handle handle;
1129     if (!decoder.decode(handle))
1130         return false;
1131     
1132     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
1133     if (!bitmap)
1134         return false;
1135     image = bitmap->createImage();
1136     if (!image)
1137         return false;
1138     return true;
1139 }
1140
1141 static void encodeOptionalImage(Encoder& encoder, Image* image)
1142 {
1143     bool hasImage = !!image;
1144     encoder << hasImage;
1145
1146     if (hasImage)
1147         encodeImage(encoder, *image);
1148 }
1149
1150 static bool decodeOptionalImage(Decoder& decoder, RefPtr<Image>& image)
1151 {
1152     image = nullptr;
1153
1154     bool hasImage;
1155     if (!decoder.decode(hasImage))
1156         return false;
1157
1158     if (!hasImage)
1159         return true;
1160
1161     return decodeImage(decoder, image);
1162 }
1163
1164 #if !PLATFORM(IOS_FAMILY)
1165 void ArgumentCoder<Cursor>::encode(Encoder& encoder, const Cursor& cursor)
1166 {
1167     encoder.encodeEnum(cursor.type());
1168         
1169     if (cursor.type() != Cursor::Custom)
1170         return;
1171
1172     if (cursor.image()->isNull()) {
1173         encoder << false; // There is no valid image being encoded.
1174         return;
1175     }
1176
1177     encoder << true;
1178     encodeImage(encoder, *cursor.image());
1179     encoder << cursor.hotSpot();
1180 #if ENABLE(MOUSE_CURSOR_SCALE)
1181     encoder << cursor.imageScaleFactor();
1182 #endif
1183 }
1184
1185 bool ArgumentCoder<Cursor>::decode(Decoder& decoder, Cursor& cursor)
1186 {
1187     Cursor::Type type;
1188     if (!decoder.decodeEnum(type))
1189         return false;
1190
1191     if (type > Cursor::Custom)
1192         return false;
1193
1194     if (type != Cursor::Custom) {
1195         const Cursor& cursorReference = Cursor::fromType(type);
1196         // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
1197         // This will avoid having to re-create the platform cursors over and over.
1198         (void)cursorReference.platformCursor();
1199
1200         cursor = cursorReference;
1201         return true;
1202     }
1203
1204     bool isValidImagePresent;
1205     if (!decoder.decode(isValidImagePresent))
1206         return false;
1207
1208     if (!isValidImagePresent) {
1209         cursor = Cursor(&Image::nullImage(), IntPoint());
1210         return true;
1211     }
1212
1213     RefPtr<Image> image;
1214     if (!decodeImage(decoder, image))
1215         return false;
1216
1217     IntPoint hotSpot;
1218     if (!decoder.decode(hotSpot))
1219         return false;
1220
1221     if (!image->rect().contains(hotSpot))
1222         return false;
1223
1224 #if ENABLE(MOUSE_CURSOR_SCALE)
1225     float scale;
1226     if (!decoder.decode(scale))
1227         return false;
1228
1229     cursor = Cursor(image.get(), hotSpot, scale);
1230 #else
1231     cursor = Cursor(image.get(), hotSpot);
1232 #endif
1233     return true;
1234 }
1235 #endif
1236
1237 void ArgumentCoder<ResourceRequest>::encode(Encoder& encoder, const ResourceRequest& resourceRequest)
1238 {
1239     encoder << resourceRequest.cachePartition();
1240     encoder << resourceRequest.hiddenFromInspector();
1241
1242 #if USE(SYSTEM_PREVIEW)
1243     if (resourceRequest.isSystemPreview()) {
1244         encoder << true;
1245         encoder << resourceRequest.systemPreviewRect();
1246     } else
1247         encoder << false;
1248 #endif
1249
1250     if (resourceRequest.encodingRequiresPlatformData()) {
1251         encoder << true;
1252         encodePlatformData(encoder, resourceRequest);
1253         return;
1254     }
1255     encoder << false;
1256     resourceRequest.encodeWithoutPlatformData(encoder);
1257 }
1258
1259 bool ArgumentCoder<ResourceRequest>::decode(Decoder& decoder, ResourceRequest& resourceRequest)
1260 {
1261     String cachePartition;
1262     if (!decoder.decode(cachePartition))
1263         return false;
1264     resourceRequest.setCachePartition(cachePartition);
1265
1266     bool isHiddenFromInspector;
1267     if (!decoder.decode(isHiddenFromInspector))
1268         return false;
1269     resourceRequest.setHiddenFromInspector(isHiddenFromInspector);
1270
1271 #if USE(SYSTEM_PREVIEW)
1272     bool isSystemPreview;
1273     if (!decoder.decode(isSystemPreview))
1274         return false;
1275     resourceRequest.setSystemPreview(isSystemPreview);
1276
1277     if (isSystemPreview) {
1278         IntRect systemPreviewRect;
1279         if (!decoder.decode(systemPreviewRect))
1280             return false;
1281         resourceRequest.setSystemPreviewRect(systemPreviewRect);
1282     }
1283 #endif
1284
1285     bool hasPlatformData;
1286     if (!decoder.decode(hasPlatformData))
1287         return false;
1288     if (hasPlatformData)
1289         return decodePlatformData(decoder, resourceRequest);
1290
1291     return resourceRequest.decodeWithoutPlatformData(decoder);
1292 }
1293
1294 void ArgumentCoder<ResourceError>::encode(Encoder& encoder, const ResourceError& resourceError)
1295 {
1296     encoder.encodeEnum(resourceError.type());
1297     if (resourceError.type() == ResourceError::Type::Null)
1298         return;
1299     encodePlatformData(encoder, resourceError);
1300 }
1301
1302 bool ArgumentCoder<ResourceError>::decode(Decoder& decoder, ResourceError& resourceError)
1303 {
1304     ResourceError::Type type;
1305     if (!decoder.decodeEnum(type))
1306         return false;
1307
1308     if (type == ResourceError::Type::Null) {
1309         resourceError = { };
1310         return true;
1311     }
1312
1313     if (!decodePlatformData(decoder, resourceError))
1314         return false;
1315
1316     resourceError.setType(type);
1317     return true;
1318 }
1319
1320 #if PLATFORM(IOS_FAMILY)
1321
1322 void ArgumentCoder<SelectionRect>::encode(Encoder& encoder, const SelectionRect& selectionRect)
1323 {
1324     encoder << selectionRect.rect();
1325     encoder << static_cast<uint32_t>(selectionRect.direction());
1326     encoder << selectionRect.minX();
1327     encoder << selectionRect.maxX();
1328     encoder << selectionRect.maxY();
1329     encoder << selectionRect.lineNumber();
1330     encoder << selectionRect.isLineBreak();
1331     encoder << selectionRect.isFirstOnLine();
1332     encoder << selectionRect.isLastOnLine();
1333     encoder << selectionRect.containsStart();
1334     encoder << selectionRect.containsEnd();
1335     encoder << selectionRect.isHorizontal();
1336 }
1337
1338 Optional<SelectionRect> ArgumentCoder<SelectionRect>::decode(Decoder& decoder)
1339 {
1340     SelectionRect selectionRect;
1341     IntRect rect;
1342     if (!decoder.decode(rect))
1343         return WTF::nullopt;
1344     selectionRect.setRect(rect);
1345
1346     uint32_t direction;
1347     if (!decoder.decode(direction))
1348         return WTF::nullopt;
1349     selectionRect.setDirection((TextDirection)direction);
1350
1351     int intValue;
1352     if (!decoder.decode(intValue))
1353         return WTF::nullopt;
1354     selectionRect.setMinX(intValue);
1355
1356     if (!decoder.decode(intValue))
1357         return WTF::nullopt;
1358     selectionRect.setMaxX(intValue);
1359
1360     if (!decoder.decode(intValue))
1361         return WTF::nullopt;
1362     selectionRect.setMaxY(intValue);
1363
1364     if (!decoder.decode(intValue))
1365         return WTF::nullopt;
1366     selectionRect.setLineNumber(intValue);
1367
1368     bool boolValue;
1369     if (!decoder.decode(boolValue))
1370         return WTF::nullopt;
1371     selectionRect.setIsLineBreak(boolValue);
1372
1373     if (!decoder.decode(boolValue))
1374         return WTF::nullopt;
1375     selectionRect.setIsFirstOnLine(boolValue);
1376
1377     if (!decoder.decode(boolValue))
1378         return WTF::nullopt;
1379     selectionRect.setIsLastOnLine(boolValue);
1380
1381     if (!decoder.decode(boolValue))
1382         return WTF::nullopt;
1383     selectionRect.setContainsStart(boolValue);
1384
1385     if (!decoder.decode(boolValue))
1386         return WTF::nullopt;
1387     selectionRect.setContainsEnd(boolValue);
1388
1389     if (!decoder.decode(boolValue))
1390         return WTF::nullopt;
1391     selectionRect.setIsHorizontal(boolValue);
1392
1393     return WTFMove(selectionRect);
1394 }
1395
1396 #endif
1397
1398 void ArgumentCoder<WindowFeatures>::encode(Encoder& encoder, const WindowFeatures& windowFeatures)
1399 {
1400     encoder << windowFeatures.x;
1401     encoder << windowFeatures.y;
1402     encoder << windowFeatures.width;
1403     encoder << windowFeatures.height;
1404     encoder << windowFeatures.menuBarVisible;
1405     encoder << windowFeatures.statusBarVisible;
1406     encoder << windowFeatures.toolBarVisible;
1407     encoder << windowFeatures.locationBarVisible;
1408     encoder << windowFeatures.scrollbarsVisible;
1409     encoder << windowFeatures.resizable;
1410     encoder << windowFeatures.fullscreen;
1411     encoder << windowFeatures.dialog;
1412 }
1413
1414 bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& windowFeatures)
1415 {
1416     if (!decoder.decode(windowFeatures.x))
1417         return false;
1418     if (!decoder.decode(windowFeatures.y))
1419         return false;
1420     if (!decoder.decode(windowFeatures.width))
1421         return false;
1422     if (!decoder.decode(windowFeatures.height))
1423         return false;
1424     if (!decoder.decode(windowFeatures.menuBarVisible))
1425         return false;
1426     if (!decoder.decode(windowFeatures.statusBarVisible))
1427         return false;
1428     if (!decoder.decode(windowFeatures.toolBarVisible))
1429         return false;
1430     if (!decoder.decode(windowFeatures.locationBarVisible))
1431         return false;
1432     if (!decoder.decode(windowFeatures.scrollbarsVisible))
1433         return false;
1434     if (!decoder.decode(windowFeatures.resizable))
1435         return false;
1436     if (!decoder.decode(windowFeatures.fullscreen))
1437         return false;
1438     if (!decoder.decode(windowFeatures.dialog))
1439         return false;
1440     return true;
1441 }
1442
1443
1444 void ArgumentCoder<Color>::encode(Encoder& encoder, const Color& color)
1445 {
1446     if (color.isExtended()) {
1447         encoder << true;
1448         encoder << color.asExtended().red();
1449         encoder << color.asExtended().green();
1450         encoder << color.asExtended().blue();
1451         encoder << color.asExtended().alpha();
1452         encoder << color.asExtended().colorSpace();
1453         return;
1454     }
1455
1456     encoder << false;
1457
1458     if (!color.isValid()) {
1459         encoder << false;
1460         return;
1461     }
1462
1463     encoder << true;
1464     encoder << color.rgb();
1465 }
1466
1467 bool ArgumentCoder<Color>::decode(Decoder& decoder, Color& color)
1468 {
1469     bool isExtended;
1470     if (!decoder.decode(isExtended))
1471         return false;
1472
1473     if (isExtended) {
1474         float red;
1475         float green;
1476         float blue;
1477         float alpha;
1478         ColorSpace colorSpace;
1479         if (!decoder.decode(red))
1480             return false;
1481         if (!decoder.decode(green))
1482             return false;
1483         if (!decoder.decode(blue))
1484             return false;
1485         if (!decoder.decode(alpha))
1486             return false;
1487         if (!decoder.decode(colorSpace))
1488             return false;
1489         color = Color(red, green, blue, alpha, colorSpace);
1490         return true;
1491     }
1492
1493     bool isValid;
1494     if (!decoder.decode(isValid))
1495         return false;
1496
1497     if (!isValid) {
1498         color = Color();
1499         return true;
1500     }
1501
1502     RGBA32 rgba;
1503     if (!decoder.decode(rgba))
1504         return false;
1505
1506     color = Color(rgba);
1507     return true;
1508 }
1509
1510 Optional<Color> ArgumentCoder<Color>::decode(Decoder& decoder)
1511 {
1512     Color color;
1513     if (!decode(decoder, color))
1514         return WTF::nullopt;
1515
1516     return color;
1517 }
1518
1519 #if ENABLE(DRAG_SUPPORT)
1520 void ArgumentCoder<DragData>::encode(Encoder& encoder, const DragData& dragData)
1521 {
1522     encoder << dragData.clientPosition();
1523     encoder << dragData.globalPosition();
1524     encoder.encodeEnum(dragData.draggingSourceOperationMask());
1525     encoder.encodeEnum(dragData.flags());
1526 #if PLATFORM(COCOA)
1527     encoder << dragData.pasteboardName();
1528     encoder << dragData.fileNames();
1529 #endif
1530     encoder.encodeEnum(dragData.dragDestinationAction());
1531 }
1532
1533 bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
1534 {
1535     IntPoint clientPosition;
1536     if (!decoder.decode(clientPosition))
1537         return false;
1538
1539     IntPoint globalPosition;
1540     if (!decoder.decode(globalPosition))
1541         return false;
1542
1543     DragOperation draggingSourceOperationMask;
1544     if (!decoder.decodeEnum(draggingSourceOperationMask))
1545         return false;
1546
1547     DragApplicationFlags applicationFlags;
1548     if (!decoder.decodeEnum(applicationFlags))
1549         return false;
1550
1551     String pasteboardName;
1552     Vector<String> fileNames;
1553 #if PLATFORM(COCOA)
1554     if (!decoder.decode(pasteboardName))
1555         return false;
1556
1557     if (!decoder.decode(fileNames))
1558         return false;
1559 #endif
1560
1561     DragDestinationAction destinationAction;
1562     if (!decoder.decodeEnum(destinationAction))
1563         return false;
1564
1565     dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, destinationAction);
1566     dragData.setFileNames(fileNames);
1567
1568     return true;
1569 }
1570 #endif
1571
1572 void ArgumentCoder<CompositionUnderline>::encode(Encoder& encoder, const CompositionUnderline& underline)
1573 {
1574     encoder << underline.startOffset;
1575     encoder << underline.endOffset;
1576     encoder << underline.thick;
1577     encoder << underline.color;
1578 }
1579
1580 Optional<CompositionUnderline> ArgumentCoder<CompositionUnderline>::decode(Decoder& decoder)
1581 {
1582     CompositionUnderline underline;
1583
1584     if (!decoder.decode(underline.startOffset))
1585         return WTF::nullopt;
1586     if (!decoder.decode(underline.endOffset))
1587         return WTF::nullopt;
1588     if (!decoder.decode(underline.thick))
1589         return WTF::nullopt;
1590     if (!decoder.decode(underline.color))
1591         return WTF::nullopt;
1592
1593     return WTFMove(underline);
1594 }
1595
1596 void ArgumentCoder<DatabaseDetails>::encode(Encoder& encoder, const DatabaseDetails& details)
1597 {
1598     encoder << details.name();
1599     encoder << details.displayName();
1600     encoder << details.expectedUsage();
1601     encoder << details.currentUsage();
1602     encoder << details.creationTime();
1603     encoder << details.modificationTime();
1604 }
1605     
1606 bool ArgumentCoder<DatabaseDetails>::decode(Decoder& decoder, DatabaseDetails& details)
1607 {
1608     String name;
1609     if (!decoder.decode(name))
1610         return false;
1611
1612     String displayName;
1613     if (!decoder.decode(displayName))
1614         return false;
1615
1616     uint64_t expectedUsage;
1617     if (!decoder.decode(expectedUsage))
1618         return false;
1619
1620     uint64_t currentUsage;
1621     if (!decoder.decode(currentUsage))
1622         return false;
1623
1624     Optional<WallTime> creationTime;
1625     if (!decoder.decode(creationTime))
1626         return false;
1627
1628     Optional<WallTime> modificationTime;
1629     if (!decoder.decode(modificationTime))
1630         return false;
1631
1632     details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime);
1633     return true;
1634 }
1635
1636 #if ENABLE(DATALIST_ELEMENT)
1637 void ArgumentCoder<DataListSuggestionInformation>::encode(Encoder& encoder, const WebCore::DataListSuggestionInformation& info)
1638 {
1639     encoder.encodeEnum(info.activationType);
1640     encoder << info.suggestions;
1641     encoder << info.elementRect;
1642 }
1643
1644 bool ArgumentCoder<DataListSuggestionInformation>::decode(Decoder& decoder, WebCore::DataListSuggestionInformation& info)
1645 {
1646     if (!decoder.decodeEnum(info.activationType))
1647         return false;
1648
1649     if (!decoder.decode(info.suggestions))
1650         return false;
1651
1652     if (!decoder.decode(info.elementRect))
1653         return false;
1654
1655     return true;
1656 }
1657 #endif
1658
1659 void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
1660 {
1661     encoder << data.origin;
1662     encoder << data.orderedTypes;
1663     encoder << data.platformData;
1664     encoder << data.sameOriginCustomData;
1665 }
1666
1667 bool ArgumentCoder<PasteboardCustomData>::decode(Decoder& decoder, PasteboardCustomData& data)
1668 {
1669     if (!decoder.decode(data.origin))
1670         return false;
1671
1672     if (!decoder.decode(data.orderedTypes))
1673         return false;
1674
1675     if (!decoder.decode(data.platformData))
1676         return false;
1677
1678     if (!decoder.decode(data.sameOriginCustomData))
1679         return false;
1680
1681     return true;
1682 }
1683
1684 void ArgumentCoder<PasteboardURL>::encode(Encoder& encoder, const PasteboardURL& content)
1685 {
1686     encoder << content.url;
1687     encoder << content.title;
1688 #if PLATFORM(MAC)
1689     encoder << content.userVisibleForm;
1690 #endif
1691 #if PLATFORM(GTK)
1692     encoder << content.markup;
1693 #endif
1694 }
1695
1696 bool ArgumentCoder<PasteboardURL>::decode(Decoder& decoder, PasteboardURL& content)
1697 {
1698     if (!decoder.decode(content.url))
1699         return false;
1700
1701     if (!decoder.decode(content.title))
1702         return false;
1703
1704 #if PLATFORM(MAC)
1705     if (!decoder.decode(content.userVisibleForm))
1706         return false;
1707 #endif
1708 #if PLATFORM(GTK)
1709     if (!decoder.decode(content.markup))
1710         return false;
1711 #endif
1712
1713     return true;
1714 }
1715
1716 #if PLATFORM(IOS_FAMILY)
1717
1718 void ArgumentCoder<Highlight>::encode(Encoder& encoder, const Highlight& highlight)
1719 {
1720     encoder << static_cast<uint32_t>(highlight.type);
1721     encoder << highlight.usePageCoordinates;
1722     encoder << highlight.contentColor;
1723     encoder << highlight.contentOutlineColor;
1724     encoder << highlight.paddingColor;
1725     encoder << highlight.borderColor;
1726     encoder << highlight.marginColor;
1727     encoder << highlight.quads;
1728 }
1729
1730 bool ArgumentCoder<Highlight>::decode(Decoder& decoder, Highlight& highlight)
1731 {
1732     uint32_t type;
1733     if (!decoder.decode(type))
1734         return false;
1735     highlight.type = (HighlightType)type;
1736
1737     if (!decoder.decode(highlight.usePageCoordinates))
1738         return false;
1739     if (!decoder.decode(highlight.contentColor))
1740         return false;
1741     if (!decoder.decode(highlight.contentOutlineColor))
1742         return false;
1743     if (!decoder.decode(highlight.paddingColor))
1744         return false;
1745     if (!decoder.decode(highlight.borderColor))
1746         return false;
1747     if (!decoder.decode(highlight.marginColor))
1748         return false;
1749     if (!decoder.decode(highlight.quads))
1750         return false;
1751     return true;
1752 }
1753
1754 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1755 {
1756     encoder << content.contentOrigin;
1757     encoder << content.canSmartCopyOrDelete;
1758     encoder << content.dataInStringFormat;
1759     encoder << content.dataInHTMLFormat;
1760
1761     encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get());
1762     encodeSharedBuffer(encoder, content.dataInRTFDFormat.get());
1763     encodeSharedBuffer(encoder, content.dataInRTFFormat.get());
1764     encodeSharedBuffer(encoder, content.dataInAttributedStringFormat.get());
1765
1766     encodeTypesAndData(encoder, content.clientTypes, content.clientData);
1767 }
1768
1769 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1770 {
1771     if (!decoder.decode(content.contentOrigin))
1772         return false;
1773     if (!decoder.decode(content.canSmartCopyOrDelete))
1774         return false;
1775     if (!decoder.decode(content.dataInStringFormat))
1776         return false;
1777     if (!decoder.decode(content.dataInHTMLFormat))
1778         return false;
1779     if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat))
1780         return false;
1781     if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat))
1782         return false;
1783     if (!decodeSharedBuffer(decoder, content.dataInRTFFormat))
1784         return false;
1785     if (!decodeSharedBuffer(decoder, content.dataInAttributedStringFormat))
1786         return false;
1787     if (!decodeTypesAndData(decoder, content.clientTypes, content.clientData))
1788         return false;
1789     return true;
1790 }
1791
1792 void ArgumentCoder<PasteboardImage>::encode(Encoder& encoder, const PasteboardImage& pasteboardImage)
1793 {
1794     encodeOptionalImage(encoder, pasteboardImage.image.get());
1795     encoder << pasteboardImage.url.url;
1796     encoder << pasteboardImage.url.title;
1797     encoder << pasteboardImage.resourceMIMEType;
1798     encoder << pasteboardImage.suggestedName;
1799     encoder << pasteboardImage.imageSize;
1800     if (pasteboardImage.resourceData)
1801         encodeSharedBuffer(encoder, pasteboardImage.resourceData.get());
1802     encodeTypesAndData(encoder, pasteboardImage.clientTypes, pasteboardImage.clientData);
1803 }
1804
1805 bool ArgumentCoder<PasteboardImage>::decode(Decoder& decoder, PasteboardImage& pasteboardImage)
1806 {
1807     if (!decodeOptionalImage(decoder, pasteboardImage.image))
1808         return false;
1809     if (!decoder.decode(pasteboardImage.url.url))
1810         return false;
1811     if (!decoder.decode(pasteboardImage.url.title))
1812         return false;
1813     if (!decoder.decode(pasteboardImage.resourceMIMEType))
1814         return false;
1815     if (!decoder.decode(pasteboardImage.suggestedName))
1816         return false;
1817     if (!decoder.decode(pasteboardImage.imageSize))
1818         return false;
1819     if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData))
1820         return false;
1821     if (!decodeTypesAndData(decoder, pasteboardImage.clientTypes, pasteboardImage.clientData))
1822         return false;
1823     return true;
1824 }
1825
1826 #endif
1827
1828 #if USE(LIBWPE)
1829 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1830 {
1831     encoder << content.text;
1832     encoder << content.markup;
1833 }
1834
1835 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1836 {
1837     if (!decoder.decode(content.text))
1838         return false;
1839     if (!decoder.decode(content.markup))
1840         return false;
1841     return true;
1842 }
1843 #endif // USE(LIBWPE)
1844
1845 void ArgumentCoder<DictationAlternative>::encode(Encoder& encoder, const DictationAlternative& dictationAlternative)
1846 {
1847     encoder << dictationAlternative.rangeStart;
1848     encoder << dictationAlternative.rangeLength;
1849     encoder << dictationAlternative.dictationContext;
1850 }
1851
1852 Optional<DictationAlternative> ArgumentCoder<DictationAlternative>::decode(Decoder& decoder)
1853 {
1854     Optional<unsigned> rangeStart;
1855     decoder >> rangeStart;
1856     if (!rangeStart)
1857         return WTF::nullopt;
1858     
1859     Optional<unsigned> rangeLength;
1860     decoder >> rangeLength;
1861     if (!rangeLength)
1862         return WTF::nullopt;
1863     
1864     Optional<uint64_t> dictationContext;
1865     decoder >> dictationContext;
1866     if (!dictationContext)
1867         return WTF::nullopt;
1868     
1869     return {{ WTFMove(*rangeStart), WTFMove(*rangeLength), WTFMove(*dictationContext) }};
1870 }
1871
1872 void ArgumentCoder<FileChooserSettings>::encode(Encoder& encoder, const FileChooserSettings& settings)
1873 {
1874     encoder << settings.allowsDirectories;
1875     encoder << settings.allowsMultipleFiles;
1876     encoder << settings.acceptMIMETypes;
1877     encoder << settings.acceptFileExtensions;
1878     encoder << settings.selectedFiles;
1879 #if ENABLE(MEDIA_CAPTURE)
1880     encoder.encodeEnum(settings.mediaCaptureType);
1881 #endif
1882 }
1883
1884 bool ArgumentCoder<FileChooserSettings>::decode(Decoder& decoder, FileChooserSettings& settings)
1885 {
1886     if (!decoder.decode(settings.allowsDirectories))
1887         return false;
1888     if (!decoder.decode(settings.allowsMultipleFiles))
1889         return false;
1890     if (!decoder.decode(settings.acceptMIMETypes))
1891         return false;
1892     if (!decoder.decode(settings.acceptFileExtensions))
1893         return false;
1894     if (!decoder.decode(settings.selectedFiles))
1895         return false;
1896 #if ENABLE(MEDIA_CAPTURE)
1897     if (!decoder.decodeEnum(settings.mediaCaptureType))
1898         return false;
1899 #endif
1900
1901     return true;
1902 }
1903     
1904 void ArgumentCoder<ShareData>::encode(Encoder& encoder, const ShareData& settings)
1905 {
1906     encoder << settings.title;
1907     encoder << settings.text;
1908     encoder << settings.url;
1909 }
1910
1911 bool ArgumentCoder<ShareData>::decode(Decoder& decoder, ShareData& settings)
1912 {
1913     if (!decoder.decode(settings.title))
1914         return false;
1915     if (!decoder.decode(settings.text))
1916         return false;
1917     if (!decoder.decode(settings.url))
1918         return false;
1919     return true;
1920 }
1921     
1922 void ArgumentCoder<ShareDataWithParsedURL>::encode(Encoder& encoder, const ShareDataWithParsedURL& settings)
1923 {
1924     encoder << settings.shareData;
1925     encoder << settings.url;
1926 }
1927
1928 bool ArgumentCoder<ShareDataWithParsedURL>::decode(Decoder& decoder, ShareDataWithParsedURL& settings)
1929 {
1930     if (!decoder.decode(settings.shareData))
1931         return false;
1932     if (!decoder.decode(settings.url))
1933         return false;
1934     return true;
1935 }
1936
1937 void ArgumentCoder<GrammarDetail>::encode(Encoder& encoder, const GrammarDetail& detail)
1938 {
1939     encoder << detail.location;
1940     encoder << detail.length;
1941     encoder << detail.guesses;
1942     encoder << detail.userDescription;
1943 }
1944
1945 Optional<GrammarDetail> ArgumentCoder<GrammarDetail>::decode(Decoder& decoder)
1946 {
1947     Optional<int> location;
1948     decoder >> location;
1949     if (!location)
1950         return WTF::nullopt;
1951
1952     Optional<int> length;
1953     decoder >> length;
1954     if (!length)
1955         return WTF::nullopt;
1956
1957     Optional<Vector<String>> guesses;
1958     decoder >> guesses;
1959     if (!guesses)
1960         return WTF::nullopt;
1961
1962     Optional<String> userDescription;
1963     decoder >> userDescription;
1964     if (!userDescription)
1965         return WTF::nullopt;
1966
1967     return {{ WTFMove(*location), WTFMove(*length), WTFMove(*guesses), WTFMove(*userDescription) }};
1968 }
1969
1970 void ArgumentCoder<TextCheckingRequestData>::encode(Encoder& encoder, const TextCheckingRequestData& request)
1971 {
1972     encoder << request.sequence();
1973     encoder << request.text();
1974     encoder << request.checkingTypes();
1975     encoder.encodeEnum(request.processType());
1976 }
1977
1978 bool ArgumentCoder<TextCheckingRequestData>::decode(Decoder& decoder, TextCheckingRequestData& request)
1979 {
1980     int sequence;
1981     if (!decoder.decode(sequence))
1982         return false;
1983
1984     String text;
1985     if (!decoder.decode(text))
1986         return false;
1987
1988     OptionSet<TextCheckingType> checkingTypes;
1989     if (!decoder.decode(checkingTypes))
1990         return false;
1991
1992     TextCheckingProcessType processType;
1993     if (!decoder.decodeEnum(processType))
1994         return false;
1995
1996     request = TextCheckingRequestData { sequence, text, checkingTypes, processType };
1997     return true;
1998 }
1999
2000 void ArgumentCoder<TextCheckingResult>::encode(Encoder& encoder, const TextCheckingResult& result)
2001 {
2002     encoder.encodeEnum(result.type);
2003     encoder << result.location;
2004     encoder << result.length;
2005     encoder << result.details;
2006     encoder << result.replacement;
2007 }
2008
2009 Optional<TextCheckingResult> ArgumentCoder<TextCheckingResult>::decode(Decoder& decoder)
2010 {
2011     TextCheckingType type;
2012     if (!decoder.decodeEnum(type))
2013         return WTF::nullopt;
2014     
2015     Optional<int> location;
2016     decoder >> location;
2017     if (!location)
2018         return WTF::nullopt;
2019
2020     Optional<int> length;
2021     decoder >> length;
2022     if (!length)
2023         return WTF::nullopt;
2024
2025     Optional<Vector<GrammarDetail>> details;
2026     decoder >> details;
2027     if (!details)
2028         return WTF::nullopt;
2029
2030     Optional<String> replacement;
2031     decoder >> replacement;
2032     if (!replacement)
2033         return WTF::nullopt;
2034
2035     return {{ WTFMove(type), WTFMove(*location), WTFMove(*length), WTFMove(*details), WTFMove(*replacement) }};
2036 }
2037
2038 void ArgumentCoder<UserStyleSheet>::encode(Encoder& encoder, const UserStyleSheet& userStyleSheet)
2039 {
2040     encoder << userStyleSheet.source();
2041     encoder << userStyleSheet.url();
2042     encoder << userStyleSheet.whitelist();
2043     encoder << userStyleSheet.blacklist();
2044     encoder.encodeEnum(userStyleSheet.injectedFrames());
2045     encoder.encodeEnum(userStyleSheet.level());
2046 }
2047
2048 bool ArgumentCoder<UserStyleSheet>::decode(Decoder& decoder, UserStyleSheet& userStyleSheet)
2049 {
2050     String source;
2051     if (!decoder.decode(source))
2052         return false;
2053
2054     URL url;
2055     if (!decoder.decode(url))
2056         return false;
2057
2058     Vector<String> whitelist;
2059     if (!decoder.decode(whitelist))
2060         return false;
2061
2062     Vector<String> blacklist;
2063     if (!decoder.decode(blacklist))
2064         return false;
2065
2066     UserContentInjectedFrames injectedFrames;
2067     if (!decoder.decodeEnum(injectedFrames))
2068         return false;
2069
2070     UserStyleLevel level;
2071     if (!decoder.decodeEnum(level))
2072         return false;
2073
2074     userStyleSheet = UserStyleSheet(source, url, WTFMove(whitelist), WTFMove(blacklist), injectedFrames, level);
2075     return true;
2076 }
2077
2078 #if ENABLE(MEDIA_SESSION)
2079 void ArgumentCoder<MediaSessionMetadata>::encode(Encoder& encoder, const MediaSessionMetadata& result)
2080 {
2081     encoder << result.artist();
2082     encoder << result.album();
2083     encoder << result.title();
2084     encoder << result.artworkURL();
2085 }
2086
2087 bool ArgumentCoder<MediaSessionMetadata>::decode(Decoder& decoder, MediaSessionMetadata& result)
2088 {
2089     String artist, album, title;
2090     URL artworkURL;
2091     if (!decoder.decode(artist))
2092         return false;
2093     if (!decoder.decode(album))
2094         return false;
2095     if (!decoder.decode(title))
2096         return false;
2097     if (!decoder.decode(artworkURL))
2098         return false;
2099     result = MediaSessionMetadata(title, artist, album, artworkURL);
2100     return true;
2101 }
2102 #endif
2103
2104 void ArgumentCoder<ScrollableAreaParameters>::encode(Encoder& encoder, const ScrollableAreaParameters& parameters)
2105 {
2106     encoder.encodeEnum(parameters.horizontalScrollElasticity);
2107     encoder.encodeEnum(parameters.verticalScrollElasticity);
2108
2109     encoder.encodeEnum(parameters.horizontalScrollbarMode);
2110     encoder.encodeEnum(parameters.verticalScrollbarMode);
2111
2112     encoder << parameters.hasEnabledHorizontalScrollbar;
2113     encoder << parameters.hasEnabledVerticalScrollbar;
2114
2115     encoder << parameters.useDarkAppearanceForScrollbars;
2116 }
2117
2118 bool ArgumentCoder<ScrollableAreaParameters>::decode(Decoder& decoder, ScrollableAreaParameters& params)
2119 {
2120     if (!decoder.decodeEnum(params.horizontalScrollElasticity))
2121         return false;
2122     if (!decoder.decodeEnum(params.verticalScrollElasticity))
2123         return false;
2124
2125     if (!decoder.decodeEnum(params.horizontalScrollbarMode))
2126         return false;
2127     if (!decoder.decodeEnum(params.verticalScrollbarMode))
2128         return false;
2129
2130     if (!decoder.decode(params.hasEnabledHorizontalScrollbar))
2131         return false;
2132     if (!decoder.decode(params.hasEnabledVerticalScrollbar))
2133         return false;
2134
2135     if (!decoder.decode(params.useDarkAppearanceForScrollbars))
2136         return false;
2137
2138     return true;
2139 }
2140
2141 void ArgumentCoder<FixedPositionViewportConstraints>::encode(Encoder& encoder, const FixedPositionViewportConstraints& viewportConstraints)
2142 {
2143     encoder << viewportConstraints.alignmentOffset();
2144     encoder << viewportConstraints.anchorEdges();
2145
2146     encoder << viewportConstraints.viewportRectAtLastLayout();
2147     encoder << viewportConstraints.layerPositionAtLastLayout();
2148 }
2149
2150 bool ArgumentCoder<FixedPositionViewportConstraints>::decode(Decoder& decoder, FixedPositionViewportConstraints& viewportConstraints)
2151 {
2152     FloatSize alignmentOffset;
2153     if (!decoder.decode(alignmentOffset))
2154         return false;
2155     
2156     ViewportConstraints::AnchorEdges anchorEdges;
2157     if (!decoder.decode(anchorEdges))
2158         return false;
2159
2160     FloatRect viewportRectAtLastLayout;
2161     if (!decoder.decode(viewportRectAtLastLayout))
2162         return false;
2163
2164     FloatPoint layerPositionAtLastLayout;
2165     if (!decoder.decode(layerPositionAtLastLayout))
2166         return false;
2167
2168     viewportConstraints = FixedPositionViewportConstraints();
2169     viewportConstraints.setAlignmentOffset(alignmentOffset);
2170     viewportConstraints.setAnchorEdges(anchorEdges);
2171
2172     viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout);
2173     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2174     
2175     return true;
2176 }
2177
2178 void ArgumentCoder<StickyPositionViewportConstraints>::encode(Encoder& encoder, const StickyPositionViewportConstraints& viewportConstraints)
2179 {
2180     encoder << viewportConstraints.alignmentOffset();
2181     encoder << viewportConstraints.anchorEdges();
2182
2183     encoder << viewportConstraints.leftOffset();
2184     encoder << viewportConstraints.rightOffset();
2185     encoder << viewportConstraints.topOffset();
2186     encoder << viewportConstraints.bottomOffset();
2187
2188     encoder << viewportConstraints.constrainingRectAtLastLayout();
2189     encoder << viewportConstraints.containingBlockRect();
2190     encoder << viewportConstraints.stickyBoxRect();
2191
2192     encoder << viewportConstraints.stickyOffsetAtLastLayout();
2193     encoder << viewportConstraints.layerPositionAtLastLayout();
2194 }
2195
2196 bool ArgumentCoder<StickyPositionViewportConstraints>::decode(Decoder& decoder, StickyPositionViewportConstraints& viewportConstraints)
2197 {
2198     FloatSize alignmentOffset;
2199     if (!decoder.decode(alignmentOffset))
2200         return false;
2201     
2202     ViewportConstraints::AnchorEdges anchorEdges;
2203     if (!decoder.decode(anchorEdges))
2204         return false;
2205     
2206     float leftOffset;
2207     if (!decoder.decode(leftOffset))
2208         return false;
2209
2210     float rightOffset;
2211     if (!decoder.decode(rightOffset))
2212         return false;
2213
2214     float topOffset;
2215     if (!decoder.decode(topOffset))
2216         return false;
2217
2218     float bottomOffset;
2219     if (!decoder.decode(bottomOffset))
2220         return false;
2221     
2222     FloatRect constrainingRectAtLastLayout;
2223     if (!decoder.decode(constrainingRectAtLastLayout))
2224         return false;
2225
2226     FloatRect containingBlockRect;
2227     if (!decoder.decode(containingBlockRect))
2228         return false;
2229
2230     FloatRect stickyBoxRect;
2231     if (!decoder.decode(stickyBoxRect))
2232         return false;
2233
2234     FloatSize stickyOffsetAtLastLayout;
2235     if (!decoder.decode(stickyOffsetAtLastLayout))
2236         return false;
2237     
2238     FloatPoint layerPositionAtLastLayout;
2239     if (!decoder.decode(layerPositionAtLastLayout))
2240         return false;
2241     
2242     viewportConstraints = StickyPositionViewportConstraints();
2243     viewportConstraints.setAlignmentOffset(alignmentOffset);
2244     viewportConstraints.setAnchorEdges(anchorEdges);
2245
2246     viewportConstraints.setLeftOffset(leftOffset);
2247     viewportConstraints.setRightOffset(rightOffset);
2248     viewportConstraints.setTopOffset(topOffset);
2249     viewportConstraints.setBottomOffset(bottomOffset);
2250     
2251     viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout);
2252     viewportConstraints.setContainingBlockRect(containingBlockRect);
2253     viewportConstraints.setStickyBoxRect(stickyBoxRect);
2254
2255     viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout);
2256     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2257
2258     return true;
2259 }
2260
2261 #if !USE(COORDINATED_GRAPHICS)
2262 void ArgumentCoder<FilterOperation>::encode(Encoder& encoder, const FilterOperation& filter)
2263 {
2264     encoder.encodeEnum(filter.type());
2265
2266     switch (filter.type()) {
2267     case FilterOperation::NONE:
2268     case FilterOperation::REFERENCE:
2269         ASSERT_NOT_REACHED();
2270         break;
2271     case FilterOperation::GRAYSCALE:
2272     case FilterOperation::SEPIA:
2273     case FilterOperation::SATURATE:
2274     case FilterOperation::HUE_ROTATE:
2275         encoder << downcast<BasicColorMatrixFilterOperation>(filter).amount();
2276         break;
2277     case FilterOperation::INVERT:
2278     case FilterOperation::OPACITY:
2279     case FilterOperation::BRIGHTNESS:
2280     case FilterOperation::CONTRAST:
2281         encoder << downcast<BasicComponentTransferFilterOperation>(filter).amount();
2282         break;
2283     case FilterOperation::APPLE_INVERT_LIGHTNESS:
2284         ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
2285         break;
2286     case FilterOperation::BLUR:
2287         encoder << downcast<BlurFilterOperation>(filter).stdDeviation();
2288         break;
2289     case FilterOperation::DROP_SHADOW: {
2290         const auto& dropShadowFilter = downcast<DropShadowFilterOperation>(filter);
2291         encoder << dropShadowFilter.location();
2292         encoder << dropShadowFilter.stdDeviation();
2293         encoder << dropShadowFilter.color();
2294         break;
2295     }
2296     case FilterOperation::DEFAULT:
2297         encoder.encodeEnum(downcast<DefaultFilterOperation>(filter).representedType());
2298         break;
2299     case FilterOperation::PASSTHROUGH:
2300         break;
2301     }
2302 }
2303
2304 bool decodeFilterOperation(Decoder& decoder, RefPtr<FilterOperation>& filter)
2305 {
2306     FilterOperation::OperationType type;
2307     if (!decoder.decodeEnum(type))
2308         return false;
2309
2310     switch (type) {
2311     case FilterOperation::NONE:
2312     case FilterOperation::REFERENCE:
2313         ASSERT_NOT_REACHED();
2314         decoder.markInvalid();
2315         return false;
2316     case FilterOperation::GRAYSCALE:
2317     case FilterOperation::SEPIA:
2318     case FilterOperation::SATURATE:
2319     case FilterOperation::HUE_ROTATE: {
2320         double amount;
2321         if (!decoder.decode(amount))
2322             return false;
2323         filter = BasicColorMatrixFilterOperation::create(amount, type);
2324         break;
2325     }
2326     case FilterOperation::INVERT:
2327     case FilterOperation::OPACITY:
2328     case FilterOperation::BRIGHTNESS:
2329     case FilterOperation::CONTRAST: {
2330         double amount;
2331         if (!decoder.decode(amount))
2332             return false;
2333         filter = BasicComponentTransferFilterOperation::create(amount, type);
2334         break;
2335     }
2336     case FilterOperation::APPLE_INVERT_LIGHTNESS:
2337         ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
2338         break;
2339     case FilterOperation::BLUR: {
2340         Length stdDeviation;
2341         if (!decoder.decode(stdDeviation))
2342             return false;
2343         filter = BlurFilterOperation::create(stdDeviation);
2344         break;
2345     }
2346     case FilterOperation::DROP_SHADOW: {
2347         IntPoint location;
2348         int stdDeviation;
2349         Color color;
2350         if (!decoder.decode(location))
2351             return false;
2352         if (!decoder.decode(stdDeviation))
2353             return false;
2354         if (!decoder.decode(color))
2355             return false;
2356         filter = DropShadowFilterOperation::create(location, stdDeviation, color);
2357         break;
2358     }
2359     case FilterOperation::DEFAULT: {
2360         FilterOperation::OperationType representedType;
2361         if (!decoder.decodeEnum(representedType))
2362             return false;
2363         filter = DefaultFilterOperation::create(representedType);
2364         break;
2365     }
2366     case FilterOperation::PASSTHROUGH:
2367         filter = PassthroughFilterOperation::create();
2368         break;
2369     }
2370             
2371     return true;
2372 }
2373
2374
2375 void ArgumentCoder<FilterOperations>::encode(Encoder& encoder, const FilterOperations& filters)
2376 {
2377     encoder << static_cast<uint64_t>(filters.size());
2378
2379     for (const auto& filter : filters.operations())
2380         encoder << *filter;
2381 }
2382
2383 bool ArgumentCoder<FilterOperations>::decode(Decoder& decoder, FilterOperations& filters)
2384 {
2385     uint64_t filterCount;
2386     if (!decoder.decode(filterCount))
2387         return false;
2388
2389     for (uint64_t i = 0; i < filterCount; ++i) {
2390         RefPtr<FilterOperation> filter;
2391         if (!decodeFilterOperation(decoder, filter))
2392             return false;
2393         filters.operations().append(WTFMove(filter));
2394     }
2395
2396     return true;
2397 }
2398 #endif // !USE(COORDINATED_GRAPHICS)
2399
2400 void ArgumentCoder<BlobPart>::encode(Encoder& encoder, const BlobPart& blobPart)
2401 {
2402     encoder << static_cast<uint32_t>(blobPart.type());
2403     switch (blobPart.type()) {
2404     case BlobPart::Data:
2405         encoder << blobPart.data();
2406         break;
2407     case BlobPart::Blob:
2408         encoder << blobPart.url();
2409         break;
2410     }
2411 }
2412
2413 Optional<BlobPart> ArgumentCoder<BlobPart>::decode(Decoder& decoder)
2414 {
2415     BlobPart blobPart;
2416
2417     Optional<uint32_t> type;
2418     decoder >> type;
2419     if (!type)
2420         return WTF::nullopt;
2421
2422     switch (*type) {
2423     case BlobPart::Data: {
2424         Optional<Vector<uint8_t>> data;
2425         decoder >> data;
2426         if (!data)
2427             return WTF::nullopt;
2428         blobPart = BlobPart(WTFMove(*data));
2429         break;
2430     }
2431     case BlobPart::Blob: {
2432         URL url;
2433         if (!decoder.decode(url))
2434             return WTF::nullopt;
2435         blobPart = BlobPart(url);
2436         break;
2437     }
2438     default:
2439         return WTF::nullopt;
2440     }
2441
2442     return WTFMove(blobPart);
2443 }
2444
2445 void ArgumentCoder<TextIndicatorData>::encode(Encoder& encoder, const TextIndicatorData& textIndicatorData)
2446 {
2447     encoder << textIndicatorData.selectionRectInRootViewCoordinates;
2448     encoder << textIndicatorData.textBoundingRectInRootViewCoordinates;
2449     encoder << textIndicatorData.textRectsInBoundingRectCoordinates;
2450     encoder << textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates;
2451     encoder << textIndicatorData.contentImageScaleFactor;
2452     encoder << textIndicatorData.estimatedBackgroundColor;
2453     encoder.encodeEnum(textIndicatorData.presentationTransition);
2454     encoder << static_cast<uint64_t>(textIndicatorData.options);
2455
2456     encodeOptionalImage(encoder, textIndicatorData.contentImage.get());
2457     encodeOptionalImage(encoder, textIndicatorData.contentImageWithHighlight.get());
2458     encodeOptionalImage(encoder, textIndicatorData.contentImageWithoutSelection.get());
2459 }
2460
2461 Optional<TextIndicatorData> ArgumentCoder<TextIndicatorData>::decode(Decoder& decoder)
2462 {
2463     TextIndicatorData textIndicatorData;
2464     if (!decoder.decode(textIndicatorData.selectionRectInRootViewCoordinates))
2465         return WTF::nullopt;
2466
2467     if (!decoder.decode(textIndicatorData.textBoundingRectInRootViewCoordinates))
2468         return WTF::nullopt;
2469
2470     if (!decoder.decode(textIndicatorData.textRectsInBoundingRectCoordinates))
2471         return WTF::nullopt;
2472
2473     if (!decoder.decode(textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates))
2474         return WTF::nullopt;
2475
2476     if (!decoder.decode(textIndicatorData.contentImageScaleFactor))
2477         return WTF::nullopt;
2478
2479     if (!decoder.decode(textIndicatorData.estimatedBackgroundColor))
2480         return WTF::nullopt;
2481
2482     if (!decoder.decodeEnum(textIndicatorData.presentationTransition))
2483         return WTF::nullopt;
2484
2485     uint64_t options;
2486     if (!decoder.decode(options))
2487         return WTF::nullopt;
2488     textIndicatorData.options = static_cast<TextIndicatorOptions>(options);
2489
2490     if (!decodeOptionalImage(decoder, textIndicatorData.contentImage))
2491         return WTF::nullopt;
2492
2493     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithHighlight))
2494         return WTF::nullopt;
2495
2496     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithoutSelection))
2497         return WTF::nullopt;
2498
2499     return WTFMove(textIndicatorData);
2500 }
2501
2502 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
2503 void ArgumentCoder<MediaPlaybackTargetContext>::encode(Encoder& encoder, const MediaPlaybackTargetContext& target)
2504 {
2505     bool hasPlatformData = target.encodingRequiresPlatformData();
2506     encoder << hasPlatformData;
2507
2508     int32_t targetType = target.type();
2509     encoder << targetType;
2510
2511     if (target.encodingRequiresPlatformData()) {
2512         encodePlatformData(encoder, target);
2513         return;
2514     }
2515
2516     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2517     encoder << target.mockDeviceName();
2518     encoder << static_cast<int32_t>(target.mockState());
2519 }
2520
2521 bool ArgumentCoder<MediaPlaybackTargetContext>::decode(Decoder& decoder, MediaPlaybackTargetContext& target)
2522 {
2523     bool hasPlatformData;
2524     if (!decoder.decode(hasPlatformData))
2525         return false;
2526
2527     int32_t targetType;
2528     if (!decoder.decode(targetType))
2529         return false;
2530
2531     if (hasPlatformData)
2532         return decodePlatformData(decoder, target);
2533
2534     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2535
2536     String mockDeviceName;
2537     if (!decoder.decode(mockDeviceName))
2538         return false;
2539
2540     int32_t mockState;
2541     if (!decoder.decode(mockState))
2542         return false;
2543
2544     target = MediaPlaybackTargetContext(mockDeviceName, static_cast<MediaPlaybackTargetContext::State>(mockState));
2545     return true;
2546 }
2547 #endif
2548
2549 void ArgumentCoder<DictionaryPopupInfo>::encode(IPC::Encoder& encoder, const DictionaryPopupInfo& info)
2550 {
2551     encoder << info.origin;
2552     encoder << info.textIndicator;
2553
2554 #if PLATFORM(COCOA)
2555     bool hadOptions = info.options;
2556     encoder << hadOptions;
2557     if (hadOptions)
2558         IPC::encode(encoder, info.options.get());
2559
2560     bool hadAttributedString = info.attributedString;
2561     encoder << hadAttributedString;
2562     if (hadAttributedString)
2563         IPC::encode(encoder, info.attributedString.get());
2564 #endif
2565 }
2566
2567 bool ArgumentCoder<DictionaryPopupInfo>::decode(IPC::Decoder& decoder, DictionaryPopupInfo& result)
2568 {
2569     if (!decoder.decode(result.origin))
2570         return false;
2571
2572     Optional<TextIndicatorData> textIndicator;
2573     decoder >> textIndicator;
2574     if (!textIndicator)
2575         return false;
2576     result.textIndicator = WTFMove(*textIndicator);
2577
2578 #if PLATFORM(COCOA)
2579     bool hadOptions;
2580     if (!decoder.decode(hadOptions))
2581         return false;
2582     if (hadOptions) {
2583         if (!IPC::decode(decoder, result.options))
2584             return false;
2585     } else
2586         result.options = nullptr;
2587
2588     bool hadAttributedString;
2589     if (!decoder.decode(hadAttributedString))
2590         return false;
2591     if (hadAttributedString) {
2592         if (!IPC::decode(decoder, result.attributedString))
2593             return false;
2594     } else
2595         result.attributedString = nullptr;
2596 #endif
2597     return true;
2598 }
2599
2600 void ArgumentCoder<ExceptionDetails>::encode(IPC::Encoder& encoder, const ExceptionDetails& info)
2601 {
2602     encoder << info.message;
2603     encoder << info.lineNumber;
2604     encoder << info.columnNumber;
2605     encoder << info.sourceURL;
2606 }
2607
2608 bool ArgumentCoder<ExceptionDetails>::decode(IPC::Decoder& decoder, ExceptionDetails& result)
2609 {
2610     if (!decoder.decode(result.message))
2611         return false;
2612
2613     if (!decoder.decode(result.lineNumber))
2614         return false;
2615
2616     if (!decoder.decode(result.columnNumber))
2617         return false;
2618
2619     if (!decoder.decode(result.sourceURL))
2620         return false;
2621
2622     return true;
2623 }
2624
2625 void ArgumentCoder<ResourceLoadStatistics>::encode(Encoder& encoder, const WebCore::ResourceLoadStatistics& statistics)
2626 {
2627     encoder << statistics.highLevelDomain;
2628     
2629     encoder << statistics.lastSeen.secondsSinceEpoch().value();
2630     
2631     // User interaction
2632     encoder << statistics.hadUserInteraction;
2633     encoder << statistics.mostRecentUserInteractionTime.secondsSinceEpoch().value();
2634     encoder << statistics.grandfathered;
2635
2636     // Storage access
2637     encoder << statistics.storageAccessUnderTopFrameOrigins;
2638
2639     // Top frame stats
2640     encoder << statistics.topFrameUniqueRedirectsTo;
2641     encoder << statistics.topFrameUniqueRedirectsFrom;
2642
2643     // Subframe stats
2644     encoder << statistics.subframeUnderTopFrameOrigins;
2645     
2646     // Subresource stats
2647     encoder << statistics.subresourceUnderTopFrameOrigins;
2648     encoder << statistics.subresourceUniqueRedirectsTo;
2649     encoder << statistics.subresourceUniqueRedirectsFrom;
2650
2651     // Prevalent Resource
2652     encoder << statistics.isPrevalentResource;
2653     encoder << statistics.isVeryPrevalentResource;
2654     encoder << statistics.dataRecordsRemoved;
2655
2656 #if ENABLE(WEB_API_STATISTICS)
2657     encoder << statistics.fontsFailedToLoad;
2658     encoder << statistics.fontsSuccessfullyLoaded;
2659     encoder << statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs;
2660     
2661     encoder << statistics.canvasActivityRecord;
2662     
2663     encoder << statistics.navigatorFunctionsAccessed;
2664     encoder << statistics.screenFunctionsAccessed;
2665 #endif
2666 }
2667
2668 Optional<ResourceLoadStatistics> ArgumentCoder<ResourceLoadStatistics>::decode(Decoder& decoder)
2669 {
2670     ResourceLoadStatistics statistics;
2671     if (!decoder.decode(statistics.highLevelDomain))
2672         return WTF::nullopt;
2673     
2674     double lastSeenTimeAsDouble;
2675     if (!decoder.decode(lastSeenTimeAsDouble))
2676         return WTF::nullopt;
2677     statistics.lastSeen = WallTime::fromRawSeconds(lastSeenTimeAsDouble);
2678     
2679     // User interaction
2680     if (!decoder.decode(statistics.hadUserInteraction))
2681         return WTF::nullopt;
2682
2683     double mostRecentUserInteractionTimeAsDouble;
2684     if (!decoder.decode(mostRecentUserInteractionTimeAsDouble))
2685         return WTF::nullopt;
2686     statistics.mostRecentUserInteractionTime = WallTime::fromRawSeconds(mostRecentUserInteractionTimeAsDouble);
2687
2688     if (!decoder.decode(statistics.grandfathered))
2689         return WTF::nullopt;
2690
2691     // Storage access
2692     if (!decoder.decode(statistics.storageAccessUnderTopFrameOrigins))
2693         return WTF::nullopt;
2694
2695     // Top frame stats
2696     if (!decoder.decode(statistics.topFrameUniqueRedirectsTo))
2697         return WTF::nullopt;    
2698
2699     if (!decoder.decode(statistics.topFrameUniqueRedirectsFrom))
2700         return WTF::nullopt;
2701
2702     // Subframe stats
2703     if (!decoder.decode(statistics.subframeUnderTopFrameOrigins))
2704         return WTF::nullopt;
2705     
2706     // Subresource stats
2707     if (!decoder.decode(statistics.subresourceUnderTopFrameOrigins))
2708         return WTF::nullopt;
2709
2710     if (!decoder.decode(statistics.subresourceUniqueRedirectsTo))
2711         return WTF::nullopt;
2712     
2713     if (!decoder.decode(statistics.subresourceUniqueRedirectsFrom))
2714         return WTF::nullopt;
2715     
2716     // Prevalent Resource
2717     if (!decoder.decode(statistics.isPrevalentResource))
2718         return WTF::nullopt;
2719
2720     if (!decoder.decode(statistics.isVeryPrevalentResource))
2721         return WTF::nullopt;
2722     
2723     if (!decoder.decode(statistics.dataRecordsRemoved))
2724         return WTF::nullopt;
2725     
2726 #if ENABLE(WEB_API_STATISTICS)
2727     if (!decoder.decode(statistics.fontsFailedToLoad))
2728         return WTF::nullopt;
2729     
2730     if (!decoder.decode(statistics.fontsSuccessfullyLoaded))
2731         return WTF::nullopt;
2732     
2733     if (!decoder.decode(statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs))
2734         return WTF::nullopt;
2735     
2736     if (!decoder.decode(statistics.canvasActivityRecord))
2737         return WTF::nullopt;
2738     
2739     if (!decoder.decode(statistics.navigatorFunctionsAccessed))
2740         return WTF::nullopt;
2741     
2742     if (!decoder.decode(statistics.screenFunctionsAccessed))
2743         return WTF::nullopt;
2744 #endif
2745
2746     return WTFMove(statistics);
2747 }
2748
2749 #if ENABLE(MEDIA_STREAM)
2750 void ArgumentCoder<MediaConstraints>::encode(Encoder& encoder, const WebCore::MediaConstraints& constraint)
2751 {
2752     encoder << constraint.mandatoryConstraints
2753         << constraint.advancedConstraints
2754         << constraint.isValid;
2755 }
2756
2757 bool ArgumentCoder<MediaConstraints>::decode(Decoder& decoder, WebCore::MediaConstraints& constraints)
2758 {
2759     Optional<WebCore::MediaTrackConstraintSetMap> mandatoryConstraints;
2760     decoder >> mandatoryConstraints;
2761     if (!mandatoryConstraints)
2762         return false;
2763     constraints.mandatoryConstraints = WTFMove(*mandatoryConstraints);
2764     return decoder.decode(constraints.advancedConstraints)
2765         && decoder.decode(constraints.isValid);
2766 }
2767 #endif
2768
2769 #if ENABLE(INDEXED_DATABASE)
2770 void ArgumentCoder<IDBKeyPath>::encode(Encoder& encoder, const IDBKeyPath& keyPath)
2771 {
2772     bool isString = WTF::holds_alternative<String>(keyPath);
2773     encoder << isString;
2774     if (isString)
2775         encoder << WTF::get<String>(keyPath);
2776     else
2777         encoder << WTF::get<Vector<String>>(keyPath);
2778 }
2779
2780 bool ArgumentCoder<IDBKeyPath>::decode(Decoder& decoder, IDBKeyPath& keyPath)
2781 {
2782     bool isString;
2783     if (!decoder.decode(isString))
2784         return false;
2785     if (isString) {
2786         String string;
2787         if (!decoder.decode(string))
2788             return false;
2789         keyPath = string;
2790     } else {
2791         Vector<String> vector;
2792         if (!decoder.decode(vector))
2793             return false;
2794         keyPath = vector;
2795     }
2796     return true;
2797 }
2798 #endif
2799
2800 #if ENABLE(SERVICE_WORKER)
2801 void ArgumentCoder<ServiceWorkerOrClientData>::encode(Encoder& encoder, const ServiceWorkerOrClientData& data)
2802 {
2803     bool isServiceWorkerData = WTF::holds_alternative<ServiceWorkerData>(data);
2804     encoder << isServiceWorkerData;
2805     if (isServiceWorkerData)
2806         encoder << WTF::get<ServiceWorkerData>(data);
2807     else
2808         encoder << WTF::get<ServiceWorkerClientData>(data);
2809 }
2810
2811 bool ArgumentCoder<ServiceWorkerOrClientData>::decode(Decoder& decoder, ServiceWorkerOrClientData& data)
2812 {
2813     bool isServiceWorkerData;
2814     if (!decoder.decode(isServiceWorkerData))
2815         return false;
2816     if (isServiceWorkerData) {
2817         Optional<ServiceWorkerData> workerData;
2818         decoder >> workerData;
2819         if (!workerData)
2820             return false;
2821
2822         data = WTFMove(*workerData);
2823     } else {
2824         Optional<ServiceWorkerClientData> clientData;
2825         decoder >> clientData;
2826         if (!clientData)
2827             return false;
2828
2829         data = WTFMove(*clientData);
2830     }
2831     return true;
2832 }
2833
2834 void ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode(Encoder& encoder, const ServiceWorkerOrClientIdentifier& identifier)
2835 {
2836     bool isServiceWorkerIdentifier = WTF::holds_alternative<ServiceWorkerIdentifier>(identifier);
2837     encoder << isServiceWorkerIdentifier;
2838     if (isServiceWorkerIdentifier)
2839         encoder << WTF::get<ServiceWorkerIdentifier>(identifier);
2840     else
2841         encoder << WTF::get<ServiceWorkerClientIdentifier>(identifier);
2842 }
2843
2844 bool ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode(Decoder& decoder, ServiceWorkerOrClientIdentifier& identifier)
2845 {
2846     bool isServiceWorkerIdentifier;
2847     if (!decoder.decode(isServiceWorkerIdentifier))
2848         return false;
2849     if (isServiceWorkerIdentifier) {
2850         Optional<ServiceWorkerIdentifier> workerIdentifier;
2851         decoder >> workerIdentifier;
2852         if (!workerIdentifier)
2853             return false;
2854
2855         identifier = WTFMove(*workerIdentifier);
2856     } else {
2857         Optional<ServiceWorkerClientIdentifier> clientIdentifier;
2858         decoder >> clientIdentifier;
2859         if (!clientIdentifier)
2860             return false;
2861
2862         identifier = WTFMove(*clientIdentifier);
2863     }
2864     return true;
2865 }
2866 #endif
2867
2868 #if ENABLE(CSS_SCROLL_SNAP)
2869
2870 void ArgumentCoder<ScrollOffsetRange<float>>::encode(Encoder& encoder, const ScrollOffsetRange<float>& range)
2871 {
2872     encoder << range.start;
2873     encoder << range.end;
2874 }
2875
2876 auto ArgumentCoder<ScrollOffsetRange<float>>::decode(Decoder& decoder) -> Optional<WebCore::ScrollOffsetRange<float>>
2877 {
2878     WebCore::ScrollOffsetRange<float> range;
2879     float start;
2880     if (!decoder.decode(start))
2881         return WTF::nullopt;
2882
2883     float end;
2884     if (!decoder.decode(end))
2885         return WTF::nullopt;
2886
2887     range.start = start;
2888     range.end = end;
2889     return WTFMove(range);
2890 }
2891
2892 #endif
2893
2894 void ArgumentCoder<MediaSelectionOption>::encode(Encoder& encoder, const MediaSelectionOption& option)
2895 {
2896     encoder << option.displayName;
2897     encoder << option.type;
2898 }
2899
2900 Optional<MediaSelectionOption> ArgumentCoder<MediaSelectionOption>::decode(Decoder& decoder)
2901 {
2902     Optional<String> displayName;
2903     decoder >> displayName;
2904     if (!displayName)
2905         return WTF::nullopt;
2906     
2907     Optional<MediaSelectionOption::Type> type;
2908     decoder >> type;
2909     if (!type)
2910         return WTF::nullopt;
2911     
2912     return {{ WTFMove(*displayName), WTFMove(*type) }};
2913 }
2914
2915 void ArgumentCoder<PromisedAttachmentInfo>::encode(Encoder& encoder, const PromisedAttachmentInfo& info)
2916 {
2917     encoder << info.blobURL;
2918     encoder << info.contentType;
2919     encoder << info.fileName;
2920 #if ENABLE(ATTACHMENT_ELEMENT)
2921     encoder << info.attachmentIdentifier;
2922 #endif
2923     encodeTypesAndData(encoder, info.additionalTypes, info.additionalData);
2924 }
2925
2926 bool ArgumentCoder<PromisedAttachmentInfo>::decode(Decoder& decoder, PromisedAttachmentInfo& info)
2927 {
2928     if (!decoder.decode(info.blobURL))
2929         return false;
2930
2931     if (!decoder.decode(info.contentType))
2932         return false;
2933
2934     if (!decoder.decode(info.fileName))
2935         return false;
2936
2937 #if ENABLE(ATTACHMENT_ELEMENT)
2938     if (!decoder.decode(info.attachmentIdentifier))
2939         return false;
2940 #endif
2941
2942     if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData))
2943         return false;
2944
2945     return true;
2946 }
2947
2948 void ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::encode(Encoder& encoder, const Vector<RefPtr<SecurityOrigin>>& origins)
2949 {
2950     encoder << static_cast<uint64_t>(origins.size());
2951     for (auto& origin : origins)
2952         encoder << *origin;
2953 }
2954     
2955 bool ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::decode(Decoder& decoder, Vector<RefPtr<SecurityOrigin>>& origins)
2956 {
2957     uint64_t dataSize;
2958     if (!decoder.decode(dataSize))
2959         return false;
2960
2961     origins.reserveInitialCapacity(dataSize);
2962     for (uint64_t i = 0; i < dataSize; ++i) {
2963         auto decodedOriginRefPtr = SecurityOrigin::decode(decoder);
2964         if (!decodedOriginRefPtr)
2965             return false;
2966         origins.uncheckedAppend(decodedOriginRefPtr.releaseNonNull());
2967     }
2968     return true;
2969 }
2970
2971 void ArgumentCoder<FontAttributes>::encode(Encoder& encoder, const FontAttributes& attributes)
2972 {
2973     encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough << attributes.textLists;
2974     encoder.encodeEnum(attributes.horizontalAlignment);
2975     encoder.encodeEnum(attributes.subscriptOrSuperscript);
2976 #if PLATFORM(COCOA)
2977     bool hasFont = attributes.font;
2978     encoder << hasFont;
2979     if (hasFont)
2980         IPC::encode(encoder, attributes.font.get());
2981 #endif
2982 }
2983
2984 Optional<FontAttributes> ArgumentCoder<FontAttributes>::decode(Decoder& decoder)
2985 {
2986     FontAttributes attributes;
2987
2988     if (!decoder.decode(attributes.backgroundColor))
2989         return WTF::nullopt;
2990
2991     if (!decoder.decode(attributes.foregroundColor))
2992         return WTF::nullopt;
2993
2994     if (!decoder.decode(attributes.fontShadow))
2995         return WTF::nullopt;
2996
2997     if (!decoder.decode(attributes.hasUnderline))
2998         return WTF::nullopt;
2999
3000     if (!decoder.decode(attributes.hasStrikeThrough))
3001         return WTF::nullopt;
3002
3003     if (!decoder.decode(attributes.textLists))
3004         return WTF::nullopt;
3005
3006     if (!decoder.decodeEnum(attributes.horizontalAlignment))
3007         return WTF::nullopt;
3008
3009     if (!decoder.decodeEnum(attributes.subscriptOrSuperscript))
3010         return WTF::nullopt;
3011
3012 #if PLATFORM(COCOA)
3013     bool hasFont = false;
3014     if (!decoder.decode(hasFont))
3015         return WTF::nullopt;
3016
3017     if (hasFont && !IPC::decode(decoder, attributes.font))
3018         return WTF::nullopt;
3019 #endif
3020
3021     return attributes;
3022 }
3023
3024 #if ENABLE(ATTACHMENT_ELEMENT)
3025
3026 void ArgumentCoder<SerializedAttachmentData>::encode(IPC::Encoder& encoder, const WebCore::SerializedAttachmentData& data)
3027 {
3028     encoder << data.identifier << data.mimeType << IPC::SharedBufferDataReference { data.data.get() };
3029 }
3030
3031 Optional<SerializedAttachmentData> ArgumentCoder<WebCore::SerializedAttachmentData>::decode(IPC::Decoder& decoder)
3032 {
3033     String identifier;
3034     if (!decoder.decode(identifier))
3035         return WTF::nullopt;
3036
3037     String mimeType;
3038     if (!decoder.decode(mimeType))
3039         return WTF::nullopt;
3040
3041     IPC::DataReference data;
3042     if (!decoder.decode(data))
3043         return WTF::nullopt;
3044
3045     return {{ WTFMove(identifier), WTFMove(mimeType), WebCore::SharedBuffer::create(data.data(), data.size()) }};
3046 }
3047
3048 #endif // ENABLE(ATTACHMENT_ELEMENT)
3049
3050 } // namespace IPC