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