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