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