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