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