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