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