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