Support drag-and-drop 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 std::optional<Path> ArgumentCoder<Path>::decode(Decoder& decoder)
856 {
857     Path path;
858     if (!decode(decoder, path))
859         return std::nullopt;
860
861     return path;
862 }
863
864 void ArgumentCoder<RecentSearch>::encode(Encoder& encoder, const RecentSearch& recentSearch)
865 {
866     encoder << recentSearch.string << recentSearch.time;
867 }
868
869 std::optional<RecentSearch> ArgumentCoder<RecentSearch>::decode(Decoder& decoder)
870 {
871     std::optional<String> string;
872     decoder >> string;
873     if (!string)
874         return std::nullopt;
875     
876     std::optional<WallTime> time;
877     decoder >> time;
878     if (!time)
879         return std::nullopt;
880     
881     return {{ WTFMove(*string), WTFMove(*time) }};
882 }
883
884 template<> struct ArgumentCoder<Region::Span> {
885     static void encode(Encoder&, const Region::Span&);
886     static std::optional<Region::Span> decode(Decoder&);
887 };
888
889 void ArgumentCoder<Region::Span>::encode(Encoder& encoder, const Region::Span& span)
890 {
891     encoder << span.y;
892     encoder << (uint64_t)span.segmentIndex;
893 }
894
895 std::optional<Region::Span> ArgumentCoder<Region::Span>::decode(Decoder& decoder)
896 {
897     Region::Span span;
898     if (!decoder.decode(span.y))
899         return std::nullopt;
900     
901     uint64_t segmentIndex;
902     if (!decoder.decode(segmentIndex))
903         return std::nullopt;
904     
905     span.segmentIndex = segmentIndex;
906     return WTFMove(span);
907 }
908
909 void ArgumentCoder<Region>::encode(Encoder& encoder, const Region& region)
910 {
911     encoder.encode(region.shapeSegments());
912     encoder.encode(region.shapeSpans());
913 }
914
915 bool ArgumentCoder<Region>::decode(Decoder& decoder, Region& region)
916 {
917     Vector<int> segments;
918     if (!decoder.decode(segments))
919         return false;
920
921     Vector<Region::Span> spans;
922     if (!decoder.decode(spans))
923         return false;
924     
925     region.setShapeSegments(segments);
926     region.setShapeSpans(spans);
927     region.updateBoundsFromShape();
928     
929     if (!region.isValid())
930         return false;
931
932     return true;
933 }
934
935 void ArgumentCoder<Length>::encode(Encoder& encoder, const Length& length)
936 {
937     SimpleArgumentCoder<Length>::encode(encoder, length);
938 }
939
940 bool ArgumentCoder<Length>::decode(Decoder& decoder, Length& length)
941 {
942     return SimpleArgumentCoder<Length>::decode(decoder, length);
943 }
944
945
946 void ArgumentCoder<ViewportAttributes>::encode(Encoder& encoder, const ViewportAttributes& viewportAttributes)
947 {
948     SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
949 }
950
951 bool ArgumentCoder<ViewportAttributes>::decode(Decoder& decoder, ViewportAttributes& viewportAttributes)
952 {
953     return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
954 }
955
956
957 void ArgumentCoder<MimeClassInfo>::encode(Encoder& encoder, const MimeClassInfo& mimeClassInfo)
958 {
959     encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions;
960 }
961
962 std::optional<MimeClassInfo> ArgumentCoder<MimeClassInfo>::decode(Decoder& decoder)
963 {
964     MimeClassInfo mimeClassInfo;
965     if (!decoder.decode(mimeClassInfo.type))
966         return std::nullopt;
967     if (!decoder.decode(mimeClassInfo.desc))
968         return std::nullopt;
969     if (!decoder.decode(mimeClassInfo.extensions))
970         return std::nullopt;
971
972     return WTFMove(mimeClassInfo);
973 }
974
975
976 void ArgumentCoder<PluginInfo>::encode(Encoder& encoder, const PluginInfo& pluginInfo)
977 {
978     encoder << pluginInfo.name;
979     encoder << pluginInfo.file;
980     encoder << pluginInfo.desc;
981     encoder << pluginInfo.mimes;
982     encoder << pluginInfo.isApplicationPlugin;
983     encoder.encodeEnum(pluginInfo.clientLoadPolicy);
984     encoder << pluginInfo.bundleIdentifier;
985 #if PLATFORM(MAC)
986     encoder << pluginInfo.versionString;
987 #endif
988 }
989
990 std::optional<WebCore::PluginInfo> ArgumentCoder<PluginInfo>::decode(Decoder& decoder)
991 {
992     PluginInfo pluginInfo;
993     if (!decoder.decode(pluginInfo.name))
994         return std::nullopt;
995     if (!decoder.decode(pluginInfo.file))
996         return std::nullopt;
997     if (!decoder.decode(pluginInfo.desc))
998         return std::nullopt;
999     if (!decoder.decode(pluginInfo.mimes))
1000         return std::nullopt;
1001     if (!decoder.decode(pluginInfo.isApplicationPlugin))
1002         return std::nullopt;
1003     if (!decoder.decodeEnum(pluginInfo.clientLoadPolicy))
1004         return std::nullopt;
1005     if (!decoder.decode(pluginInfo.bundleIdentifier))
1006         return std::nullopt;
1007 #if PLATFORM(MAC)
1008     if (!decoder.decode(pluginInfo.versionString))
1009         return std::nullopt;
1010 #endif
1011
1012     return WTFMove(pluginInfo);
1013 }
1014
1015 void ArgumentCoder<AuthenticationChallenge>::encode(Encoder& encoder, const AuthenticationChallenge& challenge)
1016 {
1017     encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error();
1018 }
1019
1020 bool ArgumentCoder<AuthenticationChallenge>::decode(Decoder& decoder, AuthenticationChallenge& challenge)
1021 {    
1022     ProtectionSpace protectionSpace;
1023     if (!decoder.decode(protectionSpace))
1024         return false;
1025
1026     Credential proposedCredential;
1027     if (!decoder.decode(proposedCredential))
1028         return false;
1029
1030     unsigned previousFailureCount;    
1031     if (!decoder.decode(previousFailureCount))
1032         return false;
1033
1034     ResourceResponse failureResponse;
1035     if (!decoder.decode(failureResponse))
1036         return false;
1037
1038     ResourceError error;
1039     if (!decoder.decode(error))
1040         return false;
1041     
1042     challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
1043     return true;
1044 }
1045
1046
1047 void ArgumentCoder<ProtectionSpace>::encode(Encoder& encoder, const ProtectionSpace& space)
1048 {
1049     if (space.encodingRequiresPlatformData()) {
1050         encoder << true;
1051         encodePlatformData(encoder, space);
1052         return;
1053     }
1054
1055     encoder << false;
1056     encoder << space.host() << space.port() << space.realm();
1057     encoder.encodeEnum(space.authenticationScheme());
1058     encoder.encodeEnum(space.serverType());
1059 }
1060
1061 bool ArgumentCoder<ProtectionSpace>::decode(Decoder& decoder, ProtectionSpace& space)
1062 {
1063     bool hasPlatformData;
1064     if (!decoder.decode(hasPlatformData))
1065         return false;
1066
1067     if (hasPlatformData)
1068         return decodePlatformData(decoder, space);
1069
1070     String host;
1071     if (!decoder.decode(host))
1072         return false;
1073
1074     int port;
1075     if (!decoder.decode(port))
1076         return false;
1077
1078     String realm;
1079     if (!decoder.decode(realm))
1080         return false;
1081     
1082     ProtectionSpaceAuthenticationScheme authenticationScheme;
1083     if (!decoder.decodeEnum(authenticationScheme))
1084         return false;
1085
1086     ProtectionSpaceServerType serverType;
1087     if (!decoder.decodeEnum(serverType))
1088         return false;
1089
1090     space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
1091     return true;
1092 }
1093
1094 void ArgumentCoder<Credential>::encode(Encoder& encoder, const Credential& credential)
1095 {
1096     if (credential.encodingRequiresPlatformData()) {
1097         encoder << true;
1098         encodePlatformData(encoder, credential);
1099         return;
1100     }
1101
1102     encoder << false;
1103     encoder << credential.user() << credential.password();
1104     encoder.encodeEnum(credential.persistence());
1105 }
1106
1107 bool ArgumentCoder<Credential>::decode(Decoder& decoder, Credential& credential)
1108 {
1109     bool hasPlatformData;
1110     if (!decoder.decode(hasPlatformData))
1111         return false;
1112
1113     if (hasPlatformData)
1114         return decodePlatformData(decoder, credential);
1115
1116     String user;
1117     if (!decoder.decode(user))
1118         return false;
1119
1120     String password;
1121     if (!decoder.decode(password))
1122         return false;
1123
1124     CredentialPersistence persistence;
1125     if (!decoder.decodeEnum(persistence))
1126         return false;
1127     
1128     credential = Credential(user, password, persistence);
1129     return true;
1130 }
1131
1132 static void encodeImage(Encoder& encoder, Image& image)
1133 {
1134     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(image.size()), { });
1135     bitmap->createGraphicsContext()->drawImage(image, IntPoint());
1136
1137     ShareableBitmap::Handle handle;
1138     bitmap->createHandle(handle);
1139
1140     encoder << handle;
1141 }
1142
1143 static bool decodeImage(Decoder& decoder, RefPtr<Image>& image)
1144 {
1145     ShareableBitmap::Handle handle;
1146     if (!decoder.decode(handle))
1147         return false;
1148     
1149     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
1150     if (!bitmap)
1151         return false;
1152     image = bitmap->createImage();
1153     if (!image)
1154         return false;
1155     return true;
1156 }
1157
1158 static void encodeOptionalImage(Encoder& encoder, Image* image)
1159 {
1160     bool hasImage = !!image;
1161     encoder << hasImage;
1162
1163     if (hasImage)
1164         encodeImage(encoder, *image);
1165 }
1166
1167 static bool decodeOptionalImage(Decoder& decoder, RefPtr<Image>& image)
1168 {
1169     image = nullptr;
1170
1171     bool hasImage;
1172     if (!decoder.decode(hasImage))
1173         return false;
1174
1175     if (!hasImage)
1176         return true;
1177
1178     return decodeImage(decoder, image);
1179 }
1180
1181 #if !PLATFORM(IOS)
1182 void ArgumentCoder<Cursor>::encode(Encoder& encoder, const Cursor& cursor)
1183 {
1184     encoder.encodeEnum(cursor.type());
1185         
1186     if (cursor.type() != Cursor::Custom)
1187         return;
1188
1189     if (cursor.image()->isNull()) {
1190         encoder << false; // There is no valid image being encoded.
1191         return;
1192     }
1193
1194     encoder << true;
1195     encodeImage(encoder, *cursor.image());
1196     encoder << cursor.hotSpot();
1197 #if ENABLE(MOUSE_CURSOR_SCALE)
1198     encoder << cursor.imageScaleFactor();
1199 #endif
1200 }
1201
1202 bool ArgumentCoder<Cursor>::decode(Decoder& decoder, Cursor& cursor)
1203 {
1204     Cursor::Type type;
1205     if (!decoder.decodeEnum(type))
1206         return false;
1207
1208     if (type > Cursor::Custom)
1209         return false;
1210
1211     if (type != Cursor::Custom) {
1212         const Cursor& cursorReference = Cursor::fromType(type);
1213         // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
1214         // This will avoid having to re-create the platform cursors over and over.
1215         (void)cursorReference.platformCursor();
1216
1217         cursor = cursorReference;
1218         return true;
1219     }
1220
1221     bool isValidImagePresent;
1222     if (!decoder.decode(isValidImagePresent))
1223         return false;
1224
1225     if (!isValidImagePresent) {
1226         cursor = Cursor(&Image::nullImage(), IntPoint());
1227         return true;
1228     }
1229
1230     RefPtr<Image> image;
1231     if (!decodeImage(decoder, image))
1232         return false;
1233
1234     IntPoint hotSpot;
1235     if (!decoder.decode(hotSpot))
1236         return false;
1237
1238     if (!image->rect().contains(hotSpot))
1239         return false;
1240
1241 #if ENABLE(MOUSE_CURSOR_SCALE)
1242     float scale;
1243     if (!decoder.decode(scale))
1244         return false;
1245
1246     cursor = Cursor(image.get(), hotSpot, scale);
1247 #else
1248     cursor = Cursor(image.get(), hotSpot);
1249 #endif
1250     return true;
1251 }
1252 #endif
1253
1254 void ArgumentCoder<ResourceRequest>::encode(Encoder& encoder, const ResourceRequest& resourceRequest)
1255 {
1256     encoder << resourceRequest.cachePartition();
1257     encoder << resourceRequest.hiddenFromInspector();
1258
1259 #if USE(SYSTEM_PREVIEW)
1260     if (resourceRequest.isSystemPreview()) {
1261         encoder << true;
1262         encoder << resourceRequest.systemPreviewRect();
1263     } else
1264         encoder << false;
1265 #endif
1266
1267     if (resourceRequest.encodingRequiresPlatformData()) {
1268         encoder << true;
1269         encodePlatformData(encoder, resourceRequest);
1270         return;
1271     }
1272     encoder << false;
1273     resourceRequest.encodeWithoutPlatformData(encoder);
1274 }
1275
1276 bool ArgumentCoder<ResourceRequest>::decode(Decoder& decoder, ResourceRequest& resourceRequest)
1277 {
1278     String cachePartition;
1279     if (!decoder.decode(cachePartition))
1280         return false;
1281     resourceRequest.setCachePartition(cachePartition);
1282
1283     bool isHiddenFromInspector;
1284     if (!decoder.decode(isHiddenFromInspector))
1285         return false;
1286     resourceRequest.setHiddenFromInspector(isHiddenFromInspector);
1287
1288 #if USE(SYSTEM_PREVIEW)
1289     bool isSystemPreview;
1290     if (!decoder.decode(isSystemPreview))
1291         return false;
1292     resourceRequest.setSystemPreview(isSystemPreview);
1293
1294     if (isSystemPreview) {
1295         IntRect systemPreviewRect;
1296         if (!decoder.decode(systemPreviewRect))
1297             return false;
1298         resourceRequest.setSystemPreviewRect(systemPreviewRect);
1299     }
1300 #endif
1301
1302     bool hasPlatformData;
1303     if (!decoder.decode(hasPlatformData))
1304         return false;
1305     if (hasPlatformData)
1306         return decodePlatformData(decoder, resourceRequest);
1307
1308     return resourceRequest.decodeWithoutPlatformData(decoder);
1309 }
1310
1311 void ArgumentCoder<ResourceError>::encode(Encoder& encoder, const ResourceError& resourceError)
1312 {
1313     encoder.encodeEnum(resourceError.type());
1314     if (resourceError.type() == ResourceError::Type::Null)
1315         return;
1316     encodePlatformData(encoder, resourceError);
1317 }
1318
1319 bool ArgumentCoder<ResourceError>::decode(Decoder& decoder, ResourceError& resourceError)
1320 {
1321     ResourceError::Type type;
1322     if (!decoder.decodeEnum(type))
1323         return false;
1324
1325     if (type == ResourceError::Type::Null) {
1326         resourceError = { };
1327         return true;
1328     }
1329
1330     if (!decodePlatformData(decoder, resourceError))
1331         return false;
1332
1333     resourceError.setType(type);
1334     return true;
1335 }
1336
1337 #if PLATFORM(IOS)
1338
1339 void ArgumentCoder<SelectionRect>::encode(Encoder& encoder, const SelectionRect& selectionRect)
1340 {
1341     encoder << selectionRect.rect();
1342     encoder << static_cast<uint32_t>(selectionRect.direction());
1343     encoder << selectionRect.minX();
1344     encoder << selectionRect.maxX();
1345     encoder << selectionRect.maxY();
1346     encoder << selectionRect.lineNumber();
1347     encoder << selectionRect.isLineBreak();
1348     encoder << selectionRect.isFirstOnLine();
1349     encoder << selectionRect.isLastOnLine();
1350     encoder << selectionRect.containsStart();
1351     encoder << selectionRect.containsEnd();
1352     encoder << selectionRect.isHorizontal();
1353 }
1354
1355 std::optional<SelectionRect> ArgumentCoder<SelectionRect>::decode(Decoder& decoder)
1356 {
1357     SelectionRect selectionRect;
1358     IntRect rect;
1359     if (!decoder.decode(rect))
1360         return std::nullopt;
1361     selectionRect.setRect(rect);
1362
1363     uint32_t direction;
1364     if (!decoder.decode(direction))
1365         return std::nullopt;
1366     selectionRect.setDirection((TextDirection)direction);
1367
1368     int intValue;
1369     if (!decoder.decode(intValue))
1370         return std::nullopt;
1371     selectionRect.setMinX(intValue);
1372
1373     if (!decoder.decode(intValue))
1374         return std::nullopt;
1375     selectionRect.setMaxX(intValue);
1376
1377     if (!decoder.decode(intValue))
1378         return std::nullopt;
1379     selectionRect.setMaxY(intValue);
1380
1381     if (!decoder.decode(intValue))
1382         return std::nullopt;
1383     selectionRect.setLineNumber(intValue);
1384
1385     bool boolValue;
1386     if (!decoder.decode(boolValue))
1387         return std::nullopt;
1388     selectionRect.setIsLineBreak(boolValue);
1389
1390     if (!decoder.decode(boolValue))
1391         return std::nullopt;
1392     selectionRect.setIsFirstOnLine(boolValue);
1393
1394     if (!decoder.decode(boolValue))
1395         return std::nullopt;
1396     selectionRect.setIsLastOnLine(boolValue);
1397
1398     if (!decoder.decode(boolValue))
1399         return std::nullopt;
1400     selectionRect.setContainsStart(boolValue);
1401
1402     if (!decoder.decode(boolValue))
1403         return std::nullopt;
1404     selectionRect.setContainsEnd(boolValue);
1405
1406     if (!decoder.decode(boolValue))
1407         return std::nullopt;
1408     selectionRect.setIsHorizontal(boolValue);
1409
1410     return WTFMove(selectionRect);
1411 }
1412
1413 #endif
1414
1415 void ArgumentCoder<WindowFeatures>::encode(Encoder& encoder, const WindowFeatures& windowFeatures)
1416 {
1417     encoder << windowFeatures.x;
1418     encoder << windowFeatures.y;
1419     encoder << windowFeatures.width;
1420     encoder << windowFeatures.height;
1421     encoder << windowFeatures.menuBarVisible;
1422     encoder << windowFeatures.statusBarVisible;
1423     encoder << windowFeatures.toolBarVisible;
1424     encoder << windowFeatures.locationBarVisible;
1425     encoder << windowFeatures.scrollbarsVisible;
1426     encoder << windowFeatures.resizable;
1427     encoder << windowFeatures.fullscreen;
1428     encoder << windowFeatures.dialog;
1429 }
1430
1431 bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& windowFeatures)
1432 {
1433     if (!decoder.decode(windowFeatures.x))
1434         return false;
1435     if (!decoder.decode(windowFeatures.y))
1436         return false;
1437     if (!decoder.decode(windowFeatures.width))
1438         return false;
1439     if (!decoder.decode(windowFeatures.height))
1440         return false;
1441     if (!decoder.decode(windowFeatures.menuBarVisible))
1442         return false;
1443     if (!decoder.decode(windowFeatures.statusBarVisible))
1444         return false;
1445     if (!decoder.decode(windowFeatures.toolBarVisible))
1446         return false;
1447     if (!decoder.decode(windowFeatures.locationBarVisible))
1448         return false;
1449     if (!decoder.decode(windowFeatures.scrollbarsVisible))
1450         return false;
1451     if (!decoder.decode(windowFeatures.resizable))
1452         return false;
1453     if (!decoder.decode(windowFeatures.fullscreen))
1454         return false;
1455     if (!decoder.decode(windowFeatures.dialog))
1456         return false;
1457     return true;
1458 }
1459
1460
1461 void ArgumentCoder<Color>::encode(Encoder& encoder, const Color& color)
1462 {
1463     if (color.isExtended()) {
1464         encoder << true;
1465         encoder << color.asExtended().red();
1466         encoder << color.asExtended().green();
1467         encoder << color.asExtended().blue();
1468         encoder << color.asExtended().alpha();
1469         encoder << color.asExtended().colorSpace();
1470         return;
1471     }
1472
1473     encoder << false;
1474
1475     if (!color.isValid()) {
1476         encoder << false;
1477         return;
1478     }
1479
1480     encoder << true;
1481     encoder << color.rgb();
1482 }
1483
1484 bool ArgumentCoder<Color>::decode(Decoder& decoder, Color& color)
1485 {
1486     bool isExtended;
1487     if (!decoder.decode(isExtended))
1488         return false;
1489
1490     if (isExtended) {
1491         float red;
1492         float green;
1493         float blue;
1494         float alpha;
1495         ColorSpace colorSpace;
1496         if (!decoder.decode(red))
1497             return false;
1498         if (!decoder.decode(green))
1499             return false;
1500         if (!decoder.decode(blue))
1501             return false;
1502         if (!decoder.decode(alpha))
1503             return false;
1504         if (!decoder.decode(colorSpace))
1505             return false;
1506         color = Color(red, green, blue, alpha, colorSpace);
1507         return true;
1508     }
1509
1510     bool isValid;
1511     if (!decoder.decode(isValid))
1512         return false;
1513
1514     if (!isValid) {
1515         color = Color();
1516         return true;
1517     }
1518
1519     RGBA32 rgba;
1520     if (!decoder.decode(rgba))
1521         return false;
1522
1523     color = Color(rgba);
1524     return true;
1525 }
1526
1527 std::optional<Color> ArgumentCoder<Color>::decode(Decoder& decoder)
1528 {
1529     Color color;
1530     if (!decode(decoder, color))
1531         return std::nullopt;
1532
1533     return color;
1534 }
1535
1536 #if ENABLE(DRAG_SUPPORT)
1537 void ArgumentCoder<DragData>::encode(Encoder& encoder, const DragData& dragData)
1538 {
1539     encoder << dragData.clientPosition();
1540     encoder << dragData.globalPosition();
1541     encoder.encodeEnum(dragData.draggingSourceOperationMask());
1542     encoder.encodeEnum(dragData.flags());
1543 #if PLATFORM(COCOA)
1544     encoder << dragData.pasteboardName();
1545     encoder << dragData.fileNames();
1546 #endif
1547     encoder.encodeEnum(dragData.dragDestinationAction());
1548 }
1549
1550 bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
1551 {
1552     IntPoint clientPosition;
1553     if (!decoder.decode(clientPosition))
1554         return false;
1555
1556     IntPoint globalPosition;
1557     if (!decoder.decode(globalPosition))
1558         return false;
1559
1560     DragOperation draggingSourceOperationMask;
1561     if (!decoder.decodeEnum(draggingSourceOperationMask))
1562         return false;
1563
1564     DragApplicationFlags applicationFlags;
1565     if (!decoder.decodeEnum(applicationFlags))
1566         return false;
1567
1568     String pasteboardName;
1569     Vector<String> fileNames;
1570 #if PLATFORM(COCOA)
1571     if (!decoder.decode(pasteboardName))
1572         return false;
1573
1574     if (!decoder.decode(fileNames))
1575         return false;
1576 #endif
1577
1578     DragDestinationAction destinationAction;
1579     if (!decoder.decodeEnum(destinationAction))
1580         return false;
1581
1582     dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, destinationAction);
1583     dragData.setFileNames(fileNames);
1584
1585     return true;
1586 }
1587 #endif
1588
1589 void ArgumentCoder<CompositionUnderline>::encode(Encoder& encoder, const CompositionUnderline& underline)
1590 {
1591     encoder << underline.startOffset;
1592     encoder << underline.endOffset;
1593     encoder << underline.thick;
1594     encoder << underline.color;
1595 }
1596
1597 std::optional<CompositionUnderline> ArgumentCoder<CompositionUnderline>::decode(Decoder& decoder)
1598 {
1599     CompositionUnderline underline;
1600
1601     if (!decoder.decode(underline.startOffset))
1602         return std::nullopt;
1603     if (!decoder.decode(underline.endOffset))
1604         return std::nullopt;
1605     if (!decoder.decode(underline.thick))
1606         return std::nullopt;
1607     if (!decoder.decode(underline.color))
1608         return std::nullopt;
1609
1610     return WTFMove(underline);
1611 }
1612
1613 void ArgumentCoder<DatabaseDetails>::encode(Encoder& encoder, const DatabaseDetails& details)
1614 {
1615     encoder << details.name();
1616     encoder << details.displayName();
1617     encoder << details.expectedUsage();
1618     encoder << details.currentUsage();
1619     encoder << details.creationTime();
1620     encoder << details.modificationTime();
1621 }
1622     
1623 bool ArgumentCoder<DatabaseDetails>::decode(Decoder& decoder, DatabaseDetails& details)
1624 {
1625     String name;
1626     if (!decoder.decode(name))
1627         return false;
1628
1629     String displayName;
1630     if (!decoder.decode(displayName))
1631         return false;
1632
1633     uint64_t expectedUsage;
1634     if (!decoder.decode(expectedUsage))
1635         return false;
1636
1637     uint64_t currentUsage;
1638     if (!decoder.decode(currentUsage))
1639         return false;
1640
1641     double creationTime;
1642     if (!decoder.decode(creationTime))
1643         return false;
1644
1645     double modificationTime;
1646     if (!decoder.decode(modificationTime))
1647         return false;
1648
1649     details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime);
1650     return true;
1651 }
1652
1653 #if ENABLE(DATALIST_ELEMENT)
1654 void ArgumentCoder<DataListSuggestionInformation>::encode(Encoder& encoder, const WebCore::DataListSuggestionInformation& info)
1655 {
1656     encoder.encodeEnum(info.activationType);
1657     encoder << info.suggestions;
1658     encoder << info.elementRect;
1659 }
1660
1661 bool ArgumentCoder<DataListSuggestionInformation>::decode(Decoder& decoder, WebCore::DataListSuggestionInformation& info)
1662 {
1663     if (!decoder.decodeEnum(info.activationType))
1664         return false;
1665
1666     if (!decoder.decode(info.suggestions))
1667         return false;
1668
1669     if (!decoder.decode(info.elementRect))
1670         return false;
1671
1672     return true;
1673 }
1674 #endif
1675
1676 void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
1677 {
1678     encoder << data.origin;
1679     encoder << data.orderedTypes;
1680     encoder << data.platformData;
1681     encoder << data.sameOriginCustomData;
1682 }
1683
1684 bool ArgumentCoder<PasteboardCustomData>::decode(Decoder& decoder, PasteboardCustomData& data)
1685 {
1686     if (!decoder.decode(data.origin))
1687         return false;
1688
1689     if (!decoder.decode(data.orderedTypes))
1690         return false;
1691
1692     if (!decoder.decode(data.platformData))
1693         return false;
1694
1695     if (!decoder.decode(data.sameOriginCustomData))
1696         return false;
1697
1698     return true;
1699 }
1700
1701 void ArgumentCoder<PasteboardURL>::encode(Encoder& encoder, const PasteboardURL& content)
1702 {
1703     encoder << content.url;
1704     encoder << content.title;
1705 #if PLATFORM(MAC)
1706     encoder << content.userVisibleForm;
1707 #endif
1708 #if PLATFORM(GTK)
1709     encoder << content.markup;
1710 #endif
1711 }
1712
1713 bool ArgumentCoder<PasteboardURL>::decode(Decoder& decoder, PasteboardURL& content)
1714 {
1715     if (!decoder.decode(content.url))
1716         return false;
1717
1718     if (!decoder.decode(content.title))
1719         return false;
1720
1721 #if PLATFORM(MAC)
1722     if (!decoder.decode(content.userVisibleForm))
1723         return false;
1724 #endif
1725 #if PLATFORM(GTK)
1726     if (!decoder.decode(content.markup))
1727         return false;
1728 #endif
1729
1730     return true;
1731 }
1732
1733 #if PLATFORM(IOS)
1734
1735 void ArgumentCoder<Highlight>::encode(Encoder& encoder, const Highlight& highlight)
1736 {
1737     encoder << static_cast<uint32_t>(highlight.type);
1738     encoder << highlight.usePageCoordinates;
1739     encoder << highlight.contentColor;
1740     encoder << highlight.contentOutlineColor;
1741     encoder << highlight.paddingColor;
1742     encoder << highlight.borderColor;
1743     encoder << highlight.marginColor;
1744     encoder << highlight.quads;
1745 }
1746
1747 bool ArgumentCoder<Highlight>::decode(Decoder& decoder, Highlight& highlight)
1748 {
1749     uint32_t type;
1750     if (!decoder.decode(type))
1751         return false;
1752     highlight.type = (HighlightType)type;
1753
1754     if (!decoder.decode(highlight.usePageCoordinates))
1755         return false;
1756     if (!decoder.decode(highlight.contentColor))
1757         return false;
1758     if (!decoder.decode(highlight.contentOutlineColor))
1759         return false;
1760     if (!decoder.decode(highlight.paddingColor))
1761         return false;
1762     if (!decoder.decode(highlight.borderColor))
1763         return false;
1764     if (!decoder.decode(highlight.marginColor))
1765         return false;
1766     if (!decoder.decode(highlight.quads))
1767         return false;
1768     return true;
1769 }
1770
1771 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1772 {
1773     encoder << content.contentOrigin;
1774     encoder << content.canSmartCopyOrDelete;
1775     encoder << content.dataInStringFormat;
1776     encoder << content.dataInHTMLFormat;
1777
1778     encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get());
1779     encodeSharedBuffer(encoder, content.dataInRTFDFormat.get());
1780     encodeSharedBuffer(encoder, content.dataInRTFFormat.get());
1781     encodeSharedBuffer(encoder, content.dataInAttributedStringFormat.get());
1782
1783     encodeTypesAndData(encoder, content.clientTypes, content.clientData);
1784 }
1785
1786 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1787 {
1788     if (!decoder.decode(content.contentOrigin))
1789         return false;
1790     if (!decoder.decode(content.canSmartCopyOrDelete))
1791         return false;
1792     if (!decoder.decode(content.dataInStringFormat))
1793         return false;
1794     if (!decoder.decode(content.dataInHTMLFormat))
1795         return false;
1796     if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat))
1797         return false;
1798     if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat))
1799         return false;
1800     if (!decodeSharedBuffer(decoder, content.dataInRTFFormat))
1801         return false;
1802     if (!decodeSharedBuffer(decoder, content.dataInAttributedStringFormat))
1803         return false;
1804     if (!decodeTypesAndData(decoder, content.clientTypes, content.clientData))
1805         return false;
1806     return true;
1807 }
1808
1809 void ArgumentCoder<PasteboardImage>::encode(Encoder& encoder, const PasteboardImage& pasteboardImage)
1810 {
1811     encodeOptionalImage(encoder, pasteboardImage.image.get());
1812     encoder << pasteboardImage.url.url;
1813     encoder << pasteboardImage.url.title;
1814     encoder << pasteboardImage.resourceMIMEType;
1815     encoder << pasteboardImage.suggestedName;
1816     encoder << pasteboardImage.imageSize;
1817     if (pasteboardImage.resourceData)
1818         encodeSharedBuffer(encoder, pasteboardImage.resourceData.get());
1819     encodeTypesAndData(encoder, pasteboardImage.clientTypes, pasteboardImage.clientData);
1820 }
1821
1822 bool ArgumentCoder<PasteboardImage>::decode(Decoder& decoder, PasteboardImage& pasteboardImage)
1823 {
1824     if (!decodeOptionalImage(decoder, pasteboardImage.image))
1825         return false;
1826     if (!decoder.decode(pasteboardImage.url.url))
1827         return false;
1828     if (!decoder.decode(pasteboardImage.url.title))
1829         return false;
1830     if (!decoder.decode(pasteboardImage.resourceMIMEType))
1831         return false;
1832     if (!decoder.decode(pasteboardImage.suggestedName))
1833         return false;
1834     if (!decoder.decode(pasteboardImage.imageSize))
1835         return false;
1836     if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData))
1837         return false;
1838     if (!decodeTypesAndData(decoder, pasteboardImage.clientTypes, pasteboardImage.clientData))
1839         return false;
1840     return true;
1841 }
1842
1843 #endif
1844
1845 #if PLATFORM(WPE)
1846 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1847 {
1848     encoder << content.text;
1849     encoder << content.markup;
1850 }
1851
1852 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1853 {
1854     if (!decoder.decode(content.text))
1855         return false;
1856     if (!decoder.decode(content.markup))
1857         return false;
1858     return true;
1859 }
1860 #endif // PLATFORM(WPE)
1861
1862 void ArgumentCoder<DictationAlternative>::encode(Encoder& encoder, const DictationAlternative& dictationAlternative)
1863 {
1864     encoder << dictationAlternative.rangeStart;
1865     encoder << dictationAlternative.rangeLength;
1866     encoder << dictationAlternative.dictationContext;
1867 }
1868
1869 std::optional<DictationAlternative> ArgumentCoder<DictationAlternative>::decode(Decoder& decoder)
1870 {
1871     std::optional<unsigned> rangeStart;
1872     decoder >> rangeStart;
1873     if (!rangeStart)
1874         return std::nullopt;
1875     
1876     std::optional<unsigned> rangeLength;
1877     decoder >> rangeLength;
1878     if (!rangeLength)
1879         return std::nullopt;
1880     
1881     std::optional<uint64_t> dictationContext;
1882     decoder >> dictationContext;
1883     if (!dictationContext)
1884         return std::nullopt;
1885     
1886     return {{ WTFMove(*rangeStart), WTFMove(*rangeLength), WTFMove(*dictationContext) }};
1887 }
1888
1889 void ArgumentCoder<FileChooserSettings>::encode(Encoder& encoder, const FileChooserSettings& settings)
1890 {
1891     encoder << settings.allowsDirectories;
1892     encoder << settings.allowsMultipleFiles;
1893     encoder << settings.acceptMIMETypes;
1894     encoder << settings.acceptFileExtensions;
1895     encoder << settings.selectedFiles;
1896 #if ENABLE(MEDIA_CAPTURE)
1897     encoder.encodeEnum(settings.mediaCaptureType);
1898 #endif
1899 }
1900
1901 bool ArgumentCoder<FileChooserSettings>::decode(Decoder& decoder, FileChooserSettings& settings)
1902 {
1903     if (!decoder.decode(settings.allowsDirectories))
1904         return false;
1905     if (!decoder.decode(settings.allowsMultipleFiles))
1906         return false;
1907     if (!decoder.decode(settings.acceptMIMETypes))
1908         return false;
1909     if (!decoder.decode(settings.acceptFileExtensions))
1910         return false;
1911     if (!decoder.decode(settings.selectedFiles))
1912         return false;
1913 #if ENABLE(MEDIA_CAPTURE)
1914     if (!decoder.decodeEnum(settings.mediaCaptureType))
1915         return false;
1916 #endif
1917
1918     return true;
1919 }
1920
1921
1922 void ArgumentCoder<GrammarDetail>::encode(Encoder& encoder, const GrammarDetail& detail)
1923 {
1924     encoder << detail.location;
1925     encoder << detail.length;
1926     encoder << detail.guesses;
1927     encoder << detail.userDescription;
1928 }
1929
1930 std::optional<GrammarDetail> ArgumentCoder<GrammarDetail>::decode(Decoder& decoder)
1931 {
1932     std::optional<int> location;
1933     decoder >> location;
1934     if (!location)
1935         return std::nullopt;
1936
1937     std::optional<int> length;
1938     decoder >> length;
1939     if (!length)
1940         return std::nullopt;
1941
1942     std::optional<Vector<String>> guesses;
1943     decoder >> guesses;
1944     if (!guesses)
1945         return std::nullopt;
1946
1947     std::optional<String> userDescription;
1948     decoder >> userDescription;
1949     if (!userDescription)
1950         return std::nullopt;
1951
1952     return {{ WTFMove(*location), WTFMove(*length), WTFMove(*guesses), WTFMove(*userDescription) }};
1953 }
1954
1955 void ArgumentCoder<TextCheckingRequestData>::encode(Encoder& encoder, const TextCheckingRequestData& request)
1956 {
1957     encoder << request.sequence();
1958     encoder << request.text();
1959     encoder << request.mask();
1960     encoder.encodeEnum(request.processType());
1961 }
1962
1963 bool ArgumentCoder<TextCheckingRequestData>::decode(Decoder& decoder, TextCheckingRequestData& request)
1964 {
1965     int sequence;
1966     if (!decoder.decode(sequence))
1967         return false;
1968
1969     String text;
1970     if (!decoder.decode(text))
1971         return false;
1972
1973     TextCheckingTypeMask mask;
1974     if (!decoder.decode(mask))
1975         return false;
1976
1977     TextCheckingProcessType processType;
1978     if (!decoder.decodeEnum(processType))
1979         return false;
1980
1981     request = TextCheckingRequestData(sequence, text, mask, processType);
1982     return true;
1983 }
1984
1985 void ArgumentCoder<TextCheckingResult>::encode(Encoder& encoder, const TextCheckingResult& result)
1986 {
1987     encoder.encodeEnum(result.type);
1988     encoder << result.location;
1989     encoder << result.length;
1990     encoder << result.details;
1991     encoder << result.replacement;
1992 }
1993
1994 std::optional<TextCheckingResult> ArgumentCoder<TextCheckingResult>::decode(Decoder& decoder)
1995 {
1996     TextCheckingType type;
1997     if (!decoder.decodeEnum(type))
1998         return std::nullopt;
1999     
2000     std::optional<int> location;
2001     decoder >> location;
2002     if (!location)
2003         return std::nullopt;
2004
2005     std::optional<int> length;
2006     decoder >> length;
2007     if (!length)
2008         return std::nullopt;
2009
2010     std::optional<Vector<GrammarDetail>> details;
2011     decoder >> details;
2012     if (!details)
2013         return std::nullopt;
2014
2015     std::optional<String> replacement;
2016     decoder >> replacement;
2017     if (!replacement)
2018         return std::nullopt;
2019
2020     return {{ WTFMove(type), WTFMove(*location), WTFMove(*length), WTFMove(*details), WTFMove(*replacement) }};
2021 }
2022
2023 void ArgumentCoder<UserStyleSheet>::encode(Encoder& encoder, const UserStyleSheet& userStyleSheet)
2024 {
2025     encoder << userStyleSheet.source();
2026     encoder << userStyleSheet.url();
2027     encoder << userStyleSheet.whitelist();
2028     encoder << userStyleSheet.blacklist();
2029     encoder.encodeEnum(userStyleSheet.injectedFrames());
2030     encoder.encodeEnum(userStyleSheet.level());
2031 }
2032
2033 bool ArgumentCoder<UserStyleSheet>::decode(Decoder& decoder, UserStyleSheet& userStyleSheet)
2034 {
2035     String source;
2036     if (!decoder.decode(source))
2037         return false;
2038
2039     URL url;
2040     if (!decoder.decode(url))
2041         return false;
2042
2043     Vector<String> whitelist;
2044     if (!decoder.decode(whitelist))
2045         return false;
2046
2047     Vector<String> blacklist;
2048     if (!decoder.decode(blacklist))
2049         return false;
2050
2051     UserContentInjectedFrames injectedFrames;
2052     if (!decoder.decodeEnum(injectedFrames))
2053         return false;
2054
2055     UserStyleLevel level;
2056     if (!decoder.decodeEnum(level))
2057         return false;
2058
2059     userStyleSheet = UserStyleSheet(source, url, WTFMove(whitelist), WTFMove(blacklist), injectedFrames, level);
2060     return true;
2061 }
2062
2063 #if ENABLE(MEDIA_SESSION)
2064 void ArgumentCoder<MediaSessionMetadata>::encode(Encoder& encoder, const MediaSessionMetadata& result)
2065 {
2066     encoder << result.artist();
2067     encoder << result.album();
2068     encoder << result.title();
2069     encoder << result.artworkURL();
2070 }
2071
2072 bool ArgumentCoder<MediaSessionMetadata>::decode(Decoder& decoder, MediaSessionMetadata& result)
2073 {
2074     String artist, album, title;
2075     URL artworkURL;
2076     if (!decoder.decode(artist))
2077         return false;
2078     if (!decoder.decode(album))
2079         return false;
2080     if (!decoder.decode(title))
2081         return false;
2082     if (!decoder.decode(artworkURL))
2083         return false;
2084     result = MediaSessionMetadata(title, artist, album, artworkURL);
2085     return true;
2086 }
2087 #endif
2088
2089 void ArgumentCoder<ScrollableAreaParameters>::encode(Encoder& encoder, const ScrollableAreaParameters& parameters)
2090 {
2091     encoder.encodeEnum(parameters.horizontalScrollElasticity);
2092     encoder.encodeEnum(parameters.verticalScrollElasticity);
2093
2094     encoder.encodeEnum(parameters.horizontalScrollbarMode);
2095     encoder.encodeEnum(parameters.verticalScrollbarMode);
2096
2097     encoder << parameters.hasEnabledHorizontalScrollbar;
2098     encoder << parameters.hasEnabledVerticalScrollbar;
2099 }
2100
2101 bool ArgumentCoder<ScrollableAreaParameters>::decode(Decoder& decoder, ScrollableAreaParameters& params)
2102 {
2103     if (!decoder.decodeEnum(params.horizontalScrollElasticity))
2104         return false;
2105     if (!decoder.decodeEnum(params.verticalScrollElasticity))
2106         return false;
2107
2108     if (!decoder.decodeEnum(params.horizontalScrollbarMode))
2109         return false;
2110     if (!decoder.decodeEnum(params.verticalScrollbarMode))
2111         return false;
2112
2113     if (!decoder.decode(params.hasEnabledHorizontalScrollbar))
2114         return false;
2115     if (!decoder.decode(params.hasEnabledVerticalScrollbar))
2116         return false;
2117     
2118     return true;
2119 }
2120
2121 void ArgumentCoder<FixedPositionViewportConstraints>::encode(Encoder& encoder, const FixedPositionViewportConstraints& viewportConstraints)
2122 {
2123     encoder << viewportConstraints.alignmentOffset();
2124     encoder << viewportConstraints.anchorEdges();
2125
2126     encoder << viewportConstraints.viewportRectAtLastLayout();
2127     encoder << viewportConstraints.layerPositionAtLastLayout();
2128 }
2129
2130 bool ArgumentCoder<FixedPositionViewportConstraints>::decode(Decoder& decoder, FixedPositionViewportConstraints& viewportConstraints)
2131 {
2132     FloatSize alignmentOffset;
2133     if (!decoder.decode(alignmentOffset))
2134         return false;
2135     
2136     ViewportConstraints::AnchorEdges anchorEdges;
2137     if (!decoder.decode(anchorEdges))
2138         return false;
2139
2140     FloatRect viewportRectAtLastLayout;
2141     if (!decoder.decode(viewportRectAtLastLayout))
2142         return false;
2143
2144     FloatPoint layerPositionAtLastLayout;
2145     if (!decoder.decode(layerPositionAtLastLayout))
2146         return false;
2147
2148     viewportConstraints = FixedPositionViewportConstraints();
2149     viewportConstraints.setAlignmentOffset(alignmentOffset);
2150     viewportConstraints.setAnchorEdges(anchorEdges);
2151
2152     viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout);
2153     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2154     
2155     return true;
2156 }
2157
2158 void ArgumentCoder<StickyPositionViewportConstraints>::encode(Encoder& encoder, const StickyPositionViewportConstraints& viewportConstraints)
2159 {
2160     encoder << viewportConstraints.alignmentOffset();
2161     encoder << viewportConstraints.anchorEdges();
2162
2163     encoder << viewportConstraints.leftOffset();
2164     encoder << viewportConstraints.rightOffset();
2165     encoder << viewportConstraints.topOffset();
2166     encoder << viewportConstraints.bottomOffset();
2167
2168     encoder << viewportConstraints.constrainingRectAtLastLayout();
2169     encoder << viewportConstraints.containingBlockRect();
2170     encoder << viewportConstraints.stickyBoxRect();
2171
2172     encoder << viewportConstraints.stickyOffsetAtLastLayout();
2173     encoder << viewportConstraints.layerPositionAtLastLayout();
2174 }
2175
2176 bool ArgumentCoder<StickyPositionViewportConstraints>::decode(Decoder& decoder, StickyPositionViewportConstraints& viewportConstraints)
2177 {
2178     FloatSize alignmentOffset;
2179     if (!decoder.decode(alignmentOffset))
2180         return false;
2181     
2182     ViewportConstraints::AnchorEdges anchorEdges;
2183     if (!decoder.decode(anchorEdges))
2184         return false;
2185     
2186     float leftOffset;
2187     if (!decoder.decode(leftOffset))
2188         return false;
2189
2190     float rightOffset;
2191     if (!decoder.decode(rightOffset))
2192         return false;
2193
2194     float topOffset;
2195     if (!decoder.decode(topOffset))
2196         return false;
2197
2198     float bottomOffset;
2199     if (!decoder.decode(bottomOffset))
2200         return false;
2201     
2202     FloatRect constrainingRectAtLastLayout;
2203     if (!decoder.decode(constrainingRectAtLastLayout))
2204         return false;
2205
2206     FloatRect containingBlockRect;
2207     if (!decoder.decode(containingBlockRect))
2208         return false;
2209
2210     FloatRect stickyBoxRect;
2211     if (!decoder.decode(stickyBoxRect))
2212         return false;
2213
2214     FloatSize stickyOffsetAtLastLayout;
2215     if (!decoder.decode(stickyOffsetAtLastLayout))
2216         return false;
2217     
2218     FloatPoint layerPositionAtLastLayout;
2219     if (!decoder.decode(layerPositionAtLastLayout))
2220         return false;
2221     
2222     viewportConstraints = StickyPositionViewportConstraints();
2223     viewportConstraints.setAlignmentOffset(alignmentOffset);
2224     viewportConstraints.setAnchorEdges(anchorEdges);
2225
2226     viewportConstraints.setLeftOffset(leftOffset);
2227     viewportConstraints.setRightOffset(rightOffset);
2228     viewportConstraints.setTopOffset(topOffset);
2229     viewportConstraints.setBottomOffset(bottomOffset);
2230     
2231     viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout);
2232     viewportConstraints.setContainingBlockRect(containingBlockRect);
2233     viewportConstraints.setStickyBoxRect(stickyBoxRect);
2234
2235     viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout);
2236     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2237
2238     return true;
2239 }
2240
2241 #if !USE(COORDINATED_GRAPHICS)
2242 void ArgumentCoder<FilterOperation>::encode(Encoder& encoder, const FilterOperation& filter)
2243 {
2244     encoder.encodeEnum(filter.type());
2245
2246     switch (filter.type()) {
2247     case FilterOperation::NONE:
2248     case FilterOperation::REFERENCE:
2249         ASSERT_NOT_REACHED();
2250         break;
2251     case FilterOperation::GRAYSCALE:
2252     case FilterOperation::SEPIA:
2253     case FilterOperation::SATURATE:
2254     case FilterOperation::HUE_ROTATE:
2255         encoder << downcast<BasicColorMatrixFilterOperation>(filter).amount();
2256         break;
2257     case FilterOperation::INVERT:
2258     case FilterOperation::OPACITY:
2259     case FilterOperation::BRIGHTNESS:
2260     case FilterOperation::CONTRAST:
2261         encoder << downcast<BasicComponentTransferFilterOperation>(filter).amount();
2262         break;
2263     case FilterOperation::APPLE_INVERT_LIGHTNESS:
2264         ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
2265         break;
2266     case FilterOperation::BLUR:
2267         encoder << downcast<BlurFilterOperation>(filter).stdDeviation();
2268         break;
2269     case FilterOperation::DROP_SHADOW: {
2270         const auto& dropShadowFilter = downcast<DropShadowFilterOperation>(filter);
2271         encoder << dropShadowFilter.location();
2272         encoder << dropShadowFilter.stdDeviation();
2273         encoder << dropShadowFilter.color();
2274         break;
2275     }
2276     case FilterOperation::DEFAULT:
2277         encoder.encodeEnum(downcast<DefaultFilterOperation>(filter).representedType());
2278         break;
2279     case FilterOperation::PASSTHROUGH:
2280         break;
2281     }
2282 }
2283
2284 bool decodeFilterOperation(Decoder& decoder, RefPtr<FilterOperation>& filter)
2285 {
2286     FilterOperation::OperationType type;
2287     if (!decoder.decodeEnum(type))
2288         return false;
2289
2290     switch (type) {
2291     case FilterOperation::NONE:
2292     case FilterOperation::REFERENCE:
2293         ASSERT_NOT_REACHED();
2294         decoder.markInvalid();
2295         return false;
2296     case FilterOperation::GRAYSCALE:
2297     case FilterOperation::SEPIA:
2298     case FilterOperation::SATURATE:
2299     case FilterOperation::HUE_ROTATE: {
2300         double amount;
2301         if (!decoder.decode(amount))
2302             return false;
2303         filter = BasicColorMatrixFilterOperation::create(amount, type);
2304         break;
2305     }
2306     case FilterOperation::INVERT:
2307     case FilterOperation::OPACITY:
2308     case FilterOperation::BRIGHTNESS:
2309     case FilterOperation::CONTRAST: {
2310         double amount;
2311         if (!decoder.decode(amount))
2312             return false;
2313         filter = BasicComponentTransferFilterOperation::create(amount, type);
2314         break;
2315     }
2316     case FilterOperation::APPLE_INVERT_LIGHTNESS:
2317         ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
2318         break;
2319     case FilterOperation::BLUR: {
2320         Length stdDeviation;
2321         if (!decoder.decode(stdDeviation))
2322             return false;
2323         filter = BlurFilterOperation::create(stdDeviation);
2324         break;
2325     }
2326     case FilterOperation::DROP_SHADOW: {
2327         IntPoint location;
2328         int stdDeviation;
2329         Color color;
2330         if (!decoder.decode(location))
2331             return false;
2332         if (!decoder.decode(stdDeviation))
2333             return false;
2334         if (!decoder.decode(color))
2335             return false;
2336         filter = DropShadowFilterOperation::create(location, stdDeviation, color);
2337         break;
2338     }
2339     case FilterOperation::DEFAULT: {
2340         FilterOperation::OperationType representedType;
2341         if (!decoder.decodeEnum(representedType))
2342             return false;
2343         filter = DefaultFilterOperation::create(representedType);
2344         break;
2345     }
2346     case FilterOperation::PASSTHROUGH:
2347         filter = PassthroughFilterOperation::create();
2348         break;
2349     }
2350             
2351     return true;
2352 }
2353
2354
2355 void ArgumentCoder<FilterOperations>::encode(Encoder& encoder, const FilterOperations& filters)
2356 {
2357     encoder << static_cast<uint64_t>(filters.size());
2358
2359     for (const auto& filter : filters.operations())
2360         encoder << *filter;
2361 }
2362
2363 bool ArgumentCoder<FilterOperations>::decode(Decoder& decoder, FilterOperations& filters)
2364 {
2365     uint64_t filterCount;
2366     if (!decoder.decode(filterCount))
2367         return false;
2368
2369     for (uint64_t i = 0; i < filterCount; ++i) {
2370         RefPtr<FilterOperation> filter;
2371         if (!decodeFilterOperation(decoder, filter))
2372             return false;
2373         filters.operations().append(WTFMove(filter));
2374     }
2375
2376     return true;
2377 }
2378 #endif // !USE(COORDINATED_GRAPHICS)
2379
2380 void ArgumentCoder<BlobPart>::encode(Encoder& encoder, const BlobPart& blobPart)
2381 {
2382     encoder << static_cast<uint32_t>(blobPart.type());
2383     switch (blobPart.type()) {
2384     case BlobPart::Data:
2385         encoder << blobPart.data();
2386         break;
2387     case BlobPart::Blob:
2388         encoder << blobPart.url();
2389         break;
2390     }
2391 }
2392
2393 std::optional<BlobPart> ArgumentCoder<BlobPart>::decode(Decoder& decoder)
2394 {
2395     BlobPart blobPart;
2396
2397     std::optional<uint32_t> type;
2398     decoder >> type;
2399     if (!type)
2400         return std::nullopt;
2401
2402     switch (*type) {
2403     case BlobPart::Data: {
2404         std::optional<Vector<uint8_t>> data;
2405         decoder >> data;
2406         if (!data)
2407             return std::nullopt;
2408         blobPart = BlobPart(WTFMove(*data));
2409         break;
2410     }
2411     case BlobPart::Blob: {
2412         URL url;
2413         if (!decoder.decode(url))
2414             return std::nullopt;
2415         blobPart = BlobPart(url);
2416         break;
2417     }
2418     default:
2419         return std::nullopt;
2420     }
2421
2422     return WTFMove(blobPart);
2423 }
2424
2425 void ArgumentCoder<TextIndicatorData>::encode(Encoder& encoder, const TextIndicatorData& textIndicatorData)
2426 {
2427     encoder << textIndicatorData.selectionRectInRootViewCoordinates;
2428     encoder << textIndicatorData.textBoundingRectInRootViewCoordinates;
2429     encoder << textIndicatorData.textRectsInBoundingRectCoordinates;
2430     encoder << textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates;
2431     encoder << textIndicatorData.contentImageScaleFactor;
2432     encoder << textIndicatorData.estimatedBackgroundColor;
2433     encoder.encodeEnum(textIndicatorData.presentationTransition);
2434     encoder << static_cast<uint64_t>(textIndicatorData.options);
2435
2436     encodeOptionalImage(encoder, textIndicatorData.contentImage.get());
2437     encodeOptionalImage(encoder, textIndicatorData.contentImageWithHighlight.get());
2438     encodeOptionalImage(encoder, textIndicatorData.contentImageWithoutSelection.get());
2439 }
2440
2441 std::optional<TextIndicatorData> ArgumentCoder<TextIndicatorData>::decode(Decoder& decoder)
2442 {
2443     TextIndicatorData textIndicatorData;
2444     if (!decoder.decode(textIndicatorData.selectionRectInRootViewCoordinates))
2445         return std::nullopt;
2446
2447     if (!decoder.decode(textIndicatorData.textBoundingRectInRootViewCoordinates))
2448         return std::nullopt;
2449
2450     if (!decoder.decode(textIndicatorData.textRectsInBoundingRectCoordinates))
2451         return std::nullopt;
2452
2453     if (!decoder.decode(textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates))
2454         return std::nullopt;
2455
2456     if (!decoder.decode(textIndicatorData.contentImageScaleFactor))
2457         return std::nullopt;
2458
2459     if (!decoder.decode(textIndicatorData.estimatedBackgroundColor))
2460         return std::nullopt;
2461
2462     if (!decoder.decodeEnum(textIndicatorData.presentationTransition))
2463         return std::nullopt;
2464
2465     uint64_t options;
2466     if (!decoder.decode(options))
2467         return std::nullopt;
2468     textIndicatorData.options = static_cast<TextIndicatorOptions>(options);
2469
2470     if (!decodeOptionalImage(decoder, textIndicatorData.contentImage))
2471         return std::nullopt;
2472
2473     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithHighlight))
2474         return std::nullopt;
2475
2476     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithoutSelection))
2477         return std::nullopt;
2478
2479     return WTFMove(textIndicatorData);
2480 }
2481
2482 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
2483 void ArgumentCoder<MediaPlaybackTargetContext>::encode(Encoder& encoder, const MediaPlaybackTargetContext& target)
2484 {
2485     bool hasPlatformData = target.encodingRequiresPlatformData();
2486     encoder << hasPlatformData;
2487
2488     int32_t targetType = target.type();
2489     encoder << targetType;
2490
2491     if (target.encodingRequiresPlatformData()) {
2492         encodePlatformData(encoder, target);
2493         return;
2494     }
2495
2496     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2497     encoder << target.mockDeviceName();
2498     encoder << static_cast<int32_t>(target.mockState());
2499 }
2500
2501 bool ArgumentCoder<MediaPlaybackTargetContext>::decode(Decoder& decoder, MediaPlaybackTargetContext& target)
2502 {
2503     bool hasPlatformData;
2504     if (!decoder.decode(hasPlatformData))
2505         return false;
2506
2507     int32_t targetType;
2508     if (!decoder.decode(targetType))
2509         return false;
2510
2511     if (hasPlatformData)
2512         return decodePlatformData(decoder, target);
2513
2514     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2515
2516     String mockDeviceName;
2517     if (!decoder.decode(mockDeviceName))
2518         return false;
2519
2520     int32_t mockState;
2521     if (!decoder.decode(mockState))
2522         return false;
2523
2524     target = MediaPlaybackTargetContext(mockDeviceName, static_cast<MediaPlaybackTargetContext::State>(mockState));
2525     return true;
2526 }
2527 #endif
2528
2529 void ArgumentCoder<DictionaryPopupInfo>::encode(IPC::Encoder& encoder, const DictionaryPopupInfo& info)
2530 {
2531     encoder << info.origin;
2532     encoder << info.textIndicator;
2533
2534 #if PLATFORM(COCOA)
2535     bool hadOptions = info.options;
2536     encoder << hadOptions;
2537     if (hadOptions)
2538         IPC::encode(encoder, info.options.get());
2539
2540     bool hadAttributedString = info.attributedString;
2541     encoder << hadAttributedString;
2542     if (hadAttributedString)
2543         IPC::encode(encoder, info.attributedString.get());
2544 #endif
2545 }
2546
2547 bool ArgumentCoder<DictionaryPopupInfo>::decode(IPC::Decoder& decoder, DictionaryPopupInfo& result)
2548 {
2549     if (!decoder.decode(result.origin))
2550         return false;
2551
2552     std::optional<TextIndicatorData> textIndicator;
2553     decoder >> textIndicator;
2554     if (!textIndicator)
2555         return false;
2556     result.textIndicator = WTFMove(*textIndicator);
2557
2558 #if PLATFORM(COCOA)
2559     bool hadOptions;
2560     if (!decoder.decode(hadOptions))
2561         return false;
2562     if (hadOptions) {
2563         if (!IPC::decode(decoder, result.options))
2564             return false;
2565     } else
2566         result.options = nullptr;
2567
2568     bool hadAttributedString;
2569     if (!decoder.decode(hadAttributedString))
2570         return false;
2571     if (hadAttributedString) {
2572         if (!IPC::decode(decoder, result.attributedString))
2573             return false;
2574     } else
2575         result.attributedString = nullptr;
2576 #endif
2577     return true;
2578 }
2579
2580 void ArgumentCoder<ExceptionDetails>::encode(IPC::Encoder& encoder, const ExceptionDetails& info)
2581 {
2582     encoder << info.message;
2583     encoder << info.lineNumber;
2584     encoder << info.columnNumber;
2585     encoder << info.sourceURL;
2586 }
2587
2588 bool ArgumentCoder<ExceptionDetails>::decode(IPC::Decoder& decoder, ExceptionDetails& result)
2589 {
2590     if (!decoder.decode(result.message))
2591         return false;
2592
2593     if (!decoder.decode(result.lineNumber))
2594         return false;
2595
2596     if (!decoder.decode(result.columnNumber))
2597         return false;
2598
2599     if (!decoder.decode(result.sourceURL))
2600         return false;
2601
2602     return true;
2603 }
2604
2605 void ArgumentCoder<ResourceLoadStatistics>::encode(Encoder& encoder, const WebCore::ResourceLoadStatistics& statistics)
2606 {
2607     encoder << statistics.highLevelDomain;
2608     
2609     encoder << statistics.lastSeen.secondsSinceEpoch().value();
2610     
2611     // User interaction
2612     encoder << statistics.hadUserInteraction;
2613     encoder << statistics.mostRecentUserInteractionTime.secondsSinceEpoch().value();
2614     encoder << statistics.grandfathered;
2615
2616     // Storage access
2617     encoder << statistics.storageAccessUnderTopFrameOrigins;
2618
2619     // Top frame stats
2620     encoder << statistics.topFrameUniqueRedirectsTo;
2621     encoder << statistics.topFrameUniqueRedirectsFrom;
2622
2623     // Subframe stats
2624     encoder << statistics.subframeUnderTopFrameOrigins;
2625     
2626     // Subresource stats
2627     encoder << statistics.subresourceUnderTopFrameOrigins;
2628     encoder << statistics.subresourceUniqueRedirectsTo;
2629     encoder << statistics.subresourceUniqueRedirectsFrom;
2630
2631     // Prevalent Resource
2632     encoder << statistics.isPrevalentResource;
2633     encoder << statistics.isVeryPrevalentResource;
2634     encoder << statistics.dataRecordsRemoved;
2635 }
2636
2637 std::optional<ResourceLoadStatistics> ArgumentCoder<ResourceLoadStatistics>::decode(Decoder& decoder)
2638 {
2639     ResourceLoadStatistics statistics;
2640     if (!decoder.decode(statistics.highLevelDomain))
2641         return std::nullopt;
2642     
2643     double lastSeenTimeAsDouble;
2644     if (!decoder.decode(lastSeenTimeAsDouble))
2645         return std::nullopt;
2646     statistics.lastSeen = WallTime::fromRawSeconds(lastSeenTimeAsDouble);
2647     
2648     // User interaction
2649     if (!decoder.decode(statistics.hadUserInteraction))
2650         return std::nullopt;
2651
2652     double mostRecentUserInteractionTimeAsDouble;
2653     if (!decoder.decode(mostRecentUserInteractionTimeAsDouble))
2654         return std::nullopt;
2655     statistics.mostRecentUserInteractionTime = WallTime::fromRawSeconds(mostRecentUserInteractionTimeAsDouble);
2656
2657     if (!decoder.decode(statistics.grandfathered))
2658         return std::nullopt;
2659
2660     // Storage access
2661     if (!decoder.decode(statistics.storageAccessUnderTopFrameOrigins))
2662         return std::nullopt;
2663
2664     // Top frame stats
2665     if (!decoder.decode(statistics.topFrameUniqueRedirectsTo))
2666         return std::nullopt;    
2667
2668     if (!decoder.decode(statistics.topFrameUniqueRedirectsFrom))
2669         return std::nullopt;
2670
2671     // Subframe stats
2672     if (!decoder.decode(statistics.subframeUnderTopFrameOrigins))
2673         return std::nullopt;
2674     
2675     // Subresource stats
2676     if (!decoder.decode(statistics.subresourceUnderTopFrameOrigins))
2677         return std::nullopt;
2678
2679     if (!decoder.decode(statistics.subresourceUniqueRedirectsTo))
2680         return std::nullopt;
2681     
2682     if (!decoder.decode(statistics.subresourceUniqueRedirectsFrom))
2683         return std::nullopt;
2684     
2685     // Prevalent Resource
2686     if (!decoder.decode(statistics.isPrevalentResource))
2687         return std::nullopt;
2688
2689     if (!decoder.decode(statistics.isVeryPrevalentResource))
2690         return std::nullopt;
2691     
2692     if (!decoder.decode(statistics.dataRecordsRemoved))
2693         return std::nullopt;
2694
2695     return WTFMove(statistics);
2696 }
2697
2698 #if ENABLE(MEDIA_STREAM)
2699 void ArgumentCoder<MediaConstraints>::encode(Encoder& encoder, const WebCore::MediaConstraints& constraint)
2700 {
2701     encoder << constraint.mandatoryConstraints
2702         << constraint.advancedConstraints
2703         << constraint.deviceIDHashSalt
2704         << constraint.isValid;
2705 }
2706
2707 bool ArgumentCoder<MediaConstraints>::decode(Decoder& decoder, WebCore::MediaConstraints& constraints)
2708 {
2709     std::optional<WebCore::MediaTrackConstraintSetMap> mandatoryConstraints;
2710     decoder >> mandatoryConstraints;
2711     if (!mandatoryConstraints)
2712         return false;
2713     constraints.mandatoryConstraints = WTFMove(*mandatoryConstraints);
2714     return decoder.decode(constraints.advancedConstraints)
2715         && decoder.decode(constraints.deviceIDHashSalt)
2716         && decoder.decode(constraints.isValid);
2717 }
2718 #endif
2719
2720 #if ENABLE(INDEXED_DATABASE)
2721 void ArgumentCoder<IDBKeyPath>::encode(Encoder& encoder, const IDBKeyPath& keyPath)
2722 {
2723     bool isString = WTF::holds_alternative<String>(keyPath);
2724     encoder << isString;
2725     if (isString)
2726         encoder << WTF::get<String>(keyPath);
2727     else
2728         encoder << WTF::get<Vector<String>>(keyPath);
2729 }
2730
2731 bool ArgumentCoder<IDBKeyPath>::decode(Decoder& decoder, IDBKeyPath& keyPath)
2732 {
2733     bool isString;
2734     if (!decoder.decode(isString))
2735         return false;
2736     if (isString) {
2737         String string;
2738         if (!decoder.decode(string))
2739             return false;
2740         keyPath = string;
2741     } else {
2742         Vector<String> vector;
2743         if (!decoder.decode(vector))
2744             return false;
2745         keyPath = vector;
2746     }
2747     return true;
2748 }
2749 #endif
2750
2751 #if ENABLE(SERVICE_WORKER)
2752 void ArgumentCoder<ServiceWorkerOrClientData>::encode(Encoder& encoder, const ServiceWorkerOrClientData& data)
2753 {
2754     bool isServiceWorkerData = WTF::holds_alternative<ServiceWorkerData>(data);
2755     encoder << isServiceWorkerData;
2756     if (isServiceWorkerData)
2757         encoder << WTF::get<ServiceWorkerData>(data);
2758     else
2759         encoder << WTF::get<ServiceWorkerClientData>(data);
2760 }
2761
2762 bool ArgumentCoder<ServiceWorkerOrClientData>::decode(Decoder& decoder, ServiceWorkerOrClientData& data)
2763 {
2764     bool isServiceWorkerData;
2765     if (!decoder.decode(isServiceWorkerData))
2766         return false;
2767     if (isServiceWorkerData) {
2768         std::optional<ServiceWorkerData> workerData;
2769         decoder >> workerData;
2770         if (!workerData)
2771             return false;
2772
2773         data = WTFMove(*workerData);
2774     } else {
2775         std::optional<ServiceWorkerClientData> clientData;
2776         decoder >> clientData;
2777         if (!clientData)
2778             return false;
2779
2780         data = WTFMove(*clientData);
2781     }
2782     return true;
2783 }
2784
2785 void ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode(Encoder& encoder, const ServiceWorkerOrClientIdentifier& identifier)
2786 {
2787     bool isServiceWorkerIdentifier = WTF::holds_alternative<ServiceWorkerIdentifier>(identifier);
2788     encoder << isServiceWorkerIdentifier;
2789     if (isServiceWorkerIdentifier)
2790         encoder << WTF::get<ServiceWorkerIdentifier>(identifier);
2791     else
2792         encoder << WTF::get<ServiceWorkerClientIdentifier>(identifier);
2793 }
2794
2795 bool ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode(Decoder& decoder, ServiceWorkerOrClientIdentifier& identifier)
2796 {
2797     bool isServiceWorkerIdentifier;
2798     if (!decoder.decode(isServiceWorkerIdentifier))
2799         return false;
2800     if (isServiceWorkerIdentifier) {
2801         std::optional<ServiceWorkerIdentifier> workerIdentifier;
2802         decoder >> workerIdentifier;
2803         if (!workerIdentifier)
2804             return false;
2805
2806         identifier = WTFMove(*workerIdentifier);
2807     } else {
2808         std::optional<ServiceWorkerClientIdentifier> clientIdentifier;
2809         decoder >> clientIdentifier;
2810         if (!clientIdentifier)
2811             return false;
2812
2813         identifier = WTFMove(*clientIdentifier);
2814     }
2815     return true;
2816 }
2817 #endif
2818
2819 #if ENABLE(CSS_SCROLL_SNAP)
2820
2821 void ArgumentCoder<ScrollOffsetRange<float>>::encode(Encoder& encoder, const ScrollOffsetRange<float>& range)
2822 {
2823     encoder << range.start;
2824     encoder << range.end;
2825 }
2826
2827 auto ArgumentCoder<ScrollOffsetRange<float>>::decode(Decoder& decoder) -> std::optional<WebCore::ScrollOffsetRange<float>>
2828 {
2829     WebCore::ScrollOffsetRange<float> range;
2830     float start;
2831     if (!decoder.decode(start))
2832         return std::nullopt;
2833
2834     float end;
2835     if (!decoder.decode(end))
2836         return std::nullopt;
2837
2838     range.start = start;
2839     range.end = end;
2840     return WTFMove(range);
2841 }
2842
2843 #endif
2844
2845 void ArgumentCoder<MediaSelectionOption>::encode(Encoder& encoder, const MediaSelectionOption& option)
2846 {
2847     encoder << option.displayName;
2848     encoder << option.type;
2849 }
2850
2851 std::optional<MediaSelectionOption> ArgumentCoder<MediaSelectionOption>::decode(Decoder& decoder)
2852 {
2853     std::optional<String> displayName;
2854     decoder >> displayName;
2855     if (!displayName)
2856         return std::nullopt;
2857     
2858     std::optional<MediaSelectionOption::Type> type;
2859     decoder >> type;
2860     if (!type)
2861         return std::nullopt;
2862     
2863     return {{ WTFMove(*displayName), WTFMove(*type) }};
2864 }
2865
2866 void ArgumentCoder<PromisedBlobInfo>::encode(Encoder& encoder, const PromisedBlobInfo& info)
2867 {
2868     encoder << info.blobURL;
2869     encoder << info.contentType;
2870     encoder << info.filename;
2871     encodeTypesAndData(encoder, info.additionalTypes, info.additionalData);
2872 }
2873
2874 bool ArgumentCoder<PromisedBlobInfo>::decode(Decoder& decoder, PromisedBlobInfo& info)
2875 {
2876     if (!decoder.decode(info.blobURL))
2877         return false;
2878
2879     if (!decoder.decode(info.contentType))
2880         return false;
2881
2882     if (!decoder.decode(info.filename))
2883         return false;
2884
2885     if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData))
2886         return false;
2887
2888     return true;
2889 }
2890
2891 #if ENABLE(ATTACHMENT_ELEMENT)
2892
2893 void ArgumentCoder<AttachmentInfo>::encode(Encoder& encoder, const AttachmentInfo& info)
2894 {
2895     bool dataIsNull = !info.data;
2896     encoder << info.contentType << info.name << info.filePath << dataIsNull;
2897     if (!dataIsNull) {
2898         SharedBufferDataReference dataReference { info.data.get() };
2899         encoder << static_cast<DataReference&>(dataReference);
2900     }
2901 }
2902
2903 bool ArgumentCoder<AttachmentInfo>::decode(Decoder& decoder, AttachmentInfo& info)
2904 {
2905     if (!decoder.decode(info.contentType))
2906         return false;
2907
2908     if (!decoder.decode(info.name))
2909         return false;
2910
2911     if (!decoder.decode(info.filePath))
2912         return false;
2913
2914     bool dataIsNull = true;
2915     if (!decoder.decode(dataIsNull))
2916         return false;
2917
2918     if (!dataIsNull) {
2919         DataReference dataReference;
2920         if (!decoder.decode(dataReference))
2921             return false;
2922         info.data = SharedBuffer::create(dataReference.data(), dataReference.size());
2923     }
2924
2925     return true;
2926 }
2927
2928 #endif // ENABLE(ATTACHMENT_ELEMENT)
2929
2930 void ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::encode(Encoder& encoder, const Vector<RefPtr<SecurityOrigin>>& origins)
2931 {
2932     encoder << static_cast<uint64_t>(origins.size());
2933     for (auto& origin : origins)
2934         encoder << *origin;
2935 }
2936     
2937 bool ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::decode(Decoder& decoder, Vector<RefPtr<SecurityOrigin>>& origins)
2938 {
2939     uint64_t dataSize;
2940     if (!decoder.decode(dataSize))
2941         return false;
2942
2943     origins.reserveInitialCapacity(dataSize);
2944     for (uint64_t i = 0; i < dataSize; ++i) {
2945         auto decodedOriginRefPtr = SecurityOrigin::decode(decoder);
2946         if (!decodedOriginRefPtr)
2947             return false;
2948         origins.uncheckedAppend(decodedOriginRefPtr.releaseNonNull());
2949     }
2950     return true;
2951 }
2952
2953 } // namespace IPC