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