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