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