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