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