Activate NetworkLoadChecker for media loads
[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/AttachmentTypes.h>
32 #include <WebCore/AuthenticationChallenge.h>
33 #include <WebCore/BlobPart.h>
34 #include <WebCore/CacheQueryOptions.h>
35 #include <WebCore/CertificateInfo.h>
36 #include <WebCore/CompositionUnderline.h>
37 #include <WebCore/Credential.h>
38 #include <WebCore/Cursor.h>
39 #include <WebCore/DatabaseDetails.h>
40 #include <WebCore/DictationAlternative.h>
41 #include <WebCore/DictionaryPopupInfo.h>
42 #include <WebCore/DragData.h>
43 #include <WebCore/EventTrackingRegions.h>
44 #include <WebCore/FetchOptions.h>
45 #include <WebCore/FileChooser.h>
46 #include <WebCore/FilterOperation.h>
47 #include <WebCore/FilterOperations.h>
48 #include <WebCore/GraphicsContext.h>
49 #include <WebCore/GraphicsLayer.h>
50 #include <WebCore/IDBGetResult.h>
51 #include <WebCore/Image.h>
52 #include <WebCore/JSDOMExceptionHandling.h>
53 #include <WebCore/Length.h>
54 #include <WebCore/LengthBox.h>
55 #include <WebCore/MediaSelectionOption.h>
56 #include <WebCore/Pasteboard.h>
57 #include <WebCore/Path.h>
58 #include <WebCore/PluginData.h>
59 #include <WebCore/PromisedBlobInfo.h>
60 #include <WebCore/ProtectionSpace.h>
61 #include <WebCore/RectEdges.h>
62 #include <WebCore/Region.h>
63 #include <WebCore/ResourceError.h>
64 #include <WebCore/ResourceLoadStatistics.h>
65 #include <WebCore/ResourceRequest.h>
66 #include <WebCore/ResourceResponse.h>
67 #include <WebCore/ScrollingConstraints.h>
68 #include <WebCore/ScrollingCoordinator.h>
69 #include <WebCore/SearchPopupMenu.h>
70 #include <WebCore/ServiceWorkerClientData.h>
71 #include <WebCore/ServiceWorkerClientIdentifier.h>
72 #include <WebCore/ServiceWorkerData.h>
73 #include <WebCore/TextCheckerClient.h>
74 #include <WebCore/TextIndicator.h>
75 #include <WebCore/TimingFunction.h>
76 #include <WebCore/TransformationMatrix.h>
77 #include <WebCore/URL.h>
78 #include <WebCore/UserStyleSheet.h>
79 #include <WebCore/ViewportArguments.h>
80 #include <WebCore/WindowFeatures.h>
81 #include <pal/SessionID.h>
82 #include <wtf/text/CString.h>
83 #include <wtf/text/StringHash.h>
84
85 #if PLATFORM(COCOA)
86 #include "ArgumentCodersCF.h"
87 #include "ArgumentCodersMac.h"
88 #endif
89
90 #if PLATFORM(IOS)
91 #include <WebCore/FloatQuad.h>
92 #include <WebCore/InspectorOverlay.h>
93 #include <WebCore/SelectionRect.h>
94 #include <WebCore/SharedBuffer.h>
95 #endif // PLATFORM(IOS)
96
97 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
98 #include <WebCore/MediaPlaybackTargetContext.h>
99 #endif
100
101 #if ENABLE(MEDIA_SESSION)
102 #include <WebCore/MediaSessionMetadata.h>
103 #endif
104
105 #if ENABLE(MEDIA_STREAM)
106 #include <WebCore/CaptureDevice.h>
107 #include <WebCore/MediaConstraints.h>
108 #endif
109
110 using namespace WebCore;
111 using namespace WebKit;
112
113 namespace IPC {
114
115 static void encodeSharedBuffer(Encoder& encoder, const SharedBuffer* buffer)
116 {
117     SharedMemory::Handle handle;
118     uint64_t bufferSize = buffer ? buffer->size() : 0;
119     encoder << bufferSize;
120     if (!bufferSize)
121         return;
122
123     auto sharedMemoryBuffer = SharedMemory::allocate(buffer->size());
124     memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
125     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
126     encoder << handle;
127 }
128
129 static bool decodeSharedBuffer(Decoder& decoder, RefPtr<SharedBuffer>& buffer)
130 {
131     uint64_t bufferSize = 0;
132     if (!decoder.decode(bufferSize))
133         return false;
134
135     if (!bufferSize)
136         return true;
137
138     SharedMemory::Handle handle;
139     if (!decoder.decode(handle))
140         return false;
141
142     auto sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
143     buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), bufferSize);
144
145     return true;
146 }
147
148 static void encodeTypesAndData(Encoder& encoder, const Vector<String>& types, const Vector<RefPtr<SharedBuffer>>& data)
149 {
150     ASSERT(types.size() == data.size());
151     encoder << types;
152     encoder << static_cast<uint64_t>(data.size());
153     for (auto& buffer : data)
154         encodeSharedBuffer(encoder, buffer.get());
155 }
156
157 static bool decodeTypesAndData(Decoder& decoder, Vector<String>& types, Vector<RefPtr<SharedBuffer>>& data)
158 {
159     if (!decoder.decode(types))
160         return false;
161
162     uint64_t dataSize;
163     if (!decoder.decode(dataSize))
164         return false;
165
166     ASSERT(dataSize == types.size());
167
168     data.resize(dataSize);
169     for (auto& buffer : data)
170         decodeSharedBuffer(decoder, buffer);
171
172     return true;
173 }
174
175 void ArgumentCoder<AffineTransform>::encode(Encoder& encoder, const AffineTransform& affineTransform)
176 {
177     SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
178 }
179
180 bool ArgumentCoder<AffineTransform>::decode(Decoder& decoder, AffineTransform& affineTransform)
181 {
182     return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
183 }
184
185 void ArgumentCoder<CacheQueryOptions>::encode(Encoder& encoder, const CacheQueryOptions& options)
186 {
187     encoder << options.ignoreSearch;
188     encoder << options.ignoreMethod;
189     encoder << options.ignoreVary;
190     encoder << options.cacheName;
191 }
192
193 bool ArgumentCoder<CacheQueryOptions>::decode(Decoder& decoder, CacheQueryOptions& options)
194 {
195     bool ignoreSearch;
196     if (!decoder.decode(ignoreSearch))
197         return false;
198     bool ignoreMethod;
199     if (!decoder.decode(ignoreMethod))
200         return false;
201     bool ignoreVary;
202     if (!decoder.decode(ignoreVary))
203         return false;
204     String cacheName;
205     if (!decoder.decode(cacheName))
206         return false;
207
208     options.ignoreSearch = ignoreSearch;
209     options.ignoreMethod = ignoreMethod;
210     options.ignoreVary = ignoreVary;
211     options.cacheName = WTFMove(cacheName);
212     return true;
213 }
214
215 void ArgumentCoder<DOMCacheEngine::CacheInfo>::encode(Encoder& encoder, const DOMCacheEngine::CacheInfo& info)
216 {
217     encoder << info.identifier;
218     encoder << info.name;
219 }
220
221 auto ArgumentCoder<DOMCacheEngine::CacheInfo>::decode(Decoder& decoder) -> std::optional<DOMCacheEngine::CacheInfo>
222 {
223     std::optional<uint64_t> identifier;
224     decoder >> identifier;
225     if (!identifier)
226         return std::nullopt;
227     
228     std::optional<String> name;
229     decoder >> name;
230     if (!name)
231         return std::nullopt;
232     
233     return {{ WTFMove(*identifier), WTFMove(*name) }};
234 }
235
236 void ArgumentCoder<DOMCacheEngine::Record>::encode(Encoder& encoder, const DOMCacheEngine::Record& record)
237 {
238     encoder << record.identifier;
239
240     encoder << record.requestHeadersGuard;
241     encoder << record.request;
242     encoder << record.options;
243     encoder << record.referrer;
244
245     encoder << record.responseHeadersGuard;
246     encoder << record.response;
247     encoder << record.updateResponseCounter;
248     encoder << record.responseBodySize;
249
250     WTF::switchOn(record.responseBody, [&](const Ref<SharedBuffer>& buffer) {
251         encoder << true;
252         encodeSharedBuffer(encoder, buffer.ptr());
253     }, [&](const Ref<FormData>& formData) {
254         encoder << false;
255         encoder << true;
256         formData->encode(encoder);
257     }, [&](const std::nullptr_t&) {
258         encoder << false;
259         encoder << false;
260     });
261 }
262
263 std::optional<DOMCacheEngine::Record> ArgumentCoder<DOMCacheEngine::Record>::decode(Decoder& decoder)
264 {
265     uint64_t identifier;
266     if (!decoder.decode(identifier))
267         return std::nullopt;
268
269     FetchHeaders::Guard requestHeadersGuard;
270     if (!decoder.decode(requestHeadersGuard))
271         return std::nullopt;
272
273     WebCore::ResourceRequest request;
274     if (!decoder.decode(request))
275         return std::nullopt;
276
277     std::optional<WebCore::FetchOptions> options;
278     decoder >> options;
279     if (!options)
280         return std::nullopt;
281
282     String referrer;
283     if (!decoder.decode(referrer))
284         return std::nullopt;
285
286     FetchHeaders::Guard responseHeadersGuard;
287     if (!decoder.decode(responseHeadersGuard))
288         return std::nullopt;
289
290     WebCore::ResourceResponse response;
291     if (!decoder.decode(response))
292         return std::nullopt;
293
294     uint64_t updateResponseCounter;
295     if (!decoder.decode(updateResponseCounter))
296         return std::nullopt;
297
298     uint64_t responseBodySize;
299     if (!decoder.decode(responseBodySize))
300         return std::nullopt;
301
302     WebCore::DOMCacheEngine::ResponseBody responseBody;
303     bool hasSharedBufferBody;
304     if (!decoder.decode(hasSharedBufferBody))
305         return std::nullopt;
306
307     if (hasSharedBufferBody) {
308         RefPtr<SharedBuffer> buffer;
309         if (!decodeSharedBuffer(decoder, buffer))
310             return std::nullopt;
311         if (buffer)
312             responseBody = buffer.releaseNonNull();
313     } else {
314         bool hasFormDataBody;
315         if (!decoder.decode(hasFormDataBody))
316             return std::nullopt;
317         if (hasFormDataBody) {
318             auto formData = FormData::decode(decoder);
319             if (!formData)
320                 return std::nullopt;
321             responseBody = formData.releaseNonNull();
322         }
323     }
324
325     return {{ WTFMove(identifier), WTFMove(updateResponseCounter), WTFMove(requestHeadersGuard), WTFMove(request), WTFMove(options.value()), WTFMove(referrer), WTFMove(responseHeadersGuard), WTFMove(response), WTFMove(responseBody), responseBodySize }};
326 }
327
328 void ArgumentCoder<EventTrackingRegions>::encode(Encoder& encoder, const EventTrackingRegions& eventTrackingRegions)
329 {
330     encoder << eventTrackingRegions.asynchronousDispatchRegion;
331     encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions;
332 }
333
334 bool ArgumentCoder<EventTrackingRegions>::decode(Decoder& decoder, EventTrackingRegions& eventTrackingRegions)
335 {
336     Region asynchronousDispatchRegion;
337     if (!decoder.decode(asynchronousDispatchRegion))
338         return false;
339     HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
340     if (!decoder.decode(eventSpecificSynchronousDispatchRegions))
341         return false;
342     eventTrackingRegions.asynchronousDispatchRegion = WTFMove(asynchronousDispatchRegion);
343     eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions);
344     return true;
345 }
346
347 void ArgumentCoder<TransformationMatrix>::encode(Encoder& encoder, const TransformationMatrix& transformationMatrix)
348 {
349     encoder << transformationMatrix.m11();
350     encoder << transformationMatrix.m12();
351     encoder << transformationMatrix.m13();
352     encoder << transformationMatrix.m14();
353
354     encoder << transformationMatrix.m21();
355     encoder << transformationMatrix.m22();
356     encoder << transformationMatrix.m23();
357     encoder << transformationMatrix.m24();
358
359     encoder << transformationMatrix.m31();
360     encoder << transformationMatrix.m32();
361     encoder << transformationMatrix.m33();
362     encoder << transformationMatrix.m34();
363
364     encoder << transformationMatrix.m41();
365     encoder << transformationMatrix.m42();
366     encoder << transformationMatrix.m43();
367     encoder << transformationMatrix.m44();
368 }
369
370 bool ArgumentCoder<TransformationMatrix>::decode(Decoder& decoder, TransformationMatrix& transformationMatrix)
371 {
372     double m11;
373     if (!decoder.decode(m11))
374         return false;
375     double m12;
376     if (!decoder.decode(m12))
377         return false;
378     double m13;
379     if (!decoder.decode(m13))
380         return false;
381     double m14;
382     if (!decoder.decode(m14))
383         return false;
384
385     double m21;
386     if (!decoder.decode(m21))
387         return false;
388     double m22;
389     if (!decoder.decode(m22))
390         return false;
391     double m23;
392     if (!decoder.decode(m23))
393         return false;
394     double m24;
395     if (!decoder.decode(m24))
396         return false;
397
398     double m31;
399     if (!decoder.decode(m31))
400         return false;
401     double m32;
402     if (!decoder.decode(m32))
403         return false;
404     double m33;
405     if (!decoder.decode(m33))
406         return false;
407     double m34;
408     if (!decoder.decode(m34))
409         return false;
410
411     double m41;
412     if (!decoder.decode(m41))
413         return false;
414     double m42;
415     if (!decoder.decode(m42))
416         return false;
417     double m43;
418     if (!decoder.decode(m43))
419         return false;
420     double m44;
421     if (!decoder.decode(m44))
422         return false;
423
424     transformationMatrix.setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
425     return true;
426 }
427
428 void ArgumentCoder<LinearTimingFunction>::encode(Encoder& encoder, const LinearTimingFunction& timingFunction)
429 {
430     encoder.encodeEnum(timingFunction.type());
431 }
432
433 bool ArgumentCoder<LinearTimingFunction>::decode(Decoder&, LinearTimingFunction&)
434 {
435     // Type is decoded by the caller. Nothing else to decode.
436     return true;
437 }
438
439 void ArgumentCoder<CubicBezierTimingFunction>::encode(Encoder& encoder, const CubicBezierTimingFunction& timingFunction)
440 {
441     encoder.encodeEnum(timingFunction.type());
442     
443     encoder << timingFunction.x1();
444     encoder << timingFunction.y1();
445     encoder << timingFunction.x2();
446     encoder << timingFunction.y2();
447     
448     encoder.encodeEnum(timingFunction.timingFunctionPreset());
449 }
450
451 bool ArgumentCoder<CubicBezierTimingFunction>::decode(Decoder& decoder, CubicBezierTimingFunction& timingFunction)
452 {
453     // Type is decoded by the caller.
454     double x1;
455     if (!decoder.decode(x1))
456         return false;
457
458     double y1;
459     if (!decoder.decode(y1))
460         return false;
461
462     double x2;
463     if (!decoder.decode(x2))
464         return false;
465
466     double y2;
467     if (!decoder.decode(y2))
468         return false;
469
470     CubicBezierTimingFunction::TimingFunctionPreset preset;
471     if (!decoder.decodeEnum(preset))
472         return false;
473
474     timingFunction.setValues(x1, y1, x2, y2);
475     timingFunction.setTimingFunctionPreset(preset);
476
477     return true;
478 }
479
480 void ArgumentCoder<StepsTimingFunction>::encode(Encoder& encoder, const StepsTimingFunction& timingFunction)
481 {
482     encoder.encodeEnum(timingFunction.type());
483     
484     encoder << timingFunction.numberOfSteps();
485     encoder << timingFunction.stepAtStart();
486 }
487
488 bool ArgumentCoder<StepsTimingFunction>::decode(Decoder& decoder, StepsTimingFunction& timingFunction)
489 {
490     // Type is decoded by the caller.
491     int numSteps;
492     if (!decoder.decode(numSteps))
493         return false;
494
495     bool stepAtStart;
496     if (!decoder.decode(stepAtStart))
497         return false;
498
499     timingFunction.setNumberOfSteps(numSteps);
500     timingFunction.setStepAtStart(stepAtStart);
501
502     return true;
503 }
504
505 void ArgumentCoder<FramesTimingFunction>::encode(Encoder& encoder, const FramesTimingFunction& timingFunction)
506 {
507     encoder.encodeEnum(timingFunction.type());
508     
509     encoder << timingFunction.numberOfFrames();
510 }
511
512 bool ArgumentCoder<FramesTimingFunction>::decode(Decoder& decoder, FramesTimingFunction& timingFunction)
513 {
514     // Type is decoded by the caller.
515     int numFrames;
516     if (!decoder.decode(numFrames))
517         return false;
518
519     timingFunction.setNumberOfFrames(numFrames);
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<WallTime> 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     encoder.encodeEnum(resourceError.type());
1273     if (resourceError.type() == ResourceError::Type::Null)
1274         return;
1275     encodePlatformData(encoder, resourceError);
1276 }
1277
1278 bool ArgumentCoder<ResourceError>::decode(Decoder& decoder, ResourceError& resourceError)
1279 {
1280     ResourceError::Type type;
1281     if (!decoder.decodeEnum(type))
1282         return false;
1283
1284     if (type == ResourceError::Type::Null) {
1285         resourceError = { };
1286         return true;
1287     }
1288
1289     if (!decodePlatformData(decoder, resourceError))
1290         return false;
1291
1292     resourceError.setType(type);
1293     return true;
1294 }
1295
1296 #if PLATFORM(IOS)
1297
1298 void ArgumentCoder<SelectionRect>::encode(Encoder& encoder, const SelectionRect& selectionRect)
1299 {
1300     encoder << selectionRect.rect();
1301     encoder << static_cast<uint32_t>(selectionRect.direction());
1302     encoder << selectionRect.minX();
1303     encoder << selectionRect.maxX();
1304     encoder << selectionRect.maxY();
1305     encoder << selectionRect.lineNumber();
1306     encoder << selectionRect.isLineBreak();
1307     encoder << selectionRect.isFirstOnLine();
1308     encoder << selectionRect.isLastOnLine();
1309     encoder << selectionRect.containsStart();
1310     encoder << selectionRect.containsEnd();
1311     encoder << selectionRect.isHorizontal();
1312 }
1313
1314 std::optional<SelectionRect> ArgumentCoder<SelectionRect>::decode(Decoder& decoder)
1315 {
1316     SelectionRect selectionRect;
1317     IntRect rect;
1318     if (!decoder.decode(rect))
1319         return std::nullopt;
1320     selectionRect.setRect(rect);
1321
1322     uint32_t direction;
1323     if (!decoder.decode(direction))
1324         return std::nullopt;
1325     selectionRect.setDirection((TextDirection)direction);
1326
1327     int intValue;
1328     if (!decoder.decode(intValue))
1329         return std::nullopt;
1330     selectionRect.setMinX(intValue);
1331
1332     if (!decoder.decode(intValue))
1333         return std::nullopt;
1334     selectionRect.setMaxX(intValue);
1335
1336     if (!decoder.decode(intValue))
1337         return std::nullopt;
1338     selectionRect.setMaxY(intValue);
1339
1340     if (!decoder.decode(intValue))
1341         return std::nullopt;
1342     selectionRect.setLineNumber(intValue);
1343
1344     bool boolValue;
1345     if (!decoder.decode(boolValue))
1346         return std::nullopt;
1347     selectionRect.setIsLineBreak(boolValue);
1348
1349     if (!decoder.decode(boolValue))
1350         return std::nullopt;
1351     selectionRect.setIsFirstOnLine(boolValue);
1352
1353     if (!decoder.decode(boolValue))
1354         return std::nullopt;
1355     selectionRect.setIsLastOnLine(boolValue);
1356
1357     if (!decoder.decode(boolValue))
1358         return std::nullopt;
1359     selectionRect.setContainsStart(boolValue);
1360
1361     if (!decoder.decode(boolValue))
1362         return std::nullopt;
1363     selectionRect.setContainsEnd(boolValue);
1364
1365     if (!decoder.decode(boolValue))
1366         return std::nullopt;
1367     selectionRect.setIsHorizontal(boolValue);
1368
1369     return WTFMove(selectionRect);
1370 }
1371
1372 #endif
1373
1374 void ArgumentCoder<WindowFeatures>::encode(Encoder& encoder, const WindowFeatures& windowFeatures)
1375 {
1376     encoder << windowFeatures.x;
1377     encoder << windowFeatures.y;
1378     encoder << windowFeatures.width;
1379     encoder << windowFeatures.height;
1380     encoder << windowFeatures.menuBarVisible;
1381     encoder << windowFeatures.statusBarVisible;
1382     encoder << windowFeatures.toolBarVisible;
1383     encoder << windowFeatures.locationBarVisible;
1384     encoder << windowFeatures.scrollbarsVisible;
1385     encoder << windowFeatures.resizable;
1386     encoder << windowFeatures.fullscreen;
1387     encoder << windowFeatures.dialog;
1388 }
1389
1390 bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& windowFeatures)
1391 {
1392     if (!decoder.decode(windowFeatures.x))
1393         return false;
1394     if (!decoder.decode(windowFeatures.y))
1395         return false;
1396     if (!decoder.decode(windowFeatures.width))
1397         return false;
1398     if (!decoder.decode(windowFeatures.height))
1399         return false;
1400     if (!decoder.decode(windowFeatures.menuBarVisible))
1401         return false;
1402     if (!decoder.decode(windowFeatures.statusBarVisible))
1403         return false;
1404     if (!decoder.decode(windowFeatures.toolBarVisible))
1405         return false;
1406     if (!decoder.decode(windowFeatures.locationBarVisible))
1407         return false;
1408     if (!decoder.decode(windowFeatures.scrollbarsVisible))
1409         return false;
1410     if (!decoder.decode(windowFeatures.resizable))
1411         return false;
1412     if (!decoder.decode(windowFeatures.fullscreen))
1413         return false;
1414     if (!decoder.decode(windowFeatures.dialog))
1415         return false;
1416     return true;
1417 }
1418
1419
1420 void ArgumentCoder<Color>::encode(Encoder& encoder, const Color& color)
1421 {
1422     if (color.isExtended()) {
1423         encoder << true;
1424         encoder << color.asExtended().red();
1425         encoder << color.asExtended().green();
1426         encoder << color.asExtended().blue();
1427         encoder << color.asExtended().alpha();
1428         encoder << color.asExtended().colorSpace();
1429         return;
1430     }
1431
1432     encoder << false;
1433
1434     if (!color.isValid()) {
1435         encoder << false;
1436         return;
1437     }
1438
1439     encoder << true;
1440     encoder << color.rgb();
1441 }
1442
1443 bool ArgumentCoder<Color>::decode(Decoder& decoder, Color& color)
1444 {
1445     bool isExtended;
1446     if (!decoder.decode(isExtended))
1447         return false;
1448
1449     if (isExtended) {
1450         float red;
1451         float green;
1452         float blue;
1453         float alpha;
1454         ColorSpace colorSpace;
1455         if (!decoder.decode(red))
1456             return false;
1457         if (!decoder.decode(green))
1458             return false;
1459         if (!decoder.decode(blue))
1460             return false;
1461         if (!decoder.decode(alpha))
1462             return false;
1463         if (!decoder.decode(colorSpace))
1464             return false;
1465         color = Color(red, green, blue, alpha, colorSpace);
1466         return true;
1467     }
1468
1469     bool isValid;
1470     if (!decoder.decode(isValid))
1471         return false;
1472
1473     if (!isValid) {
1474         color = Color();
1475         return true;
1476     }
1477
1478     RGBA32 rgba;
1479     if (!decoder.decode(rgba))
1480         return false;
1481
1482     color = Color(rgba);
1483     return true;
1484 }
1485
1486 #if ENABLE(DRAG_SUPPORT)
1487 void ArgumentCoder<DragData>::encode(Encoder& encoder, const DragData& dragData)
1488 {
1489     encoder << dragData.clientPosition();
1490     encoder << dragData.globalPosition();
1491     encoder.encodeEnum(dragData.draggingSourceOperationMask());
1492     encoder.encodeEnum(dragData.flags());
1493 #if PLATFORM(COCOA)
1494     encoder << dragData.pasteboardName();
1495     encoder << dragData.fileNames();
1496 #endif
1497     encoder.encodeEnum(dragData.dragDestinationAction());
1498 }
1499
1500 bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
1501 {
1502     IntPoint clientPosition;
1503     if (!decoder.decode(clientPosition))
1504         return false;
1505
1506     IntPoint globalPosition;
1507     if (!decoder.decode(globalPosition))
1508         return false;
1509
1510     DragOperation draggingSourceOperationMask;
1511     if (!decoder.decodeEnum(draggingSourceOperationMask))
1512         return false;
1513
1514     DragApplicationFlags applicationFlags;
1515     if (!decoder.decodeEnum(applicationFlags))
1516         return false;
1517
1518     String pasteboardName;
1519     Vector<String> fileNames;
1520 #if PLATFORM(COCOA)
1521     if (!decoder.decode(pasteboardName))
1522         return false;
1523
1524     if (!decoder.decode(fileNames))
1525         return false;
1526 #endif
1527
1528     DragDestinationAction destinationAction;
1529     if (!decoder.decodeEnum(destinationAction))
1530         return false;
1531
1532     dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, destinationAction);
1533     dragData.setFileNames(fileNames);
1534
1535     return true;
1536 }
1537 #endif
1538
1539 void ArgumentCoder<CompositionUnderline>::encode(Encoder& encoder, const CompositionUnderline& underline)
1540 {
1541     encoder << underline.startOffset;
1542     encoder << underline.endOffset;
1543     encoder << underline.thick;
1544     encoder << underline.color;
1545 }
1546
1547 std::optional<CompositionUnderline> ArgumentCoder<CompositionUnderline>::decode(Decoder& decoder)
1548 {
1549     CompositionUnderline underline;
1550
1551     if (!decoder.decode(underline.startOffset))
1552         return std::nullopt;
1553     if (!decoder.decode(underline.endOffset))
1554         return std::nullopt;
1555     if (!decoder.decode(underline.thick))
1556         return std::nullopt;
1557     if (!decoder.decode(underline.color))
1558         return std::nullopt;
1559
1560     return WTFMove(underline);
1561 }
1562
1563 void ArgumentCoder<DatabaseDetails>::encode(Encoder& encoder, const DatabaseDetails& details)
1564 {
1565     encoder << details.name();
1566     encoder << details.displayName();
1567     encoder << details.expectedUsage();
1568     encoder << details.currentUsage();
1569     encoder << details.creationTime();
1570     encoder << details.modificationTime();
1571 }
1572     
1573 bool ArgumentCoder<DatabaseDetails>::decode(Decoder& decoder, DatabaseDetails& details)
1574 {
1575     String name;
1576     if (!decoder.decode(name))
1577         return false;
1578
1579     String displayName;
1580     if (!decoder.decode(displayName))
1581         return false;
1582
1583     uint64_t expectedUsage;
1584     if (!decoder.decode(expectedUsage))
1585         return false;
1586
1587     uint64_t currentUsage;
1588     if (!decoder.decode(currentUsage))
1589         return false;
1590
1591     double creationTime;
1592     if (!decoder.decode(creationTime))
1593         return false;
1594
1595     double modificationTime;
1596     if (!decoder.decode(modificationTime))
1597         return false;
1598
1599     details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime);
1600     return true;
1601 }
1602
1603 void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
1604 {
1605     encoder << data.origin;
1606     encoder << data.orderedTypes;
1607     encoder << data.platformData;
1608     encoder << data.sameOriginCustomData;
1609 }
1610
1611 bool ArgumentCoder<PasteboardCustomData>::decode(Decoder& decoder, PasteboardCustomData& data)
1612 {
1613     if (!decoder.decode(data.origin))
1614         return false;
1615
1616     if (!decoder.decode(data.orderedTypes))
1617         return false;
1618
1619     if (!decoder.decode(data.platformData))
1620         return false;
1621
1622     if (!decoder.decode(data.sameOriginCustomData))
1623         return false;
1624
1625     return true;
1626 }
1627
1628 #if PLATFORM(IOS)
1629
1630 void ArgumentCoder<Highlight>::encode(Encoder& encoder, const Highlight& highlight)
1631 {
1632     encoder << static_cast<uint32_t>(highlight.type);
1633     encoder << highlight.usePageCoordinates;
1634     encoder << highlight.contentColor;
1635     encoder << highlight.contentOutlineColor;
1636     encoder << highlight.paddingColor;
1637     encoder << highlight.borderColor;
1638     encoder << highlight.marginColor;
1639     encoder << highlight.quads;
1640 }
1641
1642 bool ArgumentCoder<Highlight>::decode(Decoder& decoder, Highlight& highlight)
1643 {
1644     uint32_t type;
1645     if (!decoder.decode(type))
1646         return false;
1647     highlight.type = (HighlightType)type;
1648
1649     if (!decoder.decode(highlight.usePageCoordinates))
1650         return false;
1651     if (!decoder.decode(highlight.contentColor))
1652         return false;
1653     if (!decoder.decode(highlight.contentOutlineColor))
1654         return false;
1655     if (!decoder.decode(highlight.paddingColor))
1656         return false;
1657     if (!decoder.decode(highlight.borderColor))
1658         return false;
1659     if (!decoder.decode(highlight.marginColor))
1660         return false;
1661     if (!decoder.decode(highlight.quads))
1662         return false;
1663     return true;
1664 }
1665
1666 void ArgumentCoder<PasteboardURL>::encode(Encoder& encoder, const PasteboardURL& content)
1667 {
1668     encoder << content.url;
1669     encoder << content.title;
1670 }
1671
1672 bool ArgumentCoder<PasteboardURL>::decode(Decoder& decoder, PasteboardURL& content)
1673 {
1674     if (!decoder.decode(content.url))
1675         return false;
1676
1677     if (!decoder.decode(content.title))
1678         return false;
1679
1680     return true;
1681 }
1682
1683 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1684 {
1685     encoder << content.contentOrigin;
1686     encoder << content.canSmartCopyOrDelete;
1687     encoder << content.dataInStringFormat;
1688     encoder << content.dataInHTMLFormat;
1689
1690     encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get());
1691     encodeSharedBuffer(encoder, content.dataInRTFDFormat.get());
1692     encodeSharedBuffer(encoder, content.dataInRTFFormat.get());
1693     encodeSharedBuffer(encoder, content.dataInAttributedStringFormat.get());
1694
1695     encodeTypesAndData(encoder, content.clientTypes, content.clientData);
1696 }
1697
1698 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1699 {
1700     if (!decoder.decode(content.contentOrigin))
1701         return false;
1702     if (!decoder.decode(content.canSmartCopyOrDelete))
1703         return false;
1704     if (!decoder.decode(content.dataInStringFormat))
1705         return false;
1706     if (!decoder.decode(content.dataInHTMLFormat))
1707         return false;
1708     if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat))
1709         return false;
1710     if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat))
1711         return false;
1712     if (!decodeSharedBuffer(decoder, content.dataInRTFFormat))
1713         return false;
1714     if (!decodeSharedBuffer(decoder, content.dataInAttributedStringFormat))
1715         return false;
1716     if (!decodeTypesAndData(decoder, content.clientTypes, content.clientData))
1717         return false;
1718     return true;
1719 }
1720
1721 void ArgumentCoder<PasteboardImage>::encode(Encoder& encoder, const PasteboardImage& pasteboardImage)
1722 {
1723     encodeOptionalImage(encoder, pasteboardImage.image.get());
1724     encoder << pasteboardImage.url.url;
1725     encoder << pasteboardImage.url.title;
1726     encoder << pasteboardImage.resourceMIMEType;
1727     encoder << pasteboardImage.suggestedName;
1728     encoder << pasteboardImage.imageSize;
1729     if (pasteboardImage.resourceData)
1730         encodeSharedBuffer(encoder, pasteboardImage.resourceData.get());
1731     encodeTypesAndData(encoder, pasteboardImage.clientTypes, pasteboardImage.clientData);
1732 }
1733
1734 bool ArgumentCoder<PasteboardImage>::decode(Decoder& decoder, PasteboardImage& pasteboardImage)
1735 {
1736     if (!decodeOptionalImage(decoder, pasteboardImage.image))
1737         return false;
1738     if (!decoder.decode(pasteboardImage.url.url))
1739         return false;
1740     if (!decoder.decode(pasteboardImage.url.title))
1741         return false;
1742     if (!decoder.decode(pasteboardImage.resourceMIMEType))
1743         return false;
1744     if (!decoder.decode(pasteboardImage.suggestedName))
1745         return false;
1746     if (!decoder.decode(pasteboardImage.imageSize))
1747         return false;
1748     if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData))
1749         return false;
1750     if (!decodeTypesAndData(decoder, pasteboardImage.clientTypes, pasteboardImage.clientData))
1751         return false;
1752     return true;
1753 }
1754
1755 #endif
1756
1757 #if PLATFORM(WPE)
1758 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1759 {
1760     encoder << content.text;
1761     encoder << content.markup;
1762 }
1763
1764 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1765 {
1766     if (!decoder.decode(content.text))
1767         return false;
1768     if (!decoder.decode(content.markup))
1769         return false;
1770     return true;
1771 }
1772 #endif // PLATFORM(WPE)
1773
1774 void ArgumentCoder<DictationAlternative>::encode(Encoder& encoder, const DictationAlternative& dictationAlternative)
1775 {
1776     encoder << dictationAlternative.rangeStart;
1777     encoder << dictationAlternative.rangeLength;
1778     encoder << dictationAlternative.dictationContext;
1779 }
1780
1781 std::optional<DictationAlternative> ArgumentCoder<DictationAlternative>::decode(Decoder& decoder)
1782 {
1783     std::optional<unsigned> rangeStart;
1784     decoder >> rangeStart;
1785     if (!rangeStart)
1786         return std::nullopt;
1787     
1788     std::optional<unsigned> rangeLength;
1789     decoder >> rangeLength;
1790     if (!rangeLength)
1791         return std::nullopt;
1792     
1793     std::optional<uint64_t> dictationContext;
1794     decoder >> dictationContext;
1795     if (!dictationContext)
1796         return std::nullopt;
1797     
1798     return {{ WTFMove(*rangeStart), WTFMove(*rangeLength), WTFMove(*dictationContext) }};
1799 }
1800
1801 void ArgumentCoder<FileChooserSettings>::encode(Encoder& encoder, const FileChooserSettings& settings)
1802 {
1803     encoder << settings.allowsDirectories;
1804     encoder << settings.allowsMultipleFiles;
1805     encoder << settings.acceptMIMETypes;
1806     encoder << settings.acceptFileExtensions;
1807     encoder << settings.selectedFiles;
1808 #if ENABLE(MEDIA_CAPTURE)
1809     encoder.encodeEnum(settings.mediaCaptureType);
1810 #endif
1811 }
1812
1813 bool ArgumentCoder<FileChooserSettings>::decode(Decoder& decoder, FileChooserSettings& settings)
1814 {
1815     if (!decoder.decode(settings.allowsDirectories))
1816         return false;
1817     if (!decoder.decode(settings.allowsMultipleFiles))
1818         return false;
1819     if (!decoder.decode(settings.acceptMIMETypes))
1820         return false;
1821     if (!decoder.decode(settings.acceptFileExtensions))
1822         return false;
1823     if (!decoder.decode(settings.selectedFiles))
1824         return false;
1825 #if ENABLE(MEDIA_CAPTURE)
1826     if (!decoder.decodeEnum(settings.mediaCaptureType))
1827         return false;
1828 #endif
1829
1830     return true;
1831 }
1832
1833
1834 void ArgumentCoder<GrammarDetail>::encode(Encoder& encoder, const GrammarDetail& detail)
1835 {
1836     encoder << detail.location;
1837     encoder << detail.length;
1838     encoder << detail.guesses;
1839     encoder << detail.userDescription;
1840 }
1841
1842 std::optional<GrammarDetail> ArgumentCoder<GrammarDetail>::decode(Decoder& decoder)
1843 {
1844     std::optional<int> location;
1845     decoder >> location;
1846     if (!location)
1847         return std::nullopt;
1848
1849     std::optional<int> length;
1850     decoder >> length;
1851     if (!length)
1852         return std::nullopt;
1853
1854     std::optional<Vector<String>> guesses;
1855     decoder >> guesses;
1856     if (!guesses)
1857         return std::nullopt;
1858
1859     std::optional<String> userDescription;
1860     decoder >> userDescription;
1861     if (!userDescription)
1862         return std::nullopt;
1863
1864     return {{ WTFMove(*location), WTFMove(*length), WTFMove(*guesses), WTFMove(*userDescription) }};
1865 }
1866
1867 void ArgumentCoder<TextCheckingRequestData>::encode(Encoder& encoder, const TextCheckingRequestData& request)
1868 {
1869     encoder << request.sequence();
1870     encoder << request.text();
1871     encoder << request.mask();
1872     encoder.encodeEnum(request.processType());
1873 }
1874
1875 bool ArgumentCoder<TextCheckingRequestData>::decode(Decoder& decoder, TextCheckingRequestData& request)
1876 {
1877     int sequence;
1878     if (!decoder.decode(sequence))
1879         return false;
1880
1881     String text;
1882     if (!decoder.decode(text))
1883         return false;
1884
1885     TextCheckingTypeMask mask;
1886     if (!decoder.decode(mask))
1887         return false;
1888
1889     TextCheckingProcessType processType;
1890     if (!decoder.decodeEnum(processType))
1891         return false;
1892
1893     request = TextCheckingRequestData(sequence, text, mask, processType);
1894     return true;
1895 }
1896
1897 void ArgumentCoder<TextCheckingResult>::encode(Encoder& encoder, const TextCheckingResult& result)
1898 {
1899     encoder.encodeEnum(result.type);
1900     encoder << result.location;
1901     encoder << result.length;
1902     encoder << result.details;
1903     encoder << result.replacement;
1904 }
1905
1906 std::optional<TextCheckingResult> ArgumentCoder<TextCheckingResult>::decode(Decoder& decoder)
1907 {
1908     TextCheckingType type;
1909     if (!decoder.decodeEnum(type))
1910         return std::nullopt;
1911     
1912     std::optional<int> location;
1913     decoder >> location;
1914     if (!location)
1915         return std::nullopt;
1916
1917     std::optional<int> length;
1918     decoder >> length;
1919     if (!length)
1920         return std::nullopt;
1921
1922     std::optional<Vector<GrammarDetail>> details;
1923     decoder >> details;
1924     if (!details)
1925         return std::nullopt;
1926
1927     std::optional<String> replacement;
1928     decoder >> replacement;
1929     if (!replacement)
1930         return std::nullopt;
1931
1932     return {{ WTFMove(type), WTFMove(*location), WTFMove(*length), WTFMove(*details), WTFMove(*replacement) }};
1933 }
1934
1935 void ArgumentCoder<UserStyleSheet>::encode(Encoder& encoder, const UserStyleSheet& userStyleSheet)
1936 {
1937     encoder << userStyleSheet.source();
1938     encoder << userStyleSheet.url();
1939     encoder << userStyleSheet.whitelist();
1940     encoder << userStyleSheet.blacklist();
1941     encoder.encodeEnum(userStyleSheet.injectedFrames());
1942     encoder.encodeEnum(userStyleSheet.level());
1943 }
1944
1945 bool ArgumentCoder<UserStyleSheet>::decode(Decoder& decoder, UserStyleSheet& userStyleSheet)
1946 {
1947     String source;
1948     if (!decoder.decode(source))
1949         return false;
1950
1951     URL url;
1952     if (!decoder.decode(url))
1953         return false;
1954
1955     Vector<String> whitelist;
1956     if (!decoder.decode(whitelist))
1957         return false;
1958
1959     Vector<String> blacklist;
1960     if (!decoder.decode(blacklist))
1961         return false;
1962
1963     UserContentInjectedFrames injectedFrames;
1964     if (!decoder.decodeEnum(injectedFrames))
1965         return false;
1966
1967     UserStyleLevel level;
1968     if (!decoder.decodeEnum(level))
1969         return false;
1970
1971     userStyleSheet = UserStyleSheet(source, url, WTFMove(whitelist), WTFMove(blacklist), injectedFrames, level);
1972     return true;
1973 }
1974
1975 #if ENABLE(MEDIA_SESSION)
1976 void ArgumentCoder<MediaSessionMetadata>::encode(Encoder& encoder, const MediaSessionMetadata& result)
1977 {
1978     encoder << result.artist();
1979     encoder << result.album();
1980     encoder << result.title();
1981     encoder << result.artworkURL();
1982 }
1983
1984 bool ArgumentCoder<MediaSessionMetadata>::decode(Decoder& decoder, MediaSessionMetadata& result)
1985 {
1986     String artist, album, title;
1987     URL artworkURL;
1988     if (!decoder.decode(artist))
1989         return false;
1990     if (!decoder.decode(album))
1991         return false;
1992     if (!decoder.decode(title))
1993         return false;
1994     if (!decoder.decode(artworkURL))
1995         return false;
1996     result = MediaSessionMetadata(title, artist, album, artworkURL);
1997     return true;
1998 }
1999 #endif
2000
2001 void ArgumentCoder<ScrollableAreaParameters>::encode(Encoder& encoder, const ScrollableAreaParameters& parameters)
2002 {
2003     encoder.encodeEnum(parameters.horizontalScrollElasticity);
2004     encoder.encodeEnum(parameters.verticalScrollElasticity);
2005
2006     encoder.encodeEnum(parameters.horizontalScrollbarMode);
2007     encoder.encodeEnum(parameters.verticalScrollbarMode);
2008
2009     encoder << parameters.hasEnabledHorizontalScrollbar;
2010     encoder << parameters.hasEnabledVerticalScrollbar;
2011 }
2012
2013 bool ArgumentCoder<ScrollableAreaParameters>::decode(Decoder& decoder, ScrollableAreaParameters& params)
2014 {
2015     if (!decoder.decodeEnum(params.horizontalScrollElasticity))
2016         return false;
2017     if (!decoder.decodeEnum(params.verticalScrollElasticity))
2018         return false;
2019
2020     if (!decoder.decodeEnum(params.horizontalScrollbarMode))
2021         return false;
2022     if (!decoder.decodeEnum(params.verticalScrollbarMode))
2023         return false;
2024
2025     if (!decoder.decode(params.hasEnabledHorizontalScrollbar))
2026         return false;
2027     if (!decoder.decode(params.hasEnabledVerticalScrollbar))
2028         return false;
2029     
2030     return true;
2031 }
2032
2033 void ArgumentCoder<FixedPositionViewportConstraints>::encode(Encoder& encoder, const FixedPositionViewportConstraints& viewportConstraints)
2034 {
2035     encoder << viewportConstraints.alignmentOffset();
2036     encoder << viewportConstraints.anchorEdges();
2037
2038     encoder << viewportConstraints.viewportRectAtLastLayout();
2039     encoder << viewportConstraints.layerPositionAtLastLayout();
2040 }
2041
2042 bool ArgumentCoder<FixedPositionViewportConstraints>::decode(Decoder& decoder, FixedPositionViewportConstraints& viewportConstraints)
2043 {
2044     FloatSize alignmentOffset;
2045     if (!decoder.decode(alignmentOffset))
2046         return false;
2047     
2048     ViewportConstraints::AnchorEdges anchorEdges;
2049     if (!decoder.decode(anchorEdges))
2050         return false;
2051
2052     FloatRect viewportRectAtLastLayout;
2053     if (!decoder.decode(viewportRectAtLastLayout))
2054         return false;
2055
2056     FloatPoint layerPositionAtLastLayout;
2057     if (!decoder.decode(layerPositionAtLastLayout))
2058         return false;
2059
2060     viewportConstraints = FixedPositionViewportConstraints();
2061     viewportConstraints.setAlignmentOffset(alignmentOffset);
2062     viewportConstraints.setAnchorEdges(anchorEdges);
2063
2064     viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout);
2065     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2066     
2067     return true;
2068 }
2069
2070 void ArgumentCoder<StickyPositionViewportConstraints>::encode(Encoder& encoder, const StickyPositionViewportConstraints& viewportConstraints)
2071 {
2072     encoder << viewportConstraints.alignmentOffset();
2073     encoder << viewportConstraints.anchorEdges();
2074
2075     encoder << viewportConstraints.leftOffset();
2076     encoder << viewportConstraints.rightOffset();
2077     encoder << viewportConstraints.topOffset();
2078     encoder << viewportConstraints.bottomOffset();
2079
2080     encoder << viewportConstraints.constrainingRectAtLastLayout();
2081     encoder << viewportConstraints.containingBlockRect();
2082     encoder << viewportConstraints.stickyBoxRect();
2083
2084     encoder << viewportConstraints.stickyOffsetAtLastLayout();
2085     encoder << viewportConstraints.layerPositionAtLastLayout();
2086 }
2087
2088 bool ArgumentCoder<StickyPositionViewportConstraints>::decode(Decoder& decoder, StickyPositionViewportConstraints& viewportConstraints)
2089 {
2090     FloatSize alignmentOffset;
2091     if (!decoder.decode(alignmentOffset))
2092         return false;
2093     
2094     ViewportConstraints::AnchorEdges anchorEdges;
2095     if (!decoder.decode(anchorEdges))
2096         return false;
2097     
2098     float leftOffset;
2099     if (!decoder.decode(leftOffset))
2100         return false;
2101
2102     float rightOffset;
2103     if (!decoder.decode(rightOffset))
2104         return false;
2105
2106     float topOffset;
2107     if (!decoder.decode(topOffset))
2108         return false;
2109
2110     float bottomOffset;
2111     if (!decoder.decode(bottomOffset))
2112         return false;
2113     
2114     FloatRect constrainingRectAtLastLayout;
2115     if (!decoder.decode(constrainingRectAtLastLayout))
2116         return false;
2117
2118     FloatRect containingBlockRect;
2119     if (!decoder.decode(containingBlockRect))
2120         return false;
2121
2122     FloatRect stickyBoxRect;
2123     if (!decoder.decode(stickyBoxRect))
2124         return false;
2125
2126     FloatSize stickyOffsetAtLastLayout;
2127     if (!decoder.decode(stickyOffsetAtLastLayout))
2128         return false;
2129     
2130     FloatPoint layerPositionAtLastLayout;
2131     if (!decoder.decode(layerPositionAtLastLayout))
2132         return false;
2133     
2134     viewportConstraints = StickyPositionViewportConstraints();
2135     viewportConstraints.setAlignmentOffset(alignmentOffset);
2136     viewportConstraints.setAnchorEdges(anchorEdges);
2137
2138     viewportConstraints.setLeftOffset(leftOffset);
2139     viewportConstraints.setRightOffset(rightOffset);
2140     viewportConstraints.setTopOffset(topOffset);
2141     viewportConstraints.setBottomOffset(bottomOffset);
2142     
2143     viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout);
2144     viewportConstraints.setContainingBlockRect(containingBlockRect);
2145     viewportConstraints.setStickyBoxRect(stickyBoxRect);
2146
2147     viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout);
2148     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2149
2150     return true;
2151 }
2152
2153 #if !USE(COORDINATED_GRAPHICS)
2154 void ArgumentCoder<FilterOperation>::encode(Encoder& encoder, const FilterOperation& filter)
2155 {
2156     encoder.encodeEnum(filter.type());
2157
2158     switch (filter.type()) {
2159     case FilterOperation::NONE:
2160     case FilterOperation::REFERENCE:
2161         ASSERT_NOT_REACHED();
2162         break;
2163     case FilterOperation::GRAYSCALE:
2164     case FilterOperation::SEPIA:
2165     case FilterOperation::SATURATE:
2166     case FilterOperation::HUE_ROTATE:
2167         encoder << downcast<BasicColorMatrixFilterOperation>(filter).amount();
2168         break;
2169     case FilterOperation::INVERT:
2170     case FilterOperation::OPACITY:
2171     case FilterOperation::BRIGHTNESS:
2172     case FilterOperation::CONTRAST:
2173         encoder << downcast<BasicComponentTransferFilterOperation>(filter).amount();
2174         break;
2175     case FilterOperation::BLUR:
2176         encoder << downcast<BlurFilterOperation>(filter).stdDeviation();
2177         break;
2178     case FilterOperation::DROP_SHADOW: {
2179         const auto& dropShadowFilter = downcast<DropShadowFilterOperation>(filter);
2180         encoder << dropShadowFilter.location();
2181         encoder << dropShadowFilter.stdDeviation();
2182         encoder << dropShadowFilter.color();
2183         break;
2184     }
2185     case FilterOperation::DEFAULT:
2186         encoder.encodeEnum(downcast<DefaultFilterOperation>(filter).representedType());
2187         break;
2188     case FilterOperation::PASSTHROUGH:
2189         break;
2190     }
2191 }
2192
2193 bool decodeFilterOperation(Decoder& decoder, RefPtr<FilterOperation>& filter)
2194 {
2195     FilterOperation::OperationType type;
2196     if (!decoder.decodeEnum(type))
2197         return false;
2198
2199     switch (type) {
2200     case FilterOperation::NONE:
2201     case FilterOperation::REFERENCE:
2202         ASSERT_NOT_REACHED();
2203         decoder.markInvalid();
2204         return false;
2205     case FilterOperation::GRAYSCALE:
2206     case FilterOperation::SEPIA:
2207     case FilterOperation::SATURATE:
2208     case FilterOperation::HUE_ROTATE: {
2209         double amount;
2210         if (!decoder.decode(amount))
2211             return false;
2212         filter = BasicColorMatrixFilterOperation::create(amount, type);
2213         break;
2214     }
2215     case FilterOperation::INVERT:
2216     case FilterOperation::OPACITY:
2217     case FilterOperation::BRIGHTNESS:
2218     case FilterOperation::CONTRAST: {
2219         double amount;
2220         if (!decoder.decode(amount))
2221             return false;
2222         filter = BasicComponentTransferFilterOperation::create(amount, type);
2223         break;
2224     }
2225     case FilterOperation::BLUR: {
2226         Length stdDeviation;
2227         if (!decoder.decode(stdDeviation))
2228             return false;
2229         filter = BlurFilterOperation::create(stdDeviation);
2230         break;
2231     }
2232     case FilterOperation::DROP_SHADOW: {
2233         IntPoint location;
2234         int stdDeviation;
2235         Color color;
2236         if (!decoder.decode(location))
2237             return false;
2238         if (!decoder.decode(stdDeviation))
2239             return false;
2240         if (!decoder.decode(color))
2241             return false;
2242         filter = DropShadowFilterOperation::create(location, stdDeviation, color);
2243         break;
2244     }
2245     case FilterOperation::DEFAULT: {
2246         FilterOperation::OperationType representedType;
2247         if (!decoder.decodeEnum(representedType))
2248             return false;
2249         filter = DefaultFilterOperation::create(representedType);
2250         break;
2251     }
2252     case FilterOperation::PASSTHROUGH:
2253         filter = PassthroughFilterOperation::create();
2254         break;
2255     }
2256             
2257     return true;
2258 }
2259
2260
2261 void ArgumentCoder<FilterOperations>::encode(Encoder& encoder, const FilterOperations& filters)
2262 {
2263     encoder << static_cast<uint64_t>(filters.size());
2264
2265     for (const auto& filter : filters.operations())
2266         encoder << *filter;
2267 }
2268
2269 bool ArgumentCoder<FilterOperations>::decode(Decoder& decoder, FilterOperations& filters)
2270 {
2271     uint64_t filterCount;
2272     if (!decoder.decode(filterCount))
2273         return false;
2274
2275     for (uint64_t i = 0; i < filterCount; ++i) {
2276         RefPtr<FilterOperation> filter;
2277         if (!decodeFilterOperation(decoder, filter))
2278             return false;
2279         filters.operations().append(WTFMove(filter));
2280     }
2281
2282     return true;
2283 }
2284 #endif // !USE(COORDINATED_GRAPHICS)
2285
2286 void ArgumentCoder<BlobPart>::encode(Encoder& encoder, const BlobPart& blobPart)
2287 {
2288     encoder << static_cast<uint32_t>(blobPart.type());
2289     switch (blobPart.type()) {
2290     case BlobPart::Data:
2291         encoder << blobPart.data();
2292         break;
2293     case BlobPart::Blob:
2294         encoder << blobPart.url();
2295         break;
2296     }
2297 }
2298
2299 std::optional<BlobPart> ArgumentCoder<BlobPart>::decode(Decoder& decoder)
2300 {
2301     BlobPart blobPart;
2302
2303     std::optional<uint32_t> type;
2304     decoder >> type;
2305     if (!type)
2306         return std::nullopt;
2307
2308     switch (*type) {
2309     case BlobPart::Data: {
2310         std::optional<Vector<uint8_t>> data;
2311         decoder >> data;
2312         if (!data)
2313             return std::nullopt;
2314         blobPart = BlobPart(WTFMove(*data));
2315         break;
2316     }
2317     case BlobPart::Blob: {
2318         URL url;
2319         if (!decoder.decode(url))
2320             return std::nullopt;
2321         blobPart = BlobPart(url);
2322         break;
2323     }
2324     default:
2325         return std::nullopt;
2326     }
2327
2328     return WTFMove(blobPart);
2329 }
2330
2331 void ArgumentCoder<TextIndicatorData>::encode(Encoder& encoder, const TextIndicatorData& textIndicatorData)
2332 {
2333     encoder << textIndicatorData.selectionRectInRootViewCoordinates;
2334     encoder << textIndicatorData.textBoundingRectInRootViewCoordinates;
2335     encoder << textIndicatorData.textRectsInBoundingRectCoordinates;
2336     encoder << textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates;
2337     encoder << textIndicatorData.contentImageScaleFactor;
2338     encoder << textIndicatorData.estimatedBackgroundColor;
2339     encoder.encodeEnum(textIndicatorData.presentationTransition);
2340     encoder << static_cast<uint64_t>(textIndicatorData.options);
2341
2342     encodeOptionalImage(encoder, textIndicatorData.contentImage.get());
2343     encodeOptionalImage(encoder, textIndicatorData.contentImageWithHighlight.get());
2344     encodeOptionalImage(encoder, textIndicatorData.contentImageWithoutSelection.get());
2345 }
2346
2347 std::optional<TextIndicatorData> ArgumentCoder<TextIndicatorData>::decode(Decoder& decoder)
2348 {
2349     TextIndicatorData textIndicatorData;
2350     if (!decoder.decode(textIndicatorData.selectionRectInRootViewCoordinates))
2351         return std::nullopt;
2352
2353     if (!decoder.decode(textIndicatorData.textBoundingRectInRootViewCoordinates))
2354         return std::nullopt;
2355
2356     if (!decoder.decode(textIndicatorData.textRectsInBoundingRectCoordinates))
2357         return std::nullopt;
2358
2359     if (!decoder.decode(textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates))
2360         return std::nullopt;
2361
2362     if (!decoder.decode(textIndicatorData.contentImageScaleFactor))
2363         return std::nullopt;
2364
2365     if (!decoder.decode(textIndicatorData.estimatedBackgroundColor))
2366         return std::nullopt;
2367
2368     if (!decoder.decodeEnum(textIndicatorData.presentationTransition))
2369         return std::nullopt;
2370
2371     uint64_t options;
2372     if (!decoder.decode(options))
2373         return std::nullopt;
2374     textIndicatorData.options = static_cast<TextIndicatorOptions>(options);
2375
2376     if (!decodeOptionalImage(decoder, textIndicatorData.contentImage))
2377         return std::nullopt;
2378
2379     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithHighlight))
2380         return std::nullopt;
2381
2382     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithoutSelection))
2383         return std::nullopt;
2384
2385     return WTFMove(textIndicatorData);
2386 }
2387
2388 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
2389 void ArgumentCoder<MediaPlaybackTargetContext>::encode(Encoder& encoder, const MediaPlaybackTargetContext& target)
2390 {
2391     bool hasPlatformData = target.encodingRequiresPlatformData();
2392     encoder << hasPlatformData;
2393
2394     int32_t targetType = target.type();
2395     encoder << targetType;
2396
2397     if (target.encodingRequiresPlatformData()) {
2398         encodePlatformData(encoder, target);
2399         return;
2400     }
2401
2402     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2403     encoder << target.mockDeviceName();
2404     encoder << static_cast<int32_t>(target.mockState());
2405 }
2406
2407 bool ArgumentCoder<MediaPlaybackTargetContext>::decode(Decoder& decoder, MediaPlaybackTargetContext& target)
2408 {
2409     bool hasPlatformData;
2410     if (!decoder.decode(hasPlatformData))
2411         return false;
2412
2413     int32_t targetType;
2414     if (!decoder.decode(targetType))
2415         return false;
2416
2417     if (hasPlatformData)
2418         return decodePlatformData(decoder, target);
2419
2420     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2421
2422     String mockDeviceName;
2423     if (!decoder.decode(mockDeviceName))
2424         return false;
2425
2426     int32_t mockState;
2427     if (!decoder.decode(mockState))
2428         return false;
2429
2430     target = MediaPlaybackTargetContext(mockDeviceName, static_cast<MediaPlaybackTargetContext::State>(mockState));
2431     return true;
2432 }
2433 #endif
2434
2435 void ArgumentCoder<DictionaryPopupInfo>::encode(IPC::Encoder& encoder, const DictionaryPopupInfo& info)
2436 {
2437     encoder << info.origin;
2438     encoder << info.textIndicator;
2439
2440 #if PLATFORM(COCOA)
2441     bool hadOptions = info.options;
2442     encoder << hadOptions;
2443     if (hadOptions)
2444         IPC::encode(encoder, info.options.get());
2445
2446     bool hadAttributedString = info.attributedString;
2447     encoder << hadAttributedString;
2448     if (hadAttributedString)
2449         IPC::encode(encoder, info.attributedString.get());
2450 #endif
2451 }
2452
2453 bool ArgumentCoder<DictionaryPopupInfo>::decode(IPC::Decoder& decoder, DictionaryPopupInfo& result)
2454 {
2455     if (!decoder.decode(result.origin))
2456         return false;
2457
2458     std::optional<TextIndicatorData> textIndicator;
2459     decoder >> textIndicator;
2460     if (!textIndicator)
2461         return false;
2462     result.textIndicator = WTFMove(*textIndicator);
2463
2464 #if PLATFORM(COCOA)
2465     bool hadOptions;
2466     if (!decoder.decode(hadOptions))
2467         return false;
2468     if (hadOptions) {
2469         if (!IPC::decode(decoder, result.options))
2470             return false;
2471     } else
2472         result.options = nullptr;
2473
2474     bool hadAttributedString;
2475     if (!decoder.decode(hadAttributedString))
2476         return false;
2477     if (hadAttributedString) {
2478         if (!IPC::decode(decoder, result.attributedString))
2479             return false;
2480     } else
2481         result.attributedString = nullptr;
2482 #endif
2483     return true;
2484 }
2485
2486 void ArgumentCoder<ExceptionDetails>::encode(IPC::Encoder& encoder, const ExceptionDetails& info)
2487 {
2488     encoder << info.message;
2489     encoder << info.lineNumber;
2490     encoder << info.columnNumber;
2491     encoder << info.sourceURL;
2492 }
2493
2494 bool ArgumentCoder<ExceptionDetails>::decode(IPC::Decoder& decoder, ExceptionDetails& result)
2495 {
2496     if (!decoder.decode(result.message))
2497         return false;
2498
2499     if (!decoder.decode(result.lineNumber))
2500         return false;
2501
2502     if (!decoder.decode(result.columnNumber))
2503         return false;
2504
2505     if (!decoder.decode(result.sourceURL))
2506         return false;
2507
2508     return true;
2509 }
2510
2511 void ArgumentCoder<ResourceLoadStatistics>::encode(Encoder& encoder, const WebCore::ResourceLoadStatistics& statistics)
2512 {
2513     encoder << statistics.highLevelDomain;
2514     
2515     encoder << statistics.lastSeen.secondsSinceEpoch().value();
2516     
2517     // User interaction
2518     encoder << statistics.hadUserInteraction;
2519     encoder << statistics.mostRecentUserInteractionTime.secondsSinceEpoch().value();
2520     encoder << statistics.grandfathered;
2521
2522     // Storage access
2523     encoder << statistics.storageAccessUnderTopFrameOrigins;
2524
2525     // Top frame stats
2526     encoder << statistics.topFrameUniqueRedirectsTo;
2527     encoder << statistics.topFrameUniqueRedirectsFrom;
2528
2529     // Subframe stats
2530     encoder << statistics.subframeUnderTopFrameOrigins;
2531     
2532     // Subresource stats
2533     encoder << statistics.subresourceUnderTopFrameOrigins;
2534     encoder << statistics.subresourceUniqueRedirectsTo;
2535     encoder << statistics.subresourceUniqueRedirectsFrom;
2536
2537     // Prevalent Resource
2538     encoder << statistics.isPrevalentResource;
2539     encoder << statistics.isVeryPrevalentResource;
2540     encoder << statistics.dataRecordsRemoved;
2541 }
2542
2543 std::optional<ResourceLoadStatistics> ArgumentCoder<ResourceLoadStatistics>::decode(Decoder& decoder)
2544 {
2545     ResourceLoadStatistics statistics;
2546     if (!decoder.decode(statistics.highLevelDomain))
2547         return std::nullopt;
2548     
2549     double lastSeenTimeAsDouble;
2550     if (!decoder.decode(lastSeenTimeAsDouble))
2551         return std::nullopt;
2552     statistics.lastSeen = WallTime::fromRawSeconds(lastSeenTimeAsDouble);
2553     
2554     // User interaction
2555     if (!decoder.decode(statistics.hadUserInteraction))
2556         return std::nullopt;
2557
2558     double mostRecentUserInteractionTimeAsDouble;
2559     if (!decoder.decode(mostRecentUserInteractionTimeAsDouble))
2560         return std::nullopt;
2561     statistics.mostRecentUserInteractionTime = WallTime::fromRawSeconds(mostRecentUserInteractionTimeAsDouble);
2562
2563     if (!decoder.decode(statistics.grandfathered))
2564         return std::nullopt;
2565
2566     // Storage access
2567     if (!decoder.decode(statistics.storageAccessUnderTopFrameOrigins))
2568         return std::nullopt;
2569
2570     // Top frame stats
2571     if (!decoder.decode(statistics.topFrameUniqueRedirectsTo))
2572         return std::nullopt;    
2573
2574     if (!decoder.decode(statistics.topFrameUniqueRedirectsFrom))
2575         return std::nullopt;
2576
2577     // Subframe stats
2578     if (!decoder.decode(statistics.subframeUnderTopFrameOrigins))
2579         return std::nullopt;
2580     
2581     // Subresource stats
2582     if (!decoder.decode(statistics.subresourceUnderTopFrameOrigins))
2583         return std::nullopt;
2584
2585     if (!decoder.decode(statistics.subresourceUniqueRedirectsTo))
2586         return std::nullopt;
2587     
2588     if (!decoder.decode(statistics.subresourceUniqueRedirectsFrom))
2589         return std::nullopt;
2590     
2591     // Prevalent Resource
2592     if (!decoder.decode(statistics.isPrevalentResource))
2593         return std::nullopt;
2594
2595     if (!decoder.decode(statistics.isVeryPrevalentResource))
2596         return std::nullopt;
2597     
2598     if (!decoder.decode(statistics.dataRecordsRemoved))
2599         return std::nullopt;
2600
2601     return WTFMove(statistics);
2602 }
2603
2604 #if ENABLE(MEDIA_STREAM)
2605 void ArgumentCoder<MediaConstraints>::encode(Encoder& encoder, const WebCore::MediaConstraints& constraint)
2606 {
2607     encoder << constraint.mandatoryConstraints
2608         << constraint.advancedConstraints
2609         << constraint.deviceIDHashSalt
2610         << constraint.isValid;
2611 }
2612
2613 bool ArgumentCoder<MediaConstraints>::decode(Decoder& decoder, WebCore::MediaConstraints& constraints)
2614 {
2615     std::optional<WebCore::MediaTrackConstraintSetMap> mandatoryConstraints;
2616     decoder >> mandatoryConstraints;
2617     if (!mandatoryConstraints)
2618         return false;
2619     constraints.mandatoryConstraints = WTFMove(*mandatoryConstraints);
2620     return decoder.decode(constraints.advancedConstraints)
2621         && decoder.decode(constraints.deviceIDHashSalt)
2622         && decoder.decode(constraints.isValid);
2623 }
2624 #endif
2625
2626 #if ENABLE(INDEXED_DATABASE)
2627 void ArgumentCoder<IDBKeyPath>::encode(Encoder& encoder, const IDBKeyPath& keyPath)
2628 {
2629     bool isString = WTF::holds_alternative<String>(keyPath);
2630     encoder << isString;
2631     if (isString)
2632         encoder << WTF::get<String>(keyPath);
2633     else
2634         encoder << WTF::get<Vector<String>>(keyPath);
2635 }
2636
2637 bool ArgumentCoder<IDBKeyPath>::decode(Decoder& decoder, IDBKeyPath& keyPath)
2638 {
2639     bool isString;
2640     if (!decoder.decode(isString))
2641         return false;
2642     if (isString) {
2643         String string;
2644         if (!decoder.decode(string))
2645             return false;
2646         keyPath = string;
2647     } else {
2648         Vector<String> vector;
2649         if (!decoder.decode(vector))
2650             return false;
2651         keyPath = vector;
2652     }
2653     return true;
2654 }
2655 #endif
2656
2657 #if ENABLE(SERVICE_WORKER)
2658 void ArgumentCoder<ServiceWorkerOrClientData>::encode(Encoder& encoder, const ServiceWorkerOrClientData& data)
2659 {
2660     bool isServiceWorkerData = WTF::holds_alternative<ServiceWorkerData>(data);
2661     encoder << isServiceWorkerData;
2662     if (isServiceWorkerData)
2663         encoder << WTF::get<ServiceWorkerData>(data);
2664     else
2665         encoder << WTF::get<ServiceWorkerClientData>(data);
2666 }
2667
2668 bool ArgumentCoder<ServiceWorkerOrClientData>::decode(Decoder& decoder, ServiceWorkerOrClientData& data)
2669 {
2670     bool isServiceWorkerData;
2671     if (!decoder.decode(isServiceWorkerData))
2672         return false;
2673     if (isServiceWorkerData) {
2674         std::optional<ServiceWorkerData> workerData;
2675         decoder >> workerData;
2676         if (!workerData)
2677             return false;
2678
2679         data = WTFMove(*workerData);
2680     } else {
2681         std::optional<ServiceWorkerClientData> clientData;
2682         decoder >> clientData;
2683         if (!clientData)
2684             return false;
2685
2686         data = WTFMove(*clientData);
2687     }
2688     return true;
2689 }
2690
2691 void ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode(Encoder& encoder, const ServiceWorkerOrClientIdentifier& identifier)
2692 {
2693     bool isServiceWorkerIdentifier = WTF::holds_alternative<ServiceWorkerIdentifier>(identifier);
2694     encoder << isServiceWorkerIdentifier;
2695     if (isServiceWorkerIdentifier)
2696         encoder << WTF::get<ServiceWorkerIdentifier>(identifier);
2697     else
2698         encoder << WTF::get<ServiceWorkerClientIdentifier>(identifier);
2699 }
2700
2701 bool ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode(Decoder& decoder, ServiceWorkerOrClientIdentifier& identifier)
2702 {
2703     bool isServiceWorkerIdentifier;
2704     if (!decoder.decode(isServiceWorkerIdentifier))
2705         return false;
2706     if (isServiceWorkerIdentifier) {
2707         std::optional<ServiceWorkerIdentifier> workerIdentifier;
2708         decoder >> workerIdentifier;
2709         if (!workerIdentifier)
2710             return false;
2711
2712         identifier = WTFMove(*workerIdentifier);
2713     } else {
2714         std::optional<ServiceWorkerClientIdentifier> clientIdentifier;
2715         decoder >> clientIdentifier;
2716         if (!clientIdentifier)
2717             return false;
2718
2719         identifier = WTFMove(*clientIdentifier);
2720     }
2721     return true;
2722 }
2723 #endif
2724
2725 #if ENABLE(CSS_SCROLL_SNAP)
2726
2727 void ArgumentCoder<ScrollOffsetRange<float>>::encode(Encoder& encoder, const ScrollOffsetRange<float>& range)
2728 {
2729     encoder << range.start;
2730     encoder << range.end;
2731 }
2732
2733 auto ArgumentCoder<ScrollOffsetRange<float>>::decode(Decoder& decoder) -> std::optional<WebCore::ScrollOffsetRange<float>>
2734 {
2735     WebCore::ScrollOffsetRange<float> range;
2736     float start;
2737     if (!decoder.decode(start))
2738         return std::nullopt;
2739
2740     float end;
2741     if (!decoder.decode(end))
2742         return std::nullopt;
2743
2744     range.start = start;
2745     range.end = end;
2746     return WTFMove(range);
2747 }
2748
2749 #endif
2750
2751 void ArgumentCoder<MediaSelectionOption>::encode(Encoder& encoder, const MediaSelectionOption& option)
2752 {
2753     encoder << option.displayName;
2754     encoder << option.type;
2755 }
2756
2757 std::optional<MediaSelectionOption> ArgumentCoder<MediaSelectionOption>::decode(Decoder& decoder)
2758 {
2759     std::optional<String> displayName;
2760     decoder >> displayName;
2761     if (!displayName)
2762         return std::nullopt;
2763     
2764     std::optional<MediaSelectionOption::Type> type;
2765     decoder >> type;
2766     if (!type)
2767         return std::nullopt;
2768     
2769     return {{ WTFMove(*displayName), WTFMove(*type) }};
2770 }
2771
2772 void ArgumentCoder<PromisedBlobInfo>::encode(Encoder& encoder, const PromisedBlobInfo& info)
2773 {
2774     encoder << info.blobURL;
2775     encoder << info.contentType;
2776     encoder << info.filename;
2777     encodeTypesAndData(encoder, info.additionalTypes, info.additionalData);
2778 }
2779
2780 bool ArgumentCoder<PromisedBlobInfo>::decode(Decoder& decoder, PromisedBlobInfo& info)
2781 {
2782     if (!decoder.decode(info.blobURL))
2783         return false;
2784
2785     if (!decoder.decode(info.contentType))
2786         return false;
2787
2788     if (!decoder.decode(info.filename))
2789         return false;
2790
2791     if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData))
2792         return false;
2793
2794     return true;
2795 }
2796
2797 #if ENABLE(ATTACHMENT_ELEMENT)
2798
2799 void ArgumentCoder<AttachmentInfo>::encode(Encoder& encoder, const AttachmentInfo& info)
2800 {
2801     bool dataIsNull = !info.data;
2802     encoder << info.contentType << info.name << info.filePath << dataIsNull;
2803     if (!dataIsNull) {
2804         SharedBufferDataReference dataReference { info.data.get() };
2805         encoder << static_cast<DataReference&>(dataReference);
2806     }
2807 }
2808
2809 bool ArgumentCoder<AttachmentInfo>::decode(Decoder& decoder, AttachmentInfo& info)
2810 {
2811     if (!decoder.decode(info.contentType))
2812         return false;
2813
2814     if (!decoder.decode(info.name))
2815         return false;
2816
2817     if (!decoder.decode(info.filePath))
2818         return false;
2819
2820     bool dataIsNull = true;
2821     if (!decoder.decode(dataIsNull))
2822         return false;
2823
2824     if (!dataIsNull) {
2825         DataReference dataReference;
2826         if (!decoder.decode(dataReference))
2827             return false;
2828         info.data = SharedBuffer::create(dataReference.data(), dataReference.size());
2829     }
2830
2831     return true;
2832 }
2833
2834 #endif // ENABLE(ATTACHMENT_ELEMENT)
2835
2836 } // namespace IPC