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