Extended Color Cleanup: Move Color coder definitions to Color to allow for future...
[WebKit-https.git] / Source / WebKit / Shared / WebCoreArgumentCoders.cpp
1 /*
2  * Copyright (C) 2011-2020 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 "SharedBufferDataReference.h"
32 #include <JavaScriptCore/GenericTypedArrayViewInlines.h>
33 #include <JavaScriptCore/JSGenericTypedArrayViewInlines.h>
34 #include <WebCore/AuthenticationChallenge.h>
35 #include <WebCore/BlobPart.h>
36 #include <WebCore/CacheQueryOptions.h>
37 #include <WebCore/CacheStorageConnection.h>
38 #include <WebCore/CertificateInfo.h>
39 #include <WebCore/CompositionUnderline.h>
40 #include <WebCore/Credential.h>
41 #include <WebCore/Cursor.h>
42 #include <WebCore/DatabaseDetails.h>
43 #include <WebCore/DictationAlternative.h>
44 #include <WebCore/DictionaryPopupInfo.h>
45 #include <WebCore/DisplayListItems.h>
46 #include <WebCore/DragData.h>
47 #include <WebCore/EventTrackingRegions.h>
48 #include <WebCore/FetchOptions.h>
49 #include <WebCore/File.h>
50 #include <WebCore/FileChooser.h>
51 #include <WebCore/FilterOperation.h>
52 #include <WebCore/FilterOperations.h>
53 #include <WebCore/Font.h>
54 #include <WebCore/FontAttributes.h>
55 #include <WebCore/GraphicsContext.h>
56 #include <WebCore/GraphicsLayer.h>
57 #include <WebCore/IDBGetResult.h>
58 #include <WebCore/Image.h>
59 #include <WebCore/JSDOMExceptionHandling.h>
60 #include <WebCore/Length.h>
61 #include <WebCore/LengthBox.h>
62 #include <WebCore/MediaSelectionOption.h>
63 #include <WebCore/NativeImage.h>
64 #include <WebCore/Pasteboard.h>
65 #include <WebCore/PluginData.h>
66 #include <WebCore/PromisedAttachmentInfo.h>
67 #include <WebCore/ProtectionSpace.h>
68 #include <WebCore/RectEdges.h>
69 #include <WebCore/Region.h>
70 #include <WebCore/RegistrableDomain.h>
71 #include <WebCore/ResourceError.h>
72 #include <WebCore/ResourceLoadStatistics.h>
73 #include <WebCore/ResourceRequest.h>
74 #include <WebCore/ResourceResponse.h>
75 #include <WebCore/ScrollingConstraints.h>
76 #include <WebCore/ScrollingCoordinator.h>
77 #include <WebCore/SearchPopupMenu.h>
78 #include <WebCore/SecurityOrigin.h>
79 #include <WebCore/SerializedAttachmentData.h>
80 #include <WebCore/SerializedPlatformDataCueValue.h>
81 #include <WebCore/ServiceWorkerClientData.h>
82 #include <WebCore/ServiceWorkerClientIdentifier.h>
83 #include <WebCore/ServiceWorkerData.h>
84 #include <WebCore/ShareData.h>
85 #include <WebCore/TextCheckerClient.h>
86 #include <WebCore/TextIndicator.h>
87 #include <WebCore/TimingFunction.h>
88 #include <WebCore/TransformationMatrix.h>
89 #include <WebCore/UserStyleSheet.h>
90 #include <WebCore/VelocityData.h>
91 #include <WebCore/ViewportArguments.h>
92 #include <WebCore/WindowFeatures.h>
93 #include <wtf/URL.h>
94 #include <wtf/text/CString.h>
95 #include <wtf/text/StringHash.h>
96
97 #if PLATFORM(COCOA)
98 #include "ArgumentCodersCF.h"
99 #endif
100
101 #if PLATFORM(IOS_FAMILY)
102 #include <WebCore/FloatQuad.h>
103 #include <WebCore/InspectorOverlay.h>
104 #include <WebCore/SelectionRect.h>
105 #include <WebCore/SharedBuffer.h>
106 #endif // PLATFORM(IOS_FAMILY)
107
108 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
109 #include <WebCore/MediaPlaybackTargetContext.h>
110 #endif
111
112 #if ENABLE(MEDIA_SESSION)
113 #include <WebCore/MediaSessionMetadata.h>
114 #endif
115
116 #if ENABLE(MEDIA_STREAM)
117 #include <WebCore/CaptureDevice.h>
118 #include <WebCore/MediaConstraints.h>
119 #endif
120
121 // FIXME: Seems like we could use std::tuple to cut down the code below a lot!
122
123 namespace IPC {
124 using namespace WebCore;
125 using namespace WebKit;
126
127 static void encodeSharedBuffer(Encoder& encoder, const SharedBuffer* buffer)
128 {
129     uint64_t bufferSize = buffer ? buffer->size() : 0;
130     encoder << bufferSize;
131     if (!bufferSize)
132         return;
133
134 #if USE(UNIX_DOMAIN_SOCKETS)
135     // Do not use shared memory for SharedBuffer encoding in Unix, because it's easy to reach the
136     // maximum number of file descriptors open per process when sending large data in small chunks
137     // over the IPC. ConnectionUnix.cpp already uses shared memory to send any IPC message that is
138     // too large. See https://bugs.webkit.org/show_bug.cgi?id=208571.
139     for (const auto& element : *buffer)
140         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(element.segment->data()), element.segment->size(), 1);
141 #else
142     SharedMemory::Handle handle;
143     auto sharedMemoryBuffer = SharedMemory::allocate(buffer->size());
144     memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
145     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
146     encoder << handle;
147 #endif
148 }
149
150 static WARN_UNUSED_RETURN bool decodeSharedBuffer(Decoder& decoder, RefPtr<SharedBuffer>& buffer)
151 {
152     uint64_t bufferSize = 0;
153     if (!decoder.decode(bufferSize))
154         return false;
155
156     if (!bufferSize)
157         return true;
158
159 #if USE(UNIX_DOMAIN_SOCKETS)
160     if (!decoder.bufferIsLargeEnoughToContain<uint8_t>(bufferSize))
161         return false;
162
163     Vector<uint8_t> data;
164     data.grow(bufferSize);
165     if (!decoder.decodeFixedLengthData(data.data(), data.size(), 1))
166         return false;
167
168     buffer = SharedBuffer::create(WTFMove(data));
169 #else
170     SharedMemory::Handle handle;
171     if (!decoder.decode(handle))
172         return false;
173
174     // SharedMemory::Handle::size() is rounded up to the nearest page.
175     if (bufferSize > handle.size())
176         return false;
177
178     auto sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
179     if (!sharedMemoryBuffer)
180         return false;
181
182     buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), bufferSize);
183 #endif
184
185     return true;
186 }
187
188 static void encodeTypesAndData(Encoder& encoder, const Vector<String>& types, const Vector<RefPtr<SharedBuffer>>& data)
189 {
190     ASSERT(types.size() == data.size());
191     encoder << types;
192     encoder << static_cast<uint64_t>(data.size());
193     for (auto& buffer : data)
194         encodeSharedBuffer(encoder, buffer.get());
195 }
196
197 static WARN_UNUSED_RETURN bool decodeTypesAndData(Decoder& decoder, Vector<String>& types, Vector<RefPtr<SharedBuffer>>& data)
198 {
199     if (!decoder.decode(types))
200         return false;
201
202     uint64_t dataSize;
203     if (!decoder.decode(dataSize))
204         return false;
205
206     ASSERT(dataSize == types.size());
207
208     for (uint64_t i = 0; i < dataSize; i++) {
209         RefPtr<SharedBuffer> buffer;
210         if (!decodeSharedBuffer(decoder, buffer))
211             return false;
212         data.append(WTFMove(buffer));
213     }
214
215     return true;
216 }
217
218 void ArgumentCoder<AffineTransform>::encode(Encoder& encoder, const AffineTransform& affineTransform)
219 {
220     SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
221 }
222
223 bool ArgumentCoder<AffineTransform>::decode(Decoder& decoder, AffineTransform& affineTransform)
224 {
225     return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
226 }
227
228 void ArgumentCoder<CacheQueryOptions>::encode(Encoder& encoder, const CacheQueryOptions& options)
229 {
230     encoder << options.ignoreSearch;
231     encoder << options.ignoreMethod;
232     encoder << options.ignoreVary;
233     encoder << options.cacheName;
234 }
235
236 bool ArgumentCoder<CacheQueryOptions>::decode(Decoder& decoder, CacheQueryOptions& options)
237 {
238     bool ignoreSearch;
239     if (!decoder.decode(ignoreSearch))
240         return false;
241     bool ignoreMethod;
242     if (!decoder.decode(ignoreMethod))
243         return false;
244     bool ignoreVary;
245     if (!decoder.decode(ignoreVary))
246         return false;
247     String cacheName;
248     if (!decoder.decode(cacheName))
249         return false;
250
251     options.ignoreSearch = ignoreSearch;
252     options.ignoreMethod = ignoreMethod;
253     options.ignoreVary = ignoreVary;
254     options.cacheName = WTFMove(cacheName);
255     return true;
256 }
257
258 void ArgumentCoder<CharacterRange>::encode(Encoder& encoder, const CharacterRange& range)
259 {
260     encoder << static_cast<uint64_t>(range.location);
261     encoder << static_cast<uint64_t>(range.length);
262 }
263
264 Optional<CharacterRange> ArgumentCoder<CharacterRange>::decode(Decoder& decoder)
265 {
266     Optional<uint64_t> location;
267     decoder >> location;
268     if (!location)
269         return WTF::nullopt;
270
271     Optional<uint64_t> length;
272     decoder >> length;
273     if (!length)
274         return WTF::nullopt;
275
276     return { { *location, *length } };
277 }
278
279 void ArgumentCoder<DOMCacheEngine::CacheInfo>::encode(Encoder& encoder, const DOMCacheEngine::CacheInfo& info)
280 {
281     encoder << info.identifier;
282     encoder << info.name;
283 }
284
285 auto ArgumentCoder<DOMCacheEngine::CacheInfo>::decode(Decoder& decoder) -> Optional<DOMCacheEngine::CacheInfo>
286 {
287     Optional<uint64_t> identifier;
288     decoder >> identifier;
289     if (!identifier)
290         return WTF::nullopt;
291     
292     Optional<String> name;
293     decoder >> name;
294     if (!name)
295         return WTF::nullopt;
296     
297     return {{ WTFMove(*identifier), WTFMove(*name) }};
298 }
299
300 void ArgumentCoder<DOMCacheEngine::Record>::encode(Encoder& encoder, const DOMCacheEngine::Record& record)
301 {
302     encoder << record.identifier;
303
304     encoder << record.requestHeadersGuard;
305     encoder << record.request;
306     encoder << record.options;
307     encoder << record.referrer;
308
309     encoder << record.responseHeadersGuard;
310     encoder << record.response;
311     encoder << record.updateResponseCounter;
312     encoder << record.responseBodySize;
313
314     WTF::switchOn(record.responseBody, [&](const Ref<SharedBuffer>& buffer) {
315         encoder << true;
316         encodeSharedBuffer(encoder, buffer.ptr());
317     }, [&](const Ref<FormData>& formData) {
318         encoder << false;
319         encoder << true;
320         formData->encode(encoder);
321     }, [&](const std::nullptr_t&) {
322         encoder << false;
323         encoder << false;
324     });
325 }
326
327 Optional<DOMCacheEngine::Record> ArgumentCoder<DOMCacheEngine::Record>::decode(Decoder& decoder)
328 {
329     uint64_t identifier;
330     if (!decoder.decode(identifier))
331         return WTF::nullopt;
332
333     FetchHeaders::Guard requestHeadersGuard;
334     if (!decoder.decode(requestHeadersGuard))
335         return WTF::nullopt;
336
337     WebCore::ResourceRequest request;
338     if (!decoder.decode(request))
339         return WTF::nullopt;
340
341     Optional<WebCore::FetchOptions> options;
342     decoder >> options;
343     if (!options)
344         return WTF::nullopt;
345
346     String referrer;
347     if (!decoder.decode(referrer))
348         return WTF::nullopt;
349
350     FetchHeaders::Guard responseHeadersGuard;
351     if (!decoder.decode(responseHeadersGuard))
352         return WTF::nullopt;
353
354     WebCore::ResourceResponse response;
355     if (!decoder.decode(response))
356         return WTF::nullopt;
357
358     uint64_t updateResponseCounter;
359     if (!decoder.decode(updateResponseCounter))
360         return WTF::nullopt;
361
362     uint64_t responseBodySize;
363     if (!decoder.decode(responseBodySize))
364         return WTF::nullopt;
365
366     WebCore::DOMCacheEngine::ResponseBody responseBody;
367     bool hasSharedBufferBody;
368     if (!decoder.decode(hasSharedBufferBody))
369         return WTF::nullopt;
370
371     if (hasSharedBufferBody) {
372         RefPtr<SharedBuffer> buffer;
373         if (!decodeSharedBuffer(decoder, buffer))
374             return WTF::nullopt;
375         if (buffer)
376             responseBody = buffer.releaseNonNull();
377     } else {
378         bool hasFormDataBody;
379         if (!decoder.decode(hasFormDataBody))
380             return WTF::nullopt;
381         if (hasFormDataBody) {
382             auto formData = FormData::decode(decoder);
383             if (!formData)
384                 return WTF::nullopt;
385             responseBody = formData.releaseNonNull();
386         }
387     }
388
389     return {{ WTFMove(identifier), WTFMove(updateResponseCounter), WTFMove(requestHeadersGuard), WTFMove(request), WTFMove(options.value()), WTFMove(referrer), WTFMove(responseHeadersGuard), WTFMove(response), WTFMove(responseBody), responseBodySize }};
390 }
391
392 void ArgumentCoder<EventTrackingRegions>::encode(Encoder& encoder, const EventTrackingRegions& eventTrackingRegions)
393 {
394     encoder << eventTrackingRegions.asynchronousDispatchRegion;
395     encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions;
396 }
397
398 bool ArgumentCoder<EventTrackingRegions>::decode(Decoder& decoder, EventTrackingRegions& eventTrackingRegions)
399 {
400     Optional<Region> asynchronousDispatchRegion;
401     decoder >> asynchronousDispatchRegion;
402     if (!asynchronousDispatchRegion)
403         return false;
404     HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
405     if (!decoder.decode(eventSpecificSynchronousDispatchRegions))
406         return false;
407     eventTrackingRegions.asynchronousDispatchRegion = WTFMove(*asynchronousDispatchRegion);
408     eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions);
409     return true;
410 }
411
412 void ArgumentCoder<TransformationMatrix>::encode(Encoder& encoder, const TransformationMatrix& transformationMatrix)
413 {
414     encoder << transformationMatrix.m11();
415     encoder << transformationMatrix.m12();
416     encoder << transformationMatrix.m13();
417     encoder << transformationMatrix.m14();
418
419     encoder << transformationMatrix.m21();
420     encoder << transformationMatrix.m22();
421     encoder << transformationMatrix.m23();
422     encoder << transformationMatrix.m24();
423
424     encoder << transformationMatrix.m31();
425     encoder << transformationMatrix.m32();
426     encoder << transformationMatrix.m33();
427     encoder << transformationMatrix.m34();
428
429     encoder << transformationMatrix.m41();
430     encoder << transformationMatrix.m42();
431     encoder << transformationMatrix.m43();
432     encoder << transformationMatrix.m44();
433 }
434
435 bool ArgumentCoder<TransformationMatrix>::decode(Decoder& decoder, TransformationMatrix& transformationMatrix)
436 {
437     double m11;
438     if (!decoder.decode(m11))
439         return false;
440     double m12;
441     if (!decoder.decode(m12))
442         return false;
443     double m13;
444     if (!decoder.decode(m13))
445         return false;
446     double m14;
447     if (!decoder.decode(m14))
448         return false;
449
450     double m21;
451     if (!decoder.decode(m21))
452         return false;
453     double m22;
454     if (!decoder.decode(m22))
455         return false;
456     double m23;
457     if (!decoder.decode(m23))
458         return false;
459     double m24;
460     if (!decoder.decode(m24))
461         return false;
462
463     double m31;
464     if (!decoder.decode(m31))
465         return false;
466     double m32;
467     if (!decoder.decode(m32))
468         return false;
469     double m33;
470     if (!decoder.decode(m33))
471         return false;
472     double m34;
473     if (!decoder.decode(m34))
474         return false;
475
476     double m41;
477     if (!decoder.decode(m41))
478         return false;
479     double m42;
480     if (!decoder.decode(m42))
481         return false;
482     double m43;
483     if (!decoder.decode(m43))
484         return false;
485     double m44;
486     if (!decoder.decode(m44))
487         return false;
488
489     transformationMatrix.setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
490     return true;
491 }
492
493 void ArgumentCoder<LinearTimingFunction>::encode(Encoder& encoder, const LinearTimingFunction& timingFunction)
494 {
495     encoder.encodeEnum(timingFunction.type());
496 }
497
498 bool ArgumentCoder<LinearTimingFunction>::decode(Decoder&, LinearTimingFunction&)
499 {
500     // Type is decoded by the caller. Nothing else to decode.
501     return true;
502 }
503
504 void ArgumentCoder<CubicBezierTimingFunction>::encode(Encoder& encoder, const CubicBezierTimingFunction& timingFunction)
505 {
506     encoder.encodeEnum(timingFunction.type());
507     
508     encoder << timingFunction.x1();
509     encoder << timingFunction.y1();
510     encoder << timingFunction.x2();
511     encoder << timingFunction.y2();
512     
513     encoder.encodeEnum(timingFunction.timingFunctionPreset());
514 }
515
516 bool ArgumentCoder<CubicBezierTimingFunction>::decode(Decoder& decoder, CubicBezierTimingFunction& timingFunction)
517 {
518     // Type is decoded by the caller.
519     double x1;
520     if (!decoder.decode(x1))
521         return false;
522
523     double y1;
524     if (!decoder.decode(y1))
525         return false;
526
527     double x2;
528     if (!decoder.decode(x2))
529         return false;
530
531     double y2;
532     if (!decoder.decode(y2))
533         return false;
534
535     CubicBezierTimingFunction::TimingFunctionPreset preset;
536     if (!decoder.decodeEnum(preset))
537         return false;
538
539     timingFunction.setValues(x1, y1, x2, y2);
540     timingFunction.setTimingFunctionPreset(preset);
541
542     return true;
543 }
544
545 void ArgumentCoder<StepsTimingFunction>::encode(Encoder& encoder, const StepsTimingFunction& timingFunction)
546 {
547     encoder.encodeEnum(timingFunction.type());
548     
549     encoder << timingFunction.numberOfSteps();
550     encoder << timingFunction.stepPosition();
551 }
552
553 bool ArgumentCoder<StepsTimingFunction>::decode(Decoder& decoder, StepsTimingFunction& timingFunction)
554 {
555     // Type is decoded by the caller.
556     int numSteps;
557     if (!decoder.decode(numSteps))
558         return false;
559
560     Optional<StepsTimingFunction::StepPosition> stepPosition;
561     if (!decoder.decode(stepPosition))
562         return false;
563
564     timingFunction.setNumberOfSteps(numSteps);
565     timingFunction.setStepPosition(stepPosition);
566
567     return true;
568 }
569
570 void ArgumentCoder<SpringTimingFunction>::encode(Encoder& encoder, const SpringTimingFunction& timingFunction)
571 {
572     encoder.encodeEnum(timingFunction.type());
573     
574     encoder << timingFunction.mass();
575     encoder << timingFunction.stiffness();
576     encoder << timingFunction.damping();
577     encoder << timingFunction.initialVelocity();
578 }
579
580 bool ArgumentCoder<SpringTimingFunction>::decode(Decoder& decoder, SpringTimingFunction& timingFunction)
581 {
582     // Type is decoded by the caller.
583     double mass;
584     if (!decoder.decode(mass))
585         return false;
586
587     double stiffness;
588     if (!decoder.decode(stiffness))
589         return false;
590
591     double damping;
592     if (!decoder.decode(damping))
593         return false;
594
595     double initialVelocity;
596     if (!decoder.decode(initialVelocity))
597         return false;
598
599     timingFunction.setValues(mass, stiffness, damping, initialVelocity);
600
601     return true;
602 }
603
604 void ArgumentCoder<FloatPoint>::encode(Encoder& encoder, const FloatPoint& floatPoint)
605 {
606     SimpleArgumentCoder<FloatPoint>::encode(encoder, floatPoint);
607 }
608
609 bool ArgumentCoder<FloatPoint>::decode(Decoder& decoder, FloatPoint& floatPoint)
610 {
611     return SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint);
612 }
613
614 Optional<FloatPoint> ArgumentCoder<FloatPoint>::decode(Decoder& decoder)
615 {
616     FloatPoint floatPoint;
617     if (!SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint))
618         return WTF::nullopt;
619     return floatPoint;
620 }
621
622 void ArgumentCoder<FloatPoint3D>::encode(Encoder& encoder, const FloatPoint3D& floatPoint)
623 {
624     SimpleArgumentCoder<FloatPoint3D>::encode(encoder, floatPoint);
625 }
626
627 bool ArgumentCoder<FloatPoint3D>::decode(Decoder& decoder, FloatPoint3D& floatPoint)
628 {
629     return SimpleArgumentCoder<FloatPoint3D>::decode(decoder, floatPoint);
630 }
631
632
633 void ArgumentCoder<FloatRect>::encode(Encoder& encoder, const FloatRect& floatRect)
634 {
635     SimpleArgumentCoder<FloatRect>::encode(encoder, floatRect);
636 }
637
638 bool ArgumentCoder<FloatRect>::decode(Decoder& decoder, FloatRect& floatRect)
639 {
640     return SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect);
641 }
642
643 Optional<FloatRect> ArgumentCoder<FloatRect>::decode(Decoder& decoder)
644 {
645     FloatRect floatRect;
646     if (!SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect))
647         return WTF::nullopt;
648     return floatRect;
649 }
650
651
652 void ArgumentCoder<FloatBoxExtent>::encode(Encoder& encoder, const FloatBoxExtent& floatBoxExtent)
653 {
654     SimpleArgumentCoder<FloatBoxExtent>::encode(encoder, floatBoxExtent);
655 }
656     
657 bool ArgumentCoder<FloatBoxExtent>::decode(Decoder& decoder, FloatBoxExtent& floatBoxExtent)
658 {
659     return SimpleArgumentCoder<FloatBoxExtent>::decode(decoder, floatBoxExtent);
660 }
661     
662
663 void ArgumentCoder<FloatSize>::encode(Encoder& encoder, const FloatSize& floatSize)
664 {
665     SimpleArgumentCoder<FloatSize>::encode(encoder, floatSize);
666 }
667
668 bool ArgumentCoder<FloatSize>::decode(Decoder& decoder, FloatSize& floatSize)
669 {
670     return SimpleArgumentCoder<FloatSize>::decode(decoder, floatSize);
671 }
672
673
674 void ArgumentCoder<FloatRoundedRect>::encode(Encoder& encoder, const FloatRoundedRect& roundedRect)
675 {
676     SimpleArgumentCoder<FloatRoundedRect>::encode(encoder, roundedRect);
677 }
678
679 bool ArgumentCoder<FloatRoundedRect>::decode(Decoder& decoder, FloatRoundedRect& roundedRect)
680 {
681     return SimpleArgumentCoder<FloatRoundedRect>::decode(decoder, roundedRect);
682 }
683
684 #if PLATFORM(IOS_FAMILY)
685 void ArgumentCoder<FloatQuad>::encode(Encoder& encoder, const FloatQuad& floatQuad)
686 {
687     SimpleArgumentCoder<FloatQuad>::encode(encoder, floatQuad);
688 }
689
690 Optional<FloatQuad> ArgumentCoder<FloatQuad>::decode(Decoder& decoder)
691 {
692     FloatQuad floatQuad;
693     if (!SimpleArgumentCoder<FloatQuad>::decode(decoder, floatQuad))
694         return WTF::nullopt;
695     return floatQuad;
696 }
697 #endif // PLATFORM(IOS_FAMILY)
698
699 #if ENABLE(META_VIEWPORT)
700 void ArgumentCoder<ViewportArguments>::encode(Encoder& encoder, const ViewportArguments& viewportArguments)
701 {
702     SimpleArgumentCoder<ViewportArguments>::encode(encoder, viewportArguments);
703 }
704
705 bool ArgumentCoder<ViewportArguments>::decode(Decoder& decoder, ViewportArguments& viewportArguments)
706 {
707     return SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments);
708 }
709
710 Optional<ViewportArguments> ArgumentCoder<ViewportArguments>::decode(Decoder& decoder)
711 {
712     ViewportArguments viewportArguments;
713     if (!SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments))
714         return WTF::nullopt;
715     return viewportArguments;
716 }
717
718 #endif // ENABLE(META_VIEWPORT)
719
720 void ArgumentCoder<ViewportAttributes>::encode(Encoder& encoder, const ViewportAttributes& viewportAttributes)
721 {
722     SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
723 }
724
725 bool ArgumentCoder<ViewportAttributes>::decode(Decoder& decoder, ViewportAttributes& viewportAttributes)
726 {
727     return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
728 }
729
730 void ArgumentCoder<IntPoint>::encode(Encoder& encoder, const IntPoint& intPoint)
731 {
732     SimpleArgumentCoder<IntPoint>::encode(encoder, intPoint);
733 }
734
735 bool ArgumentCoder<IntPoint>::decode(Decoder& decoder, IntPoint& intPoint)
736 {
737     return SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint);
738 }
739
740 Optional<WebCore::IntPoint> ArgumentCoder<IntPoint>::decode(Decoder& decoder)
741 {
742     IntPoint intPoint;
743     if (!SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint))
744         return WTF::nullopt;
745     return intPoint;
746 }
747
748 void ArgumentCoder<IntRect>::encode(Encoder& encoder, const IntRect& intRect)
749 {
750     SimpleArgumentCoder<IntRect>::encode(encoder, intRect);
751 }
752
753 bool ArgumentCoder<IntRect>::decode(Decoder& decoder, IntRect& intRect)
754 {
755     return SimpleArgumentCoder<IntRect>::decode(decoder, intRect);
756 }
757
758 Optional<IntRect> ArgumentCoder<IntRect>::decode(Decoder& decoder)
759 {
760     IntRect rect;
761     if (!decode(decoder, rect))
762         return WTF::nullopt;
763     return rect;
764 }
765
766 void ArgumentCoder<IntSize>::encode(Encoder& encoder, const IntSize& intSize)
767 {
768     SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
769 }
770
771 bool ArgumentCoder<IntSize>::decode(Decoder& decoder, IntSize& intSize)
772 {
773     return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
774 }
775
776 Optional<IntSize> ArgumentCoder<IntSize>::decode(Decoder& decoder)
777 {
778     IntSize intSize;
779     if (!SimpleArgumentCoder<IntSize>::decode(decoder, intSize))
780         return WTF::nullopt;
781     return intSize;
782 }
783
784 void ArgumentCoder<LayoutSize>::encode(Encoder& encoder, const LayoutSize& layoutSize)
785 {
786     SimpleArgumentCoder<LayoutSize>::encode(encoder, layoutSize);
787 }
788
789 bool ArgumentCoder<LayoutSize>::decode(Decoder& decoder, LayoutSize& layoutSize)
790 {
791     return SimpleArgumentCoder<LayoutSize>::decode(decoder, layoutSize);
792 }
793
794
795 void ArgumentCoder<LayoutPoint>::encode(Encoder& encoder, const LayoutPoint& layoutPoint)
796 {
797     SimpleArgumentCoder<LayoutPoint>::encode(encoder, layoutPoint);
798 }
799
800 bool ArgumentCoder<LayoutPoint>::decode(Decoder& decoder, LayoutPoint& layoutPoint)
801 {
802     return SimpleArgumentCoder<LayoutPoint>::decode(decoder, layoutPoint);
803 }
804
805 void ArgumentCoder<RecentSearch>::encode(Encoder& encoder, const RecentSearch& recentSearch)
806 {
807     encoder << recentSearch.string << recentSearch.time;
808 }
809
810 Optional<RecentSearch> ArgumentCoder<RecentSearch>::decode(Decoder& decoder)
811 {
812     Optional<String> string;
813     decoder >> string;
814     if (!string)
815         return WTF::nullopt;
816     
817     Optional<WallTime> time;
818     decoder >> time;
819     if (!time)
820         return WTF::nullopt;
821     
822     return {{ WTFMove(*string), WTFMove(*time) }};
823 }
824
825 void ArgumentCoder<Length>::encode(Encoder& encoder, const Length& length)
826 {
827     SimpleArgumentCoder<Length>::encode(encoder, length);
828 }
829
830 bool ArgumentCoder<Length>::decode(Decoder& decoder, Length& length)
831 {
832     return SimpleArgumentCoder<Length>::decode(decoder, length);
833 }
834
835 void ArgumentCoder<VelocityData>::encode(Encoder& encoder, const VelocityData& velocityData)
836 {
837     encoder << velocityData.horizontalVelocity << velocityData.verticalVelocity << velocityData.scaleChangeRate << velocityData.lastUpdateTime;
838 }
839
840 bool ArgumentCoder<VelocityData>::decode(Decoder& decoder, VelocityData& velocityData)
841 {
842     float horizontalVelocity;
843     if (!decoder.decode(horizontalVelocity))
844         return false;
845
846     float verticalVelocity;
847     if (!decoder.decode(verticalVelocity))
848         return false;
849
850     float scaleChangeRate;
851     if (!decoder.decode(scaleChangeRate))
852         return false;
853
854     MonotonicTime lastUpdateTime;
855     if (!decoder.decode(lastUpdateTime))
856         return false;
857
858     velocityData.horizontalVelocity = horizontalVelocity;
859     velocityData.verticalVelocity = verticalVelocity;
860     velocityData.scaleChangeRate = scaleChangeRate;
861     velocityData.lastUpdateTime = lastUpdateTime;
862
863     return true;
864 }
865
866 void ArgumentCoder<MimeClassInfo>::encode(Encoder& encoder, const MimeClassInfo& mimeClassInfo)
867 {
868     encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions;
869 }
870
871 Optional<MimeClassInfo> ArgumentCoder<MimeClassInfo>::decode(Decoder& decoder)
872 {
873     MimeClassInfo mimeClassInfo;
874     if (!decoder.decode(mimeClassInfo.type))
875         return WTF::nullopt;
876     if (!decoder.decode(mimeClassInfo.desc))
877         return WTF::nullopt;
878     if (!decoder.decode(mimeClassInfo.extensions))
879         return WTF::nullopt;
880
881     return mimeClassInfo;
882 }
883
884
885 void ArgumentCoder<PluginInfo>::encode(Encoder& encoder, const PluginInfo& pluginInfo)
886 {
887     encoder << pluginInfo.name;
888     encoder << pluginInfo.file;
889     encoder << pluginInfo.desc;
890     encoder << pluginInfo.mimes;
891     encoder << pluginInfo.isApplicationPlugin;
892     encoder.encodeEnum(pluginInfo.clientLoadPolicy);
893     encoder << pluginInfo.bundleIdentifier;
894 #if PLATFORM(MAC)
895     encoder << pluginInfo.versionString;
896 #endif
897 }
898
899 Optional<WebCore::PluginInfo> ArgumentCoder<PluginInfo>::decode(Decoder& decoder)
900 {
901     PluginInfo pluginInfo;
902     if (!decoder.decode(pluginInfo.name))
903         return WTF::nullopt;
904     if (!decoder.decode(pluginInfo.file))
905         return WTF::nullopt;
906     if (!decoder.decode(pluginInfo.desc))
907         return WTF::nullopt;
908     if (!decoder.decode(pluginInfo.mimes))
909         return WTF::nullopt;
910     if (!decoder.decode(pluginInfo.isApplicationPlugin))
911         return WTF::nullopt;
912     if (!decoder.decodeEnum(pluginInfo.clientLoadPolicy))
913         return WTF::nullopt;
914     if (!decoder.decode(pluginInfo.bundleIdentifier))
915         return WTF::nullopt;
916 #if PLATFORM(MAC)
917     if (!decoder.decode(pluginInfo.versionString))
918         return WTF::nullopt;
919 #endif
920
921     return pluginInfo;
922 }
923
924 void ArgumentCoder<AuthenticationChallenge>::encode(Encoder& encoder, const AuthenticationChallenge& challenge)
925 {
926     encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error();
927 }
928
929 bool ArgumentCoder<AuthenticationChallenge>::decode(Decoder& decoder, AuthenticationChallenge& challenge)
930 {    
931     ProtectionSpace protectionSpace;
932     if (!decoder.decode(protectionSpace))
933         return false;
934
935     Credential proposedCredential;
936     if (!decoder.decode(proposedCredential))
937         return false;
938
939     unsigned previousFailureCount;    
940     if (!decoder.decode(previousFailureCount))
941         return false;
942
943     ResourceResponse failureResponse;
944     if (!decoder.decode(failureResponse))
945         return false;
946
947     ResourceError error;
948     if (!decoder.decode(error))
949         return false;
950     
951     challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
952     return true;
953 }
954
955
956 void ArgumentCoder<ProtectionSpace>::encode(Encoder& encoder, const ProtectionSpace& space)
957 {
958     if (space.encodingRequiresPlatformData()) {
959         encoder << true;
960         encodePlatformData(encoder, space);
961         return;
962     }
963
964     encoder << false;
965     encoder << space.host() << space.port() << space.realm();
966     encoder.encodeEnum(space.authenticationScheme());
967     encoder.encodeEnum(space.serverType());
968 }
969
970 bool ArgumentCoder<ProtectionSpace>::decode(Decoder& decoder, ProtectionSpace& space)
971 {
972     bool hasPlatformData;
973     if (!decoder.decode(hasPlatformData))
974         return false;
975
976     if (hasPlatformData)
977         return decodePlatformData(decoder, space);
978
979     String host;
980     if (!decoder.decode(host))
981         return false;
982
983     int port;
984     if (!decoder.decode(port))
985         return false;
986
987     String realm;
988     if (!decoder.decode(realm))
989         return false;
990     
991     ProtectionSpaceAuthenticationScheme authenticationScheme;
992     if (!decoder.decodeEnum(authenticationScheme))
993         return false;
994
995     ProtectionSpaceServerType serverType;
996     if (!decoder.decodeEnum(serverType))
997         return false;
998
999     space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
1000     return true;
1001 }
1002
1003 void ArgumentCoder<Credential>::encode(Encoder& encoder, const Credential& credential)
1004 {
1005     if (credential.encodingRequiresPlatformData()) {
1006         encoder << true;
1007         encodePlatformData(encoder, credential);
1008         return;
1009     }
1010
1011     encoder << false;
1012     encoder << credential.user() << credential.password();
1013     encoder.encodeEnum(credential.persistence());
1014 }
1015
1016 bool ArgumentCoder<Credential>::decode(Decoder& decoder, Credential& credential)
1017 {
1018     bool hasPlatformData;
1019     if (!decoder.decode(hasPlatformData))
1020         return false;
1021
1022     if (hasPlatformData)
1023         return decodePlatformData(decoder, credential);
1024
1025     String user;
1026     if (!decoder.decode(user))
1027         return false;
1028
1029     String password;
1030     if (!decoder.decode(password))
1031         return false;
1032
1033     CredentialPersistence persistence;
1034     if (!decoder.decodeEnum(persistence))
1035         return false;
1036     
1037     credential = Credential(user, password, persistence);
1038     return true;
1039 }
1040
1041 static void encodeImage(Encoder& encoder, Image& image)
1042 {
1043     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(image.size()), { });
1044     auto graphicsContext = bitmap->createGraphicsContext();
1045     encoder << !!graphicsContext;
1046     if (!graphicsContext)
1047         return;
1048
1049     graphicsContext->drawImage(image, IntPoint());
1050
1051     ShareableBitmap::Handle handle;
1052     bitmap->createHandle(handle);
1053
1054     encoder << handle;
1055 }
1056
1057 static WARN_UNUSED_RETURN bool decodeImage(Decoder& decoder, RefPtr<Image>& image)
1058 {
1059     Optional<bool> didCreateGraphicsContext;
1060     decoder >> didCreateGraphicsContext;
1061     if (!didCreateGraphicsContext.hasValue() || !didCreateGraphicsContext.value())
1062         return false;
1063
1064     ShareableBitmap::Handle handle;
1065     if (!decoder.decode(handle))
1066         return false;
1067     
1068     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
1069     if (!bitmap)
1070         return false;
1071     image = bitmap->createImage();
1072     if (!image)
1073         return false;
1074     return true;
1075 }
1076
1077 static void encodeOptionalImage(Encoder& encoder, Image* image)
1078 {
1079     bool hasImage = !!image;
1080     encoder << hasImage;
1081
1082     if (hasImage)
1083         encodeImage(encoder, *image);
1084 }
1085
1086 static WARN_UNUSED_RETURN bool decodeOptionalImage(Decoder& decoder, RefPtr<Image>& image)
1087 {
1088     image = nullptr;
1089
1090     bool hasImage;
1091     if (!decoder.decode(hasImage))
1092         return false;
1093
1094     if (!hasImage)
1095         return true;
1096
1097     return decodeImage(decoder, image);
1098 }
1099
1100 void ArgumentCoder<ImageHandle>::encode(Encoder& encoder, const ImageHandle& imageHandle)
1101 {
1102     encodeOptionalImage(encoder, imageHandle.image.get());
1103 }
1104
1105 bool ArgumentCoder<ImageHandle>::decode(Decoder& decoder, ImageHandle& imageHandle)
1106 {
1107     if (!decodeOptionalImage(decoder, imageHandle.image))
1108         return false;
1109     return true;
1110 }
1111
1112 static void encodeNativeImage(Encoder& encoder, NativeImagePtr image)
1113 {
1114     auto imageSize = nativeImageSize(image);
1115     auto bitmap = ShareableBitmap::createShareable(imageSize, { });
1116     auto graphicsContext = bitmap->createGraphicsContext();
1117     encoder << !!graphicsContext;
1118     if (!graphicsContext)
1119         return;
1120
1121     graphicsContext->drawNativeImage(image, imageSize, FloatRect({ }, imageSize), FloatRect({ }, imageSize));
1122
1123     ShareableBitmap::Handle handle;
1124     bitmap->createHandle(handle);
1125
1126     encoder << handle;
1127 }
1128
1129 static WARN_UNUSED_RETURN bool decodeNativeImage(Decoder& decoder, NativeImagePtr& nativeImage)
1130 {
1131     Optional<bool> didCreateGraphicsContext;
1132     decoder >> didCreateGraphicsContext;
1133     if (!didCreateGraphicsContext.hasValue() || !didCreateGraphicsContext.value())
1134         return false;
1135
1136     ShareableBitmap::Handle handle;
1137     if (!decoder.decode(handle))
1138         return false;
1139
1140     auto bitmap = ShareableBitmap::create(handle);
1141     if (!bitmap)
1142         return false;
1143
1144     auto image = bitmap->createImage();
1145     if (!image)
1146         return false;
1147
1148     nativeImage = image->nativeImage();
1149     if (!nativeImage)
1150         return false;
1151
1152     return true;
1153 }
1154
1155 static void encodeOptionalNativeImage(Encoder& encoder, NativeImagePtr image)
1156 {
1157     bool hasImage = !!image;
1158     encoder << hasImage;
1159
1160     if (hasImage)
1161         encodeNativeImage(encoder, image);
1162 }
1163
1164 static WARN_UNUSED_RETURN bool decodeOptionalNativeImage(Decoder& decoder, NativeImagePtr& image)
1165 {
1166     image = nullptr;
1167
1168     bool hasImage;
1169     if (!decoder.decode(hasImage))
1170         return false;
1171
1172     if (!hasImage)
1173         return true;
1174
1175     return decodeNativeImage(decoder, image);
1176 }
1177
1178 void ArgumentCoder<NativeImageHandle>::encode(Encoder& encoder, const NativeImageHandle& imageHandle)
1179 {
1180     encodeOptionalNativeImage(encoder, imageHandle.image.get());
1181 }
1182
1183 bool ArgumentCoder<NativeImageHandle>::decode(Decoder& decoder, NativeImageHandle& imageHandle)
1184 {
1185     return decodeOptionalNativeImage(decoder, imageHandle.image);
1186 }
1187
1188 void ArgumentCoder<FontHandle>::encode(Encoder& encoder, const FontHandle& handle)
1189 {
1190     encoder << !!handle.font;
1191     if (!handle.font)
1192         return;
1193
1194     auto* fontFaceData = handle.font->fontFaceData();
1195     encoder << !!fontFaceData;
1196     if (fontFaceData) {
1197         encodeSharedBuffer(encoder, fontFaceData);
1198         auto& data = handle.font->platformData();
1199         encoder << data.size();
1200         encoder << data.syntheticBold();
1201         encoder << data.syntheticOblique();
1202     }
1203
1204     encodePlatformData(encoder, handle);
1205 }
1206
1207 bool ArgumentCoder<FontHandle>::decode(Decoder& decoder, FontHandle& handle)
1208 {
1209     Optional<bool> hasFont;
1210     decoder >> hasFont;
1211     if (!hasFont.hasValue())
1212         return false;
1213
1214     if (!hasFont.value())
1215         return true;
1216
1217     Optional<bool> hasFontFaceData;
1218     decoder >> hasFontFaceData;
1219     if (!hasFontFaceData.hasValue())
1220         return false;
1221
1222     if (hasFontFaceData.value()) {
1223         RefPtr<SharedBuffer> fontFaceData;
1224         if (!decodeSharedBuffer(decoder, fontFaceData))
1225             return false;
1226
1227         if (!fontFaceData)
1228             return false;
1229
1230         Optional<float> fontSize;
1231         decoder >> fontSize;
1232         if (!fontSize)
1233             return false;
1234
1235         Optional<bool> syntheticBold;
1236         decoder >> syntheticBold;
1237         if (!syntheticBold)
1238             return false;
1239
1240         Optional<bool> syntheticItalic;
1241         decoder >> syntheticItalic;
1242         if (!syntheticItalic)
1243             return false;
1244
1245         FontDescription description;
1246         description.setComputedSize(*fontSize);
1247         handle = { fontFaceData.releaseNonNull(), Font::Origin::Remote, *fontSize, *syntheticBold, *syntheticItalic };
1248     }
1249
1250     return decodePlatformData(decoder, handle);
1251 }
1252
1253 void ArgumentCoder<Cursor>::encode(Encoder& encoder, const Cursor& cursor)
1254 {
1255     encoder.encodeEnum(cursor.type());
1256         
1257     if (cursor.type() != Cursor::Custom)
1258         return;
1259
1260     if (cursor.image()->isNull()) {
1261         encoder << false; // There is no valid image being encoded.
1262         return;
1263     }
1264
1265     encoder << true;
1266     encodeImage(encoder, *cursor.image());
1267     encoder << cursor.hotSpot();
1268 #if ENABLE(MOUSE_CURSOR_SCALE)
1269     encoder << cursor.imageScaleFactor();
1270 #endif
1271 }
1272
1273 bool ArgumentCoder<Cursor>::decode(Decoder& decoder, Cursor& cursor)
1274 {
1275     Cursor::Type type;
1276     if (!decoder.decodeEnum(type))
1277         return false;
1278
1279     if (type > Cursor::Custom)
1280         return false;
1281
1282     if (type != Cursor::Custom) {
1283         const Cursor& cursorReference = Cursor::fromType(type);
1284         // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
1285         // This will avoid having to re-create the platform cursors over and over.
1286         (void)cursorReference.platformCursor();
1287
1288         cursor = cursorReference;
1289         return true;
1290     }
1291
1292     bool isValidImagePresent;
1293     if (!decoder.decode(isValidImagePresent))
1294         return false;
1295
1296     if (!isValidImagePresent) {
1297         cursor = Cursor(&Image::nullImage(), IntPoint());
1298         return true;
1299     }
1300
1301     RefPtr<Image> image;
1302     if (!decodeImage(decoder, image))
1303         return false;
1304
1305     IntPoint hotSpot;
1306     if (!decoder.decode(hotSpot))
1307         return false;
1308
1309     if (!image->rect().contains(hotSpot))
1310         return false;
1311
1312 #if ENABLE(MOUSE_CURSOR_SCALE)
1313     float scale;
1314     if (!decoder.decode(scale))
1315         return false;
1316
1317     cursor = Cursor(image.get(), hotSpot, scale);
1318 #else
1319     cursor = Cursor(image.get(), hotSpot);
1320 #endif
1321     return true;
1322 }
1323
1324 void ArgumentCoder<ResourceRequest>::encode(Encoder& encoder, const ResourceRequest& resourceRequest)
1325 {
1326     encoder << resourceRequest.cachePartition();
1327     encoder << resourceRequest.hiddenFromInspector();
1328
1329 #if USE(SYSTEM_PREVIEW)
1330     if (resourceRequest.isSystemPreview()) {
1331         encoder << true;
1332         encoder << resourceRequest.systemPreviewInfo();
1333     } else
1334         encoder << false;
1335 #endif
1336
1337     if (resourceRequest.encodingRequiresPlatformData()) {
1338         encoder << true;
1339         encodePlatformData(encoder, resourceRequest);
1340         return;
1341     }
1342     encoder << false;
1343     resourceRequest.encodeWithoutPlatformData(encoder);
1344 }
1345
1346 bool ArgumentCoder<ResourceRequest>::decode(Decoder& decoder, ResourceRequest& resourceRequest)
1347 {
1348     String cachePartition;
1349     if (!decoder.decode(cachePartition))
1350         return false;
1351     resourceRequest.setCachePartition(cachePartition);
1352
1353     bool isHiddenFromInspector;
1354     if (!decoder.decode(isHiddenFromInspector))
1355         return false;
1356     resourceRequest.setHiddenFromInspector(isHiddenFromInspector);
1357
1358 #if USE(SYSTEM_PREVIEW)
1359     bool isSystemPreview;
1360     if (!decoder.decode(isSystemPreview))
1361         return false;
1362
1363     if (isSystemPreview) {
1364         SystemPreviewInfo systemPreviewInfo;
1365         if (!decoder.decode(systemPreviewInfo))
1366             return false;
1367         resourceRequest.setSystemPreviewInfo(systemPreviewInfo);
1368     }
1369 #endif
1370
1371     bool hasPlatformData;
1372     if (!decoder.decode(hasPlatformData))
1373         return false;
1374     if (hasPlatformData)
1375         return decodePlatformData(decoder, resourceRequest);
1376
1377     return resourceRequest.decodeWithoutPlatformData(decoder);
1378 }
1379
1380 void ArgumentCoder<ResourceError>::encode(Encoder& encoder, const ResourceError& resourceError)
1381 {
1382     encoder.encodeEnum(resourceError.type());
1383     if (resourceError.type() == ResourceError::Type::Null)
1384         return;
1385     encodePlatformData(encoder, resourceError);
1386 }
1387
1388 bool ArgumentCoder<ResourceError>::decode(Decoder& decoder, ResourceError& resourceError)
1389 {
1390     ResourceError::Type type;
1391     if (!decoder.decodeEnum(type))
1392         return false;
1393
1394     if (type == ResourceError::Type::Null) {
1395         resourceError = { };
1396         return true;
1397     }
1398
1399     if (!decodePlatformData(decoder, resourceError))
1400         return false;
1401
1402     resourceError.setType(type);
1403     return true;
1404 }
1405
1406 #if PLATFORM(IOS_FAMILY)
1407
1408 void ArgumentCoder<SelectionRect>::encode(Encoder& encoder, const SelectionRect& selectionRect)
1409 {
1410     encoder << selectionRect.rect();
1411     encoder << static_cast<uint32_t>(selectionRect.direction());
1412     encoder << selectionRect.minX();
1413     encoder << selectionRect.maxX();
1414     encoder << selectionRect.maxY();
1415     encoder << selectionRect.lineNumber();
1416     encoder << selectionRect.isLineBreak();
1417     encoder << selectionRect.isFirstOnLine();
1418     encoder << selectionRect.isLastOnLine();
1419     encoder << selectionRect.containsStart();
1420     encoder << selectionRect.containsEnd();
1421     encoder << selectionRect.isHorizontal();
1422 }
1423
1424 Optional<SelectionRect> ArgumentCoder<SelectionRect>::decode(Decoder& decoder)
1425 {
1426     SelectionRect selectionRect;
1427     IntRect rect;
1428     if (!decoder.decode(rect))
1429         return WTF::nullopt;
1430     selectionRect.setRect(rect);
1431
1432     uint32_t direction;
1433     if (!decoder.decode(direction))
1434         return WTF::nullopt;
1435     selectionRect.setDirection((TextDirection)direction);
1436
1437     int intValue;
1438     if (!decoder.decode(intValue))
1439         return WTF::nullopt;
1440     selectionRect.setMinX(intValue);
1441
1442     if (!decoder.decode(intValue))
1443         return WTF::nullopt;
1444     selectionRect.setMaxX(intValue);
1445
1446     if (!decoder.decode(intValue))
1447         return WTF::nullopt;
1448     selectionRect.setMaxY(intValue);
1449
1450     if (!decoder.decode(intValue))
1451         return WTF::nullopt;
1452     selectionRect.setLineNumber(intValue);
1453
1454     bool boolValue;
1455     if (!decoder.decode(boolValue))
1456         return WTF::nullopt;
1457     selectionRect.setIsLineBreak(boolValue);
1458
1459     if (!decoder.decode(boolValue))
1460         return WTF::nullopt;
1461     selectionRect.setIsFirstOnLine(boolValue);
1462
1463     if (!decoder.decode(boolValue))
1464         return WTF::nullopt;
1465     selectionRect.setIsLastOnLine(boolValue);
1466
1467     if (!decoder.decode(boolValue))
1468         return WTF::nullopt;
1469     selectionRect.setContainsStart(boolValue);
1470
1471     if (!decoder.decode(boolValue))
1472         return WTF::nullopt;
1473     selectionRect.setContainsEnd(boolValue);
1474
1475     if (!decoder.decode(boolValue))
1476         return WTF::nullopt;
1477     selectionRect.setIsHorizontal(boolValue);
1478
1479     return selectionRect;
1480 }
1481
1482 #endif
1483
1484 void ArgumentCoder<WindowFeatures>::encode(Encoder& encoder, const WindowFeatures& windowFeatures)
1485 {
1486     encoder << windowFeatures.x;
1487     encoder << windowFeatures.y;
1488     encoder << windowFeatures.width;
1489     encoder << windowFeatures.height;
1490     encoder << windowFeatures.menuBarVisible;
1491     encoder << windowFeatures.statusBarVisible;
1492     encoder << windowFeatures.toolBarVisible;
1493     encoder << windowFeatures.locationBarVisible;
1494     encoder << windowFeatures.scrollbarsVisible;
1495     encoder << windowFeatures.resizable;
1496     encoder << windowFeatures.fullscreen;
1497     encoder << windowFeatures.dialog;
1498 }
1499
1500 bool ArgumentCoder<WindowFeatures>::decode(Decoder& decoder, WindowFeatures& windowFeatures)
1501 {
1502     if (!decoder.decode(windowFeatures.x))
1503         return false;
1504     if (!decoder.decode(windowFeatures.y))
1505         return false;
1506     if (!decoder.decode(windowFeatures.width))
1507         return false;
1508     if (!decoder.decode(windowFeatures.height))
1509         return false;
1510     if (!decoder.decode(windowFeatures.menuBarVisible))
1511         return false;
1512     if (!decoder.decode(windowFeatures.statusBarVisible))
1513         return false;
1514     if (!decoder.decode(windowFeatures.toolBarVisible))
1515         return false;
1516     if (!decoder.decode(windowFeatures.locationBarVisible))
1517         return false;
1518     if (!decoder.decode(windowFeatures.scrollbarsVisible))
1519         return false;
1520     if (!decoder.decode(windowFeatures.resizable))
1521         return false;
1522     if (!decoder.decode(windowFeatures.fullscreen))
1523         return false;
1524     if (!decoder.decode(windowFeatures.dialog))
1525         return false;
1526     return true;
1527 }
1528
1529 #if ENABLE(DRAG_SUPPORT)
1530 void ArgumentCoder<DragData>::encode(Encoder& encoder, const DragData& dragData)
1531 {
1532     encoder << dragData.clientPosition();
1533     encoder << dragData.globalPosition();
1534     encoder.encodeEnum(dragData.draggingSourceOperationMask());
1535     encoder.encodeEnum(dragData.flags());
1536 #if PLATFORM(COCOA)
1537     encoder << dragData.pasteboardName();
1538     encoder << dragData.fileNames();
1539 #endif
1540     encoder.encodeEnum(dragData.dragDestinationAction());
1541 }
1542
1543 bool ArgumentCoder<DragData>::decode(Decoder& decoder, DragData& dragData)
1544 {
1545     IntPoint clientPosition;
1546     if (!decoder.decode(clientPosition))
1547         return false;
1548
1549     IntPoint globalPosition;
1550     if (!decoder.decode(globalPosition))
1551         return false;
1552
1553     DragOperation draggingSourceOperationMask;
1554     if (!decoder.decodeEnum(draggingSourceOperationMask))
1555         return false;
1556
1557     DragApplicationFlags applicationFlags;
1558     if (!decoder.decodeEnum(applicationFlags))
1559         return false;
1560
1561     String pasteboardName;
1562     Vector<String> fileNames;
1563 #if PLATFORM(COCOA)
1564     if (!decoder.decode(pasteboardName))
1565         return false;
1566
1567     if (!decoder.decode(fileNames))
1568         return false;
1569 #endif
1570
1571     DragDestinationAction destinationAction;
1572     if (!decoder.decodeEnum(destinationAction))
1573         return false;
1574
1575     dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags, destinationAction);
1576     dragData.setFileNames(fileNames);
1577
1578     return true;
1579 }
1580 #endif
1581
1582 void ArgumentCoder<CompositionUnderline>::encode(Encoder& encoder, const CompositionUnderline& underline)
1583 {
1584     encoder << underline.startOffset;
1585     encoder << underline.endOffset;
1586     encoder << underline.thick;
1587     encoder.encodeEnum(underline.compositionUnderlineColor);
1588     encoder << underline.color;
1589 }
1590
1591 Optional<CompositionUnderline> ArgumentCoder<CompositionUnderline>::decode(Decoder& decoder)
1592 {
1593     CompositionUnderline underline;
1594
1595     if (!decoder.decode(underline.startOffset))
1596         return WTF::nullopt;
1597     if (!decoder.decode(underline.endOffset))
1598         return WTF::nullopt;
1599     if (!decoder.decode(underline.thick))
1600         return WTF::nullopt;
1601     if (!decoder.decodeEnum(underline.compositionUnderlineColor))
1602         return WTF::nullopt;
1603     if (!decoder.decode(underline.color))
1604         return WTF::nullopt;
1605
1606     return underline;
1607 }
1608
1609 void ArgumentCoder<DatabaseDetails>::encode(Encoder& encoder, const DatabaseDetails& details)
1610 {
1611     encoder << details.name();
1612     encoder << details.displayName();
1613     encoder << details.expectedUsage();
1614     encoder << details.currentUsage();
1615     encoder << details.creationTime();
1616     encoder << details.modificationTime();
1617 }
1618     
1619 bool ArgumentCoder<DatabaseDetails>::decode(Decoder& decoder, DatabaseDetails& details)
1620 {
1621     String name;
1622     if (!decoder.decode(name))
1623         return false;
1624
1625     String displayName;
1626     if (!decoder.decode(displayName))
1627         return false;
1628
1629     uint64_t expectedUsage;
1630     if (!decoder.decode(expectedUsage))
1631         return false;
1632
1633     uint64_t currentUsage;
1634     if (!decoder.decode(currentUsage))
1635         return false;
1636
1637     Optional<WallTime> creationTime;
1638     if (!decoder.decode(creationTime))
1639         return false;
1640
1641     Optional<WallTime> modificationTime;
1642     if (!decoder.decode(modificationTime))
1643         return false;
1644
1645     details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime);
1646     return true;
1647 }
1648
1649 template<> struct ArgumentCoder<PasteboardCustomData::Entry> {
1650     static void encode(Encoder&, const PasteboardCustomData::Entry&);
1651     static WARN_UNUSED_RETURN bool decode(Decoder&, PasteboardCustomData::Entry&);
1652 };
1653
1654 void ArgumentCoder<PasteboardCustomData::Entry>::encode(Encoder& encoder, const PasteboardCustomData::Entry& data)
1655 {
1656     encoder << data.type << data.customData;
1657
1658     auto& platformData = data.platformData;
1659     bool hasString = WTF::holds_alternative<String>(platformData);
1660     encoder << hasString;
1661     if (hasString)
1662         encoder << WTF::get<String>(platformData);
1663
1664     bool hasBuffer = WTF::holds_alternative<Ref<SharedBuffer>>(platformData);
1665     encoder << hasBuffer;
1666     if (hasBuffer)
1667         encodeSharedBuffer(encoder, WTF::get<Ref<SharedBuffer>>(platformData).ptr());
1668 }
1669
1670 bool ArgumentCoder<PasteboardCustomData::Entry>::decode(Decoder& decoder, PasteboardCustomData::Entry& data)
1671 {
1672     if (!decoder.decode(data.type))
1673         return false;
1674
1675     if (!decoder.decode(data.customData))
1676         return false;
1677
1678     bool hasString;
1679     if (!decoder.decode(hasString))
1680         return false;
1681
1682     if (hasString) {
1683         String value;
1684         if (!decoder.decode(value))
1685             return false;
1686         data.platformData = { WTFMove(value) };
1687     }
1688
1689     bool hasBuffer;
1690     if (!decoder.decode(hasBuffer))
1691         return false;
1692
1693     if (hasString && hasBuffer)
1694         return false;
1695
1696     if (hasBuffer) {
1697         RefPtr<SharedBuffer> value;
1698         if (!decodeSharedBuffer(decoder, value))
1699             return false;
1700         data.platformData = { value.releaseNonNull() };
1701     }
1702
1703     return true;
1704 }
1705
1706 void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
1707 {
1708     encoder << data.origin();
1709     encoder << data.data();
1710 }
1711
1712 bool ArgumentCoder<PasteboardCustomData>::decode(Decoder& decoder, PasteboardCustomData& data)
1713 {
1714     String origin;
1715     if (!decoder.decode(origin))
1716         return false;
1717
1718     Vector<PasteboardCustomData::Entry> items;
1719     if (!decoder.decode(items))
1720         return false;
1721
1722     data = PasteboardCustomData(WTFMove(origin), WTFMove(items));
1723     return true;
1724 }
1725
1726 void ArgumentCoder<PasteboardURL>::encode(Encoder& encoder, const PasteboardURL& content)
1727 {
1728     encoder << content.url;
1729     encoder << content.title;
1730 #if PLATFORM(MAC)
1731     encoder << content.userVisibleForm;
1732 #endif
1733 #if PLATFORM(GTK)
1734     encoder << content.markup;
1735 #endif
1736 }
1737
1738 bool ArgumentCoder<PasteboardURL>::decode(Decoder& decoder, PasteboardURL& content)
1739 {
1740     if (!decoder.decode(content.url))
1741         return false;
1742
1743     if (!decoder.decode(content.title))
1744         return false;
1745
1746 #if PLATFORM(MAC)
1747     if (!decoder.decode(content.userVisibleForm))
1748         return false;
1749 #endif
1750 #if PLATFORM(GTK)
1751     if (!decoder.decode(content.markup))
1752         return false;
1753 #endif
1754
1755     return true;
1756 }
1757
1758 #if PLATFORM(IOS_FAMILY)
1759
1760 void ArgumentCoder<Highlight>::encode(Encoder& encoder, const Highlight& highlight)
1761 {
1762     encoder << static_cast<uint32_t>(highlight.type);
1763     encoder << highlight.usePageCoordinates;
1764     encoder << highlight.contentColor;
1765     encoder << highlight.contentOutlineColor;
1766     encoder << highlight.paddingColor;
1767     encoder << highlight.borderColor;
1768     encoder << highlight.marginColor;
1769     encoder << highlight.quads;
1770 }
1771
1772 bool ArgumentCoder<Highlight>::decode(Decoder& decoder, Highlight& highlight)
1773 {
1774     uint32_t type;
1775     if (!decoder.decode(type))
1776         return false;
1777     highlight.type = (HighlightType)type;
1778
1779     if (!decoder.decode(highlight.usePageCoordinates))
1780         return false;
1781     if (!decoder.decode(highlight.contentColor))
1782         return false;
1783     if (!decoder.decode(highlight.contentOutlineColor))
1784         return false;
1785     if (!decoder.decode(highlight.paddingColor))
1786         return false;
1787     if (!decoder.decode(highlight.borderColor))
1788         return false;
1789     if (!decoder.decode(highlight.marginColor))
1790         return false;
1791     if (!decoder.decode(highlight.quads))
1792         return false;
1793     return true;
1794 }
1795
1796 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1797 {
1798     encoder << content.contentOrigin;
1799     encoder << content.canSmartCopyOrDelete;
1800     encoder << content.dataInStringFormat;
1801     encoder << content.dataInHTMLFormat;
1802
1803     encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get());
1804     encodeSharedBuffer(encoder, content.dataInRTFDFormat.get());
1805     encodeSharedBuffer(encoder, content.dataInRTFFormat.get());
1806     encodeSharedBuffer(encoder, content.dataInAttributedStringFormat.get());
1807
1808     encodeTypesAndData(encoder, content.clientTypes, content.clientData);
1809 }
1810
1811 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1812 {
1813     if (!decoder.decode(content.contentOrigin))
1814         return false;
1815     if (!decoder.decode(content.canSmartCopyOrDelete))
1816         return false;
1817     if (!decoder.decode(content.dataInStringFormat))
1818         return false;
1819     if (!decoder.decode(content.dataInHTMLFormat))
1820         return false;
1821     if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat))
1822         return false;
1823     if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat))
1824         return false;
1825     if (!decodeSharedBuffer(decoder, content.dataInRTFFormat))
1826         return false;
1827     if (!decodeSharedBuffer(decoder, content.dataInAttributedStringFormat))
1828         return false;
1829     if (!decodeTypesAndData(decoder, content.clientTypes, content.clientData))
1830         return false;
1831     return true;
1832 }
1833
1834 void ArgumentCoder<PasteboardImage>::encode(Encoder& encoder, const PasteboardImage& pasteboardImage)
1835 {
1836     encodeOptionalImage(encoder, pasteboardImage.image.get());
1837     encoder << pasteboardImage.url.url;
1838     encoder << pasteboardImage.url.title;
1839     encoder << pasteboardImage.resourceMIMEType;
1840     encoder << pasteboardImage.suggestedName;
1841     encoder << pasteboardImage.imageSize;
1842     if (pasteboardImage.resourceData)
1843         encodeSharedBuffer(encoder, pasteboardImage.resourceData.get());
1844     encodeTypesAndData(encoder, pasteboardImage.clientTypes, pasteboardImage.clientData);
1845 }
1846
1847 bool ArgumentCoder<PasteboardImage>::decode(Decoder& decoder, PasteboardImage& pasteboardImage)
1848 {
1849     if (!decodeOptionalImage(decoder, pasteboardImage.image))
1850         return false;
1851     if (!decoder.decode(pasteboardImage.url.url))
1852         return false;
1853     if (!decoder.decode(pasteboardImage.url.title))
1854         return false;
1855     if (!decoder.decode(pasteboardImage.resourceMIMEType))
1856         return false;
1857     if (!decoder.decode(pasteboardImage.suggestedName))
1858         return false;
1859     if (!decoder.decode(pasteboardImage.imageSize))
1860         return false;
1861     if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData))
1862         return false;
1863     if (!decodeTypesAndData(decoder, pasteboardImage.clientTypes, pasteboardImage.clientData))
1864         return false;
1865     return true;
1866 }
1867
1868 #endif
1869
1870 #if USE(LIBWPE)
1871 void ArgumentCoder<PasteboardWebContent>::encode(Encoder& encoder, const PasteboardWebContent& content)
1872 {
1873     encoder << content.text;
1874     encoder << content.markup;
1875 }
1876
1877 bool ArgumentCoder<PasteboardWebContent>::decode(Decoder& decoder, PasteboardWebContent& content)
1878 {
1879     if (!decoder.decode(content.text))
1880         return false;
1881     if (!decoder.decode(content.markup))
1882         return false;
1883     return true;
1884 }
1885 #endif // USE(LIBWPE)
1886
1887 void ArgumentCoder<DictationAlternative>::encode(Encoder& encoder, const DictationAlternative& alternative)
1888 {
1889     encoder << alternative.range << alternative.context;
1890 }
1891
1892 Optional<DictationAlternative> ArgumentCoder<DictationAlternative>::decode(Decoder& decoder)
1893 {
1894     Optional<CharacterRange> range;
1895     decoder >> range;
1896     if (!range)
1897         return WTF::nullopt;
1898
1899     Optional<DictationContext> context;
1900     decoder >> context;
1901     if (!context)
1902         return WTF::nullopt;
1903
1904     return {{ *range, *context }};
1905 }
1906
1907 void ArgumentCoder<FileChooserSettings>::encode(Encoder& encoder, const FileChooserSettings& settings)
1908 {
1909     encoder << settings.allowsDirectories;
1910     encoder << settings.allowsMultipleFiles;
1911     encoder << settings.acceptMIMETypes;
1912     encoder << settings.acceptFileExtensions;
1913     encoder << settings.selectedFiles;
1914 #if ENABLE(MEDIA_CAPTURE)
1915     encoder.encodeEnum(settings.mediaCaptureType);
1916 #endif
1917 }
1918
1919 bool ArgumentCoder<FileChooserSettings>::decode(Decoder& decoder, FileChooserSettings& settings)
1920 {
1921     if (!decoder.decode(settings.allowsDirectories))
1922         return false;
1923     if (!decoder.decode(settings.allowsMultipleFiles))
1924         return false;
1925     if (!decoder.decode(settings.acceptMIMETypes))
1926         return false;
1927     if (!decoder.decode(settings.acceptFileExtensions))
1928         return false;
1929     if (!decoder.decode(settings.selectedFiles))
1930         return false;
1931 #if ENABLE(MEDIA_CAPTURE)
1932     if (!decoder.decodeEnum(settings.mediaCaptureType))
1933         return false;
1934 #endif
1935
1936     return true;
1937 }
1938
1939 void ArgumentCoder<RawFile>::encode(Encoder& encoder, const RawFile& file)
1940 {
1941     encoder << file.fileName;
1942     encodeSharedBuffer(encoder, file.fileData.get());
1943 }
1944
1945 bool ArgumentCoder<RawFile>::decode(Decoder& decoder, RawFile& file)
1946 {
1947     if (!decoder.decode(file.fileName))
1948         return false;
1949     if (!decodeSharedBuffer(decoder, file.fileData))
1950         return false;
1951     return true;
1952 }
1953     
1954 void ArgumentCoder<ShareData>::encode(Encoder& encoder, const ShareData& settings)
1955 {
1956     encoder << settings.title;
1957     encoder << settings.text;
1958     encoder << settings.url;
1959 }
1960
1961 bool ArgumentCoder<ShareData>::decode(Decoder& decoder, ShareData& settings)
1962 {
1963     if (!decoder.decode(settings.title))
1964         return false;
1965     if (!decoder.decode(settings.text))
1966         return false;
1967     if (!decoder.decode(settings.url))
1968         return false;
1969     return true;
1970 }
1971     
1972 void ArgumentCoder<ShareDataWithParsedURL>::encode(Encoder& encoder, const ShareDataWithParsedURL& settings)
1973 {
1974     encoder << settings.shareData;
1975     encoder << settings.url;
1976     encoder << settings.files;
1977 }
1978
1979 bool ArgumentCoder<ShareDataWithParsedURL>::decode(Decoder& decoder, ShareDataWithParsedURL& settings)
1980 {
1981     if (!decoder.decode(settings.shareData))
1982         return false;
1983     if (!decoder.decode(settings.url))
1984         return false;
1985     if (!decoder.decode(settings.files))
1986         return false;
1987     return true;
1988 }
1989
1990 void ArgumentCoder<GrammarDetail>::encode(Encoder& encoder, const GrammarDetail& detail)
1991 {
1992     encoder << detail.range;
1993     encoder << detail.guesses;
1994     encoder << detail.userDescription;
1995 }
1996
1997 Optional<GrammarDetail> ArgumentCoder<GrammarDetail>::decode(Decoder& decoder)
1998 {
1999     Optional<CharacterRange> range;
2000     decoder >> range;
2001     if (!range)
2002         return WTF::nullopt;
2003
2004     Optional<Vector<String>> guesses;
2005     decoder >> guesses;
2006     if (!guesses)
2007         return WTF::nullopt;
2008
2009     Optional<String> userDescription;
2010     decoder >> userDescription;
2011     if (!userDescription)
2012         return WTF::nullopt;
2013
2014     return { { *range, WTFMove(*guesses), WTFMove(*userDescription) } };
2015 }
2016
2017 void ArgumentCoder<TextCheckingRequestData>::encode(Encoder& encoder, const TextCheckingRequestData& request)
2018 {
2019     encoder << request.identifier();
2020     encoder << request.text();
2021     encoder << request.checkingTypes();
2022     encoder.encodeEnum(request.processType());
2023 }
2024
2025 bool ArgumentCoder<TextCheckingRequestData>::decode(Decoder& decoder, TextCheckingRequestData& request)
2026 {
2027     Optional<TextCheckingRequestIdentifier> identifier;
2028     if (!decoder.decode(identifier))
2029         return false;
2030
2031     String text;
2032     if (!decoder.decode(text))
2033         return false;
2034
2035     OptionSet<TextCheckingType> checkingTypes;
2036     if (!decoder.decode(checkingTypes))
2037         return false;
2038
2039     TextCheckingProcessType processType;
2040     if (!decoder.decodeEnum(processType))
2041         return false;
2042
2043     request = TextCheckingRequestData { identifier, text, checkingTypes, processType };
2044     return true;
2045 }
2046
2047 void ArgumentCoder<TextCheckingResult>::encode(Encoder& encoder, const TextCheckingResult& result)
2048 {
2049     encoder.encodeEnum(result.type);
2050     encoder << result.range;
2051     encoder << result.details;
2052     encoder << result.replacement;
2053 }
2054
2055 Optional<TextCheckingResult> ArgumentCoder<TextCheckingResult>::decode(Decoder& decoder)
2056 {
2057     TextCheckingType type;
2058     if (!decoder.decodeEnum(type))
2059         return WTF::nullopt;
2060     
2061     Optional<CharacterRange> range;
2062     decoder >> range;
2063     if (!range)
2064         return WTF::nullopt;
2065
2066     Optional<Vector<GrammarDetail>> details;
2067     decoder >> details;
2068     if (!details)
2069         return WTF::nullopt;
2070
2071     Optional<String> replacement;
2072     decoder >> replacement;
2073     if (!replacement)
2074         return WTF::nullopt;
2075
2076     return { { type, *range, WTFMove(*details), WTFMove(*replacement) } };
2077 }
2078
2079 void ArgumentCoder<UserStyleSheet>::encode(Encoder& encoder, const UserStyleSheet& userStyleSheet)
2080 {
2081     encoder << userStyleSheet.source();
2082     encoder << userStyleSheet.url();
2083     encoder << userStyleSheet.whitelist();
2084     encoder << userStyleSheet.blacklist();
2085     encoder.encodeEnum(userStyleSheet.injectedFrames());
2086     encoder.encodeEnum(userStyleSheet.level());
2087     encoder << userStyleSheet.pageID();
2088 }
2089
2090 bool ArgumentCoder<UserStyleSheet>::decode(Decoder& decoder, UserStyleSheet& userStyleSheet)
2091 {
2092     String source;
2093     if (!decoder.decode(source))
2094         return false;
2095
2096     URL url;
2097     if (!decoder.decode(url))
2098         return false;
2099
2100     Vector<String> whitelist;
2101     if (!decoder.decode(whitelist))
2102         return false;
2103
2104     Vector<String> blacklist;
2105     if (!decoder.decode(blacklist))
2106         return false;
2107
2108     UserContentInjectedFrames injectedFrames;
2109     if (!decoder.decodeEnum(injectedFrames))
2110         return false;
2111
2112     UserStyleLevel level;
2113     if (!decoder.decodeEnum(level))
2114         return false;
2115
2116     Optional<Optional<PageIdentifier>> pageID;
2117     decoder >> pageID;
2118     if (!pageID)
2119         return false;
2120
2121     userStyleSheet = UserStyleSheet(source, url, WTFMove(whitelist), WTFMove(blacklist), injectedFrames, level, WTFMove(*pageID));
2122     return true;
2123 }
2124
2125 #if ENABLE(MEDIA_SESSION)
2126 void ArgumentCoder<MediaSessionMetadata>::encode(Encoder& encoder, const MediaSessionMetadata& result)
2127 {
2128     encoder << result.artist();
2129     encoder << result.album();
2130     encoder << result.title();
2131     encoder << result.artworkURL();
2132 }
2133
2134 bool ArgumentCoder<MediaSessionMetadata>::decode(Decoder& decoder, MediaSessionMetadata& result)
2135 {
2136     String artist, album, title;
2137     URL artworkURL;
2138     if (!decoder.decode(artist))
2139         return false;
2140     if (!decoder.decode(album))
2141         return false;
2142     if (!decoder.decode(title))
2143         return false;
2144     if (!decoder.decode(artworkURL))
2145         return false;
2146     result = MediaSessionMetadata(title, artist, album, artworkURL);
2147     return true;
2148 }
2149 #endif
2150
2151 void ArgumentCoder<ScrollableAreaParameters>::encode(Encoder& encoder, const ScrollableAreaParameters& parameters)
2152 {
2153     encoder.encodeEnum(parameters.horizontalScrollElasticity);
2154     encoder.encodeEnum(parameters.verticalScrollElasticity);
2155
2156     encoder.encodeEnum(parameters.horizontalScrollbarMode);
2157     encoder.encodeEnum(parameters.verticalScrollbarMode);
2158
2159     encoder << parameters.hasEnabledHorizontalScrollbar;
2160     encoder << parameters.hasEnabledVerticalScrollbar;
2161
2162     encoder << parameters.horizontalScrollbarHiddenByStyle;
2163     encoder << parameters.verticalScrollbarHiddenByStyle;
2164
2165     encoder << parameters.useDarkAppearanceForScrollbars;
2166 }
2167
2168 bool ArgumentCoder<ScrollableAreaParameters>::decode(Decoder& decoder, ScrollableAreaParameters& params)
2169 {
2170     if (!decoder.decodeEnum(params.horizontalScrollElasticity))
2171         return false;
2172     if (!decoder.decodeEnum(params.verticalScrollElasticity))
2173         return false;
2174
2175     if (!decoder.decodeEnum(params.horizontalScrollbarMode))
2176         return false;
2177     if (!decoder.decodeEnum(params.verticalScrollbarMode))
2178         return false;
2179
2180     if (!decoder.decode(params.hasEnabledHorizontalScrollbar))
2181         return false;
2182     if (!decoder.decode(params.hasEnabledVerticalScrollbar))
2183         return false;
2184
2185     if (!decoder.decode(params.horizontalScrollbarHiddenByStyle))
2186         return false;
2187     if (!decoder.decode(params.verticalScrollbarHiddenByStyle))
2188         return false;
2189
2190     if (!decoder.decode(params.useDarkAppearanceForScrollbars))
2191         return false;
2192
2193     return true;
2194 }
2195
2196 void ArgumentCoder<FixedPositionViewportConstraints>::encode(Encoder& encoder, const FixedPositionViewportConstraints& viewportConstraints)
2197 {
2198     encoder << viewportConstraints.alignmentOffset();
2199     encoder << viewportConstraints.anchorEdges();
2200
2201     encoder << viewportConstraints.viewportRectAtLastLayout();
2202     encoder << viewportConstraints.layerPositionAtLastLayout();
2203 }
2204
2205 bool ArgumentCoder<FixedPositionViewportConstraints>::decode(Decoder& decoder, FixedPositionViewportConstraints& viewportConstraints)
2206 {
2207     FloatSize alignmentOffset;
2208     if (!decoder.decode(alignmentOffset))
2209         return false;
2210     
2211     ViewportConstraints::AnchorEdges anchorEdges;
2212     if (!decoder.decode(anchorEdges))
2213         return false;
2214
2215     FloatRect viewportRectAtLastLayout;
2216     if (!decoder.decode(viewportRectAtLastLayout))
2217         return false;
2218
2219     FloatPoint layerPositionAtLastLayout;
2220     if (!decoder.decode(layerPositionAtLastLayout))
2221         return false;
2222
2223     viewportConstraints = FixedPositionViewportConstraints();
2224     viewportConstraints.setAlignmentOffset(alignmentOffset);
2225     viewportConstraints.setAnchorEdges(anchorEdges);
2226
2227     viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout);
2228     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2229     
2230     return true;
2231 }
2232
2233 void ArgumentCoder<AbsolutePositionConstraints>::encode(Encoder& encoder, const AbsolutePositionConstraints& layoutConstraints)
2234 {
2235     encoder << layoutConstraints.alignmentOffset();
2236     encoder << layoutConstraints.layerPositionAtLastLayout();
2237 }
2238
2239 bool ArgumentCoder<AbsolutePositionConstraints>::decode(Decoder& decoder, AbsolutePositionConstraints& layoutConstraints)
2240 {
2241     FloatSize alignmentOffset;
2242     if (!decoder.decode(alignmentOffset))
2243         return false;
2244
2245     FloatPoint layerPosition;
2246     if (!decoder.decode(layerPosition))
2247         return false;
2248
2249     layoutConstraints = { };
2250     layoutConstraints.setAlignmentOffset(alignmentOffset);
2251     layoutConstraints.setLayerPositionAtLastLayout(layerPosition);
2252     return true;
2253 }
2254
2255 void ArgumentCoder<StickyPositionViewportConstraints>::encode(Encoder& encoder, const StickyPositionViewportConstraints& viewportConstraints)
2256 {
2257     encoder << viewportConstraints.alignmentOffset();
2258     encoder << viewportConstraints.anchorEdges();
2259
2260     encoder << viewportConstraints.leftOffset();
2261     encoder << viewportConstraints.rightOffset();
2262     encoder << viewportConstraints.topOffset();
2263     encoder << viewportConstraints.bottomOffset();
2264
2265     encoder << viewportConstraints.constrainingRectAtLastLayout();
2266     encoder << viewportConstraints.containingBlockRect();
2267     encoder << viewportConstraints.stickyBoxRect();
2268
2269     encoder << viewportConstraints.stickyOffsetAtLastLayout();
2270     encoder << viewportConstraints.layerPositionAtLastLayout();
2271 }
2272
2273 bool ArgumentCoder<StickyPositionViewportConstraints>::decode(Decoder& decoder, StickyPositionViewportConstraints& viewportConstraints)
2274 {
2275     FloatSize alignmentOffset;
2276     if (!decoder.decode(alignmentOffset))
2277         return false;
2278     
2279     ViewportConstraints::AnchorEdges anchorEdges;
2280     if (!decoder.decode(anchorEdges))
2281         return false;
2282     
2283     float leftOffset;
2284     if (!decoder.decode(leftOffset))
2285         return false;
2286
2287     float rightOffset;
2288     if (!decoder.decode(rightOffset))
2289         return false;
2290
2291     float topOffset;
2292     if (!decoder.decode(topOffset))
2293         return false;
2294
2295     float bottomOffset;
2296     if (!decoder.decode(bottomOffset))
2297         return false;
2298     
2299     FloatRect constrainingRectAtLastLayout;
2300     if (!decoder.decode(constrainingRectAtLastLayout))
2301         return false;
2302
2303     FloatRect containingBlockRect;
2304     if (!decoder.decode(containingBlockRect))
2305         return false;
2306
2307     FloatRect stickyBoxRect;
2308     if (!decoder.decode(stickyBoxRect))
2309         return false;
2310
2311     FloatSize stickyOffsetAtLastLayout;
2312     if (!decoder.decode(stickyOffsetAtLastLayout))
2313         return false;
2314     
2315     FloatPoint layerPositionAtLastLayout;
2316     if (!decoder.decode(layerPositionAtLastLayout))
2317         return false;
2318
2319     viewportConstraints = StickyPositionViewportConstraints();
2320     viewportConstraints.setAlignmentOffset(alignmentOffset);
2321     viewportConstraints.setAnchorEdges(anchorEdges);
2322
2323     viewportConstraints.setLeftOffset(leftOffset);
2324     viewportConstraints.setRightOffset(rightOffset);
2325     viewportConstraints.setTopOffset(topOffset);
2326     viewportConstraints.setBottomOffset(bottomOffset);
2327     
2328     viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout);
2329     viewportConstraints.setContainingBlockRect(containingBlockRect);
2330     viewportConstraints.setStickyBoxRect(stickyBoxRect);
2331
2332     viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout);
2333     viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
2334
2335     return true;
2336 }
2337
2338 #if !USE(COORDINATED_GRAPHICS)
2339 void ArgumentCoder<FilterOperation>::encode(Encoder& encoder, const FilterOperation& filter)
2340 {
2341     encoder.encodeEnum(filter.type());
2342
2343     switch (filter.type()) {
2344     case FilterOperation::NONE:
2345     case FilterOperation::REFERENCE:
2346         ASSERT_NOT_REACHED();
2347         break;
2348     case FilterOperation::GRAYSCALE:
2349     case FilterOperation::SEPIA:
2350     case FilterOperation::SATURATE:
2351     case FilterOperation::HUE_ROTATE:
2352         encoder << downcast<BasicColorMatrixFilterOperation>(filter).amount();
2353         break;
2354     case FilterOperation::INVERT:
2355     case FilterOperation::OPACITY:
2356     case FilterOperation::BRIGHTNESS:
2357     case FilterOperation::CONTRAST:
2358         encoder << downcast<BasicComponentTransferFilterOperation>(filter).amount();
2359         break;
2360     case FilterOperation::APPLE_INVERT_LIGHTNESS:
2361         ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
2362         break;
2363     case FilterOperation::BLUR:
2364         encoder << downcast<BlurFilterOperation>(filter).stdDeviation();
2365         break;
2366     case FilterOperation::DROP_SHADOW: {
2367         const auto& dropShadowFilter = downcast<DropShadowFilterOperation>(filter);
2368         encoder << dropShadowFilter.location();
2369         encoder << dropShadowFilter.stdDeviation();
2370         encoder << dropShadowFilter.color();
2371         break;
2372     }
2373     case FilterOperation::DEFAULT:
2374         encoder.encodeEnum(downcast<DefaultFilterOperation>(filter).representedType());
2375         break;
2376     case FilterOperation::PASSTHROUGH:
2377         break;
2378     }
2379 }
2380
2381 bool decodeFilterOperation(Decoder& decoder, RefPtr<FilterOperation>& filter)
2382 {
2383     FilterOperation::OperationType type;
2384     if (!decoder.decodeEnum(type))
2385         return false;
2386
2387     switch (type) {
2388     case FilterOperation::NONE:
2389     case FilterOperation::REFERENCE:
2390         ASSERT_NOT_REACHED();
2391         decoder.markInvalid();
2392         return false;
2393     case FilterOperation::GRAYSCALE:
2394     case FilterOperation::SEPIA:
2395     case FilterOperation::SATURATE:
2396     case FilterOperation::HUE_ROTATE: {
2397         double amount;
2398         if (!decoder.decode(amount))
2399             return false;
2400         filter = BasicColorMatrixFilterOperation::create(amount, type);
2401         break;
2402     }
2403     case FilterOperation::INVERT:
2404     case FilterOperation::OPACITY:
2405     case FilterOperation::BRIGHTNESS:
2406     case FilterOperation::CONTRAST: {
2407         double amount;
2408         if (!decoder.decode(amount))
2409             return false;
2410         filter = BasicComponentTransferFilterOperation::create(amount, type);
2411         break;
2412     }
2413     case FilterOperation::APPLE_INVERT_LIGHTNESS:
2414         ASSERT_NOT_REACHED(); // APPLE_INVERT_LIGHTNESS is only used in -apple-color-filter.
2415         break;
2416     case FilterOperation::BLUR: {
2417         Length stdDeviation;
2418         if (!decoder.decode(stdDeviation))
2419             return false;
2420         filter = BlurFilterOperation::create(stdDeviation);
2421         break;
2422     }
2423     case FilterOperation::DROP_SHADOW: {
2424         IntPoint location;
2425         int stdDeviation;
2426         Color color;
2427         if (!decoder.decode(location))
2428             return false;
2429         if (!decoder.decode(stdDeviation))
2430             return false;
2431         if (!decoder.decode(color))
2432             return false;
2433         filter = DropShadowFilterOperation::create(location, stdDeviation, color);
2434         break;
2435     }
2436     case FilterOperation::DEFAULT: {
2437         FilterOperation::OperationType representedType;
2438         if (!decoder.decodeEnum(representedType))
2439             return false;
2440         filter = DefaultFilterOperation::create(representedType);
2441         break;
2442     }
2443     case FilterOperation::PASSTHROUGH:
2444         filter = PassthroughFilterOperation::create();
2445         break;
2446     }
2447             
2448     return true;
2449 }
2450
2451
2452 void ArgumentCoder<FilterOperations>::encode(Encoder& encoder, const FilterOperations& filters)
2453 {
2454     encoder << static_cast<uint64_t>(filters.size());
2455
2456     for (const auto& filter : filters.operations())
2457         encoder << *filter;
2458 }
2459
2460 bool ArgumentCoder<FilterOperations>::decode(Decoder& decoder, FilterOperations& filters)
2461 {
2462     uint64_t filterCount;
2463     if (!decoder.decode(filterCount))
2464         return false;
2465
2466     for (uint64_t i = 0; i < filterCount; ++i) {
2467         RefPtr<FilterOperation> filter;
2468         if (!decodeFilterOperation(decoder, filter))
2469             return false;
2470         filters.operations().append(WTFMove(filter));
2471     }
2472
2473     return true;
2474 }
2475 #endif // !USE(COORDINATED_GRAPHICS)
2476
2477 void ArgumentCoder<BlobPart>::encode(Encoder& encoder, const BlobPart& blobPart)
2478 {
2479     encoder << static_cast<uint32_t>(blobPart.type());
2480     switch (blobPart.type()) {
2481     case BlobPart::Data:
2482         encoder << blobPart.data();
2483         break;
2484     case BlobPart::Blob:
2485         encoder << blobPart.url();
2486         break;
2487     }
2488 }
2489
2490 Optional<BlobPart> ArgumentCoder<BlobPart>::decode(Decoder& decoder)
2491 {
2492     BlobPart blobPart;
2493
2494     Optional<uint32_t> type;
2495     decoder >> type;
2496     if (!type)
2497         return WTF::nullopt;
2498
2499     switch (*type) {
2500     case BlobPart::Data: {
2501         Optional<Vector<uint8_t>> data;
2502         decoder >> data;
2503         if (!data)
2504             return WTF::nullopt;
2505         blobPart = BlobPart(WTFMove(*data));
2506         break;
2507     }
2508     case BlobPart::Blob: {
2509         URL url;
2510         if (!decoder.decode(url))
2511             return WTF::nullopt;
2512         blobPart = BlobPart(url);
2513         break;
2514     }
2515     default:
2516         return WTF::nullopt;
2517     }
2518
2519     return blobPart;
2520 }
2521
2522 void ArgumentCoder<TextIndicatorData>::encode(Encoder& encoder, const TextIndicatorData& textIndicatorData)
2523 {
2524     encoder << textIndicatorData.selectionRectInRootViewCoordinates;
2525     encoder << textIndicatorData.textBoundingRectInRootViewCoordinates;
2526     encoder << textIndicatorData.textRectsInBoundingRectCoordinates;
2527     encoder << textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates;
2528     encoder << textIndicatorData.contentImageScaleFactor;
2529     encoder << textIndicatorData.estimatedBackgroundColor;
2530     encoder << textIndicatorData.presentationTransition;
2531     encoder << textIndicatorData.options;
2532
2533     encodeOptionalImage(encoder, textIndicatorData.contentImage.get());
2534     encodeOptionalImage(encoder, textIndicatorData.contentImageWithHighlight.get());
2535     encodeOptionalImage(encoder, textIndicatorData.contentImageWithoutSelection.get());
2536 }
2537
2538 Optional<TextIndicatorData> ArgumentCoder<TextIndicatorData>::decode(Decoder& decoder)
2539 {
2540     TextIndicatorData textIndicatorData;
2541     if (!decoder.decode(textIndicatorData.selectionRectInRootViewCoordinates))
2542         return WTF::nullopt;
2543
2544     if (!decoder.decode(textIndicatorData.textBoundingRectInRootViewCoordinates))
2545         return WTF::nullopt;
2546
2547     if (!decoder.decode(textIndicatorData.textRectsInBoundingRectCoordinates))
2548         return WTF::nullopt;
2549
2550     if (!decoder.decode(textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates))
2551         return WTF::nullopt;
2552
2553     if (!decoder.decode(textIndicatorData.contentImageScaleFactor))
2554         return WTF::nullopt;
2555
2556     if (!decoder.decode(textIndicatorData.estimatedBackgroundColor))
2557         return WTF::nullopt;
2558
2559     if (!decoder.decode(textIndicatorData.presentationTransition))
2560         return WTF::nullopt;
2561
2562     if (!decoder.decode(textIndicatorData.options))
2563         return WTF::nullopt;
2564
2565     if (!decodeOptionalImage(decoder, textIndicatorData.contentImage))
2566         return WTF::nullopt;
2567
2568     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithHighlight))
2569         return WTF::nullopt;
2570
2571     if (!decodeOptionalImage(decoder, textIndicatorData.contentImageWithoutSelection))
2572         return WTF::nullopt;
2573
2574     return textIndicatorData;
2575 }
2576
2577 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
2578 void ArgumentCoder<MediaPlaybackTargetContext>::encode(Encoder& encoder, const MediaPlaybackTargetContext& target)
2579 {
2580     bool hasPlatformData = target.encodingRequiresPlatformData();
2581     encoder << hasPlatformData;
2582
2583     int32_t targetType = target.type();
2584     encoder << targetType;
2585
2586     if (target.encodingRequiresPlatformData()) {
2587         encodePlatformData(encoder, target);
2588         return;
2589     }
2590
2591     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2592     encoder << target.mockDeviceName();
2593     encoder << static_cast<int32_t>(target.mockState());
2594 }
2595
2596 bool ArgumentCoder<MediaPlaybackTargetContext>::decode(Decoder& decoder, MediaPlaybackTargetContext& target)
2597 {
2598     bool hasPlatformData;
2599     if (!decoder.decode(hasPlatformData))
2600         return false;
2601
2602     int32_t targetType;
2603     if (!decoder.decode(targetType))
2604         return false;
2605
2606     if (hasPlatformData)
2607         return decodePlatformData(decoder, target);
2608
2609     ASSERT(targetType == MediaPlaybackTargetContext::MockType);
2610
2611     String mockDeviceName;
2612     if (!decoder.decode(mockDeviceName))
2613         return false;
2614
2615     int32_t mockState;
2616     if (!decoder.decode(mockState))
2617         return false;
2618
2619     target = MediaPlaybackTargetContext(mockDeviceName, static_cast<MediaPlaybackTargetContext::State>(mockState));
2620     return true;
2621 }
2622 #endif
2623
2624 void ArgumentCoder<DictionaryPopupInfo>::encode(IPC::Encoder& encoder, const DictionaryPopupInfo& info)
2625 {
2626     encoder << info.origin;
2627     encoder << info.textIndicator;
2628
2629     if (info.encodingRequiresPlatformData()) {
2630         encoder << true;
2631         encodePlatformData(encoder, info);
2632         return;
2633     }
2634
2635     encoder << false;
2636 }
2637
2638 bool ArgumentCoder<DictionaryPopupInfo>::decode(IPC::Decoder& decoder, DictionaryPopupInfo& result)
2639 {
2640     if (!decoder.decode(result.origin))
2641         return false;
2642
2643     Optional<TextIndicatorData> textIndicator;
2644     decoder >> textIndicator;
2645     if (!textIndicator)
2646         return false;
2647     result.textIndicator = WTFMove(*textIndicator);
2648
2649     bool hasPlatformData;
2650     if (!decoder.decode(hasPlatformData))
2651         return false;
2652     if (hasPlatformData)
2653         return decodePlatformData(decoder, result);
2654     return true;
2655 }
2656
2657 void ArgumentCoder<ExceptionDetails>::encode(IPC::Encoder& encoder, const ExceptionDetails& info)
2658 {
2659     encoder << info.message;
2660     encoder << info.lineNumber;
2661     encoder << info.columnNumber;
2662     encoder << info.sourceURL;
2663 }
2664
2665 bool ArgumentCoder<ExceptionDetails>::decode(IPC::Decoder& decoder, ExceptionDetails& result)
2666 {
2667     if (!decoder.decode(result.message))
2668         return false;
2669
2670     if (!decoder.decode(result.lineNumber))
2671         return false;
2672
2673     if (!decoder.decode(result.columnNumber))
2674         return false;
2675
2676     if (!decoder.decode(result.sourceURL))
2677         return false;
2678
2679     return true;
2680 }
2681
2682 void ArgumentCoder<ResourceLoadStatistics>::encode(Encoder& encoder, const WebCore::ResourceLoadStatistics& statistics)
2683 {
2684     encoder << statistics.registrableDomain;
2685     
2686     encoder << statistics.lastSeen.secondsSinceEpoch().value();
2687     
2688     // User interaction
2689     encoder << statistics.hadUserInteraction;
2690     encoder << statistics.mostRecentUserInteractionTime.secondsSinceEpoch().value();
2691     encoder << statistics.grandfathered;
2692
2693     // Storage access
2694     encoder << statistics.storageAccessUnderTopFrameDomains;
2695
2696     // Top frame stats
2697     encoder << statistics.topFrameUniqueRedirectsTo;
2698     encoder << statistics.topFrameUniqueRedirectsFrom;
2699     encoder << statistics.topFrameLoadedThirdPartyScripts;
2700
2701     // Subframe stats
2702     encoder << statistics.subframeUnderTopFrameDomains;
2703     
2704     // Subresource stats
2705     encoder << statistics.subresourceUnderTopFrameDomains;
2706     encoder << statistics.subresourceUniqueRedirectsTo;
2707     encoder << statistics.subresourceUniqueRedirectsFrom;
2708
2709     // Prevalent Resource
2710     encoder << statistics.isPrevalentResource;
2711     encoder << statistics.isVeryPrevalentResource;
2712     encoder << statistics.dataRecordsRemoved;
2713
2714 #if ENABLE(WEB_API_STATISTICS)
2715     encoder << statistics.fontsFailedToLoad;
2716     encoder << statistics.fontsSuccessfullyLoaded;
2717     encoder << statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs;
2718     
2719     encoder << statistics.canvasActivityRecord;
2720     
2721     encoder << statistics.navigatorFunctionsAccessed;
2722     encoder << statistics.screenFunctionsAccessed;
2723 #endif
2724 }
2725
2726 Optional<ResourceLoadStatistics> ArgumentCoder<ResourceLoadStatistics>::decode(Decoder& decoder)
2727 {
2728     ResourceLoadStatistics statistics;
2729     Optional<RegistrableDomain> registrableDomain;
2730     decoder >> registrableDomain;
2731     if (!registrableDomain)
2732         return WTF::nullopt;
2733     statistics.registrableDomain = WTFMove(*registrableDomain);
2734
2735     double lastSeenTimeAsDouble;
2736     if (!decoder.decode(lastSeenTimeAsDouble))
2737         return WTF::nullopt;
2738     statistics.lastSeen = WallTime::fromRawSeconds(lastSeenTimeAsDouble);
2739     
2740     // User interaction
2741     if (!decoder.decode(statistics.hadUserInteraction))
2742         return WTF::nullopt;
2743
2744     double mostRecentUserInteractionTimeAsDouble;
2745     if (!decoder.decode(mostRecentUserInteractionTimeAsDouble))
2746         return WTF::nullopt;
2747     statistics.mostRecentUserInteractionTime = WallTime::fromRawSeconds(mostRecentUserInteractionTimeAsDouble);
2748
2749     if (!decoder.decode(statistics.grandfathered))
2750         return WTF::nullopt;
2751
2752     // Storage access
2753     Optional<HashSet<RegistrableDomain>> storageAccessUnderTopFrameDomains;
2754     decoder >> storageAccessUnderTopFrameDomains;
2755     if (!storageAccessUnderTopFrameDomains)
2756         return WTF::nullopt;
2757     statistics.storageAccessUnderTopFrameDomains = WTFMove(*storageAccessUnderTopFrameDomains);
2758
2759     // Top frame stats
2760     Optional<HashSet<RegistrableDomain>> topFrameUniqueRedirectsTo;
2761     decoder >> topFrameUniqueRedirectsTo;
2762     if (!topFrameUniqueRedirectsTo)
2763         return WTF::nullopt;
2764     statistics.topFrameUniqueRedirectsTo = WTFMove(*topFrameUniqueRedirectsTo);
2765
2766     Optional<HashSet<RegistrableDomain>> topFrameUniqueRedirectsFrom;
2767     decoder >> topFrameUniqueRedirectsFrom;
2768     if (!topFrameUniqueRedirectsFrom)
2769         return WTF::nullopt;
2770     statistics.topFrameUniqueRedirectsFrom = WTFMove(*topFrameUniqueRedirectsFrom);
2771
2772     Optional<HashSet<RegistrableDomain>> topFrameLoadedThirdPartyScripts;
2773     decoder >> topFrameLoadedThirdPartyScripts;
2774     if (!topFrameLoadedThirdPartyScripts)
2775         return WTF::nullopt;
2776     statistics.topFrameLoadedThirdPartyScripts = WTFMove(*topFrameLoadedThirdPartyScripts);
2777
2778     // Subframe stats
2779     Optional<HashSet<RegistrableDomain>> subframeUnderTopFrameDomains;
2780     decoder >> subframeUnderTopFrameDomains;
2781     if (!subframeUnderTopFrameDomains)
2782         return WTF::nullopt;
2783     statistics.subframeUnderTopFrameDomains = WTFMove(*subframeUnderTopFrameDomains);
2784
2785     // Subresource stats
2786     Optional<HashSet<RegistrableDomain>> subresourceUnderTopFrameDomains;
2787     decoder >> subresourceUnderTopFrameDomains;
2788     if (!subresourceUnderTopFrameDomains)
2789         return WTF::nullopt;
2790     statistics.subresourceUnderTopFrameDomains = WTFMove(*subresourceUnderTopFrameDomains);
2791
2792     Optional<HashSet<RegistrableDomain>> subresourceUniqueRedirectsTo;
2793     decoder >> subresourceUniqueRedirectsTo;
2794     if (!subresourceUniqueRedirectsTo)
2795         return WTF::nullopt;
2796     statistics.subresourceUniqueRedirectsTo = WTFMove(*subresourceUniqueRedirectsTo);
2797
2798     Optional<HashSet<RegistrableDomain>> subresourceUniqueRedirectsFrom;
2799     decoder >> subresourceUniqueRedirectsFrom;
2800     if (!subresourceUniqueRedirectsFrom)
2801         return WTF::nullopt;
2802     statistics.subresourceUniqueRedirectsFrom = WTFMove(*subresourceUniqueRedirectsFrom);
2803
2804     // Prevalent Resource
2805     if (!decoder.decode(statistics.isPrevalentResource))
2806         return WTF::nullopt;
2807
2808     if (!decoder.decode(statistics.isVeryPrevalentResource))
2809         return WTF::nullopt;
2810     
2811     if (!decoder.decode(statistics.dataRecordsRemoved))
2812         return WTF::nullopt;
2813     
2814 #if ENABLE(WEB_API_STATISTICS)
2815     if (!decoder.decode(statistics.fontsFailedToLoad))
2816         return WTF::nullopt;
2817     
2818     if (!decoder.decode(statistics.fontsSuccessfullyLoaded))
2819         return WTF::nullopt;
2820     
2821     if (!decoder.decode(statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs))
2822         return WTF::nullopt;
2823     
2824     if (!decoder.decode(statistics.canvasActivityRecord))
2825         return WTF::nullopt;
2826     
2827     if (!decoder.decode(statistics.navigatorFunctionsAccessed))
2828         return WTF::nullopt;
2829     
2830     if (!decoder.decode(statistics.screenFunctionsAccessed))
2831         return WTF::nullopt;
2832 #endif
2833
2834     return statistics;
2835 }
2836
2837 #if ENABLE(MEDIA_STREAM)
2838 void ArgumentCoder<MediaConstraints>::encode(Encoder& encoder, const WebCore::MediaConstraints& constraint)
2839 {
2840     encoder << constraint.mandatoryConstraints
2841         << constraint.advancedConstraints
2842         << constraint.isValid;
2843 }
2844
2845 bool ArgumentCoder<MediaConstraints>::decode(Decoder& decoder, WebCore::MediaConstraints& constraints)
2846 {
2847     Optional<WebCore::MediaTrackConstraintSetMap> mandatoryConstraints;
2848     decoder >> mandatoryConstraints;
2849     if (!mandatoryConstraints)
2850         return false;
2851     constraints.mandatoryConstraints = WTFMove(*mandatoryConstraints);
2852     return decoder.decode(constraints.advancedConstraints)
2853         && decoder.decode(constraints.isValid);
2854 }
2855 #endif
2856
2857 #if ENABLE(INDEXED_DATABASE)
2858 void ArgumentCoder<IDBKeyPath>::encode(Encoder& encoder, const IDBKeyPath& keyPath)
2859 {
2860     bool isString = WTF::holds_alternative<String>(keyPath);
2861     encoder << isString;
2862     if (isString)
2863         encoder << WTF::get<String>(keyPath);
2864     else
2865         encoder << WTF::get<Vector<String>>(keyPath);
2866 }
2867
2868 bool ArgumentCoder<IDBKeyPath>::decode(Decoder& decoder, IDBKeyPath& keyPath)
2869 {
2870     bool isString;
2871     if (!decoder.decode(isString))
2872         return false;
2873     if (isString) {
2874         String string;
2875         if (!decoder.decode(string))
2876             return false;
2877         keyPath = string;
2878     } else {
2879         Vector<String> vector;
2880         if (!decoder.decode(vector))
2881             return false;
2882         keyPath = vector;
2883     }
2884     return true;
2885 }
2886 #endif
2887
2888 #if ENABLE(SERVICE_WORKER)
2889 void ArgumentCoder<ServiceWorkerOrClientData>::encode(Encoder& encoder, const ServiceWorkerOrClientData& data)
2890 {
2891     bool isServiceWorkerData = WTF::holds_alternative<ServiceWorkerData>(data);
2892     encoder << isServiceWorkerData;
2893     if (isServiceWorkerData)
2894         encoder << WTF::get<ServiceWorkerData>(data);
2895     else
2896         encoder << WTF::get<ServiceWorkerClientData>(data);
2897 }
2898
2899 bool ArgumentCoder<ServiceWorkerOrClientData>::decode(Decoder& decoder, ServiceWorkerOrClientData& data)
2900 {
2901     bool isServiceWorkerData;
2902     if (!decoder.decode(isServiceWorkerData))
2903         return false;
2904     if (isServiceWorkerData) {
2905         Optional<ServiceWorkerData> workerData;
2906         decoder >> workerData;
2907         if (!workerData)
2908             return false;
2909
2910         data = WTFMove(*workerData);
2911     } else {
2912         Optional<ServiceWorkerClientData> clientData;
2913         decoder >> clientData;
2914         if (!clientData)
2915             return false;
2916
2917         data = WTFMove(*clientData);
2918     }
2919     return true;
2920 }
2921
2922 void ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode(Encoder& encoder, const ServiceWorkerOrClientIdentifier& identifier)
2923 {
2924     bool isServiceWorkerIdentifier = WTF::holds_alternative<ServiceWorkerIdentifier>(identifier);
2925     encoder << isServiceWorkerIdentifier;
2926     if (isServiceWorkerIdentifier)
2927         encoder << WTF::get<ServiceWorkerIdentifier>(identifier);
2928     else
2929         encoder << WTF::get<ServiceWorkerClientIdentifier>(identifier);
2930 }
2931
2932 bool ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode(Decoder& decoder, ServiceWorkerOrClientIdentifier& identifier)
2933 {
2934     bool isServiceWorkerIdentifier;
2935     if (!decoder.decode(isServiceWorkerIdentifier))
2936         return false;
2937     if (isServiceWorkerIdentifier) {
2938         Optional<ServiceWorkerIdentifier> workerIdentifier;
2939         decoder >> workerIdentifier;
2940         if (!workerIdentifier)
2941             return false;
2942
2943         identifier = WTFMove(*workerIdentifier);
2944     } else {
2945         Optional<ServiceWorkerClientIdentifier> clientIdentifier;
2946         decoder >> clientIdentifier;
2947         if (!clientIdentifier)
2948             return false;
2949
2950         identifier = WTFMove(*clientIdentifier);
2951     }
2952     return true;
2953 }
2954 #endif
2955
2956 #if ENABLE(CSS_SCROLL_SNAP)
2957
2958 void ArgumentCoder<ScrollOffsetRange<float>>::encode(Encoder& encoder, const ScrollOffsetRange<float>& range)
2959 {
2960     encoder << range.start;
2961     encoder << range.end;
2962 }
2963
2964 auto ArgumentCoder<ScrollOffsetRange<float>>::decode(Decoder& decoder) -> Optional<WebCore::ScrollOffsetRange<float>>
2965 {
2966     WebCore::ScrollOffsetRange<float> range;
2967     float start;
2968     if (!decoder.decode(start))
2969         return WTF::nullopt;
2970
2971     float end;
2972     if (!decoder.decode(end))
2973         return WTF::nullopt;
2974
2975     range.start = start;
2976     range.end = end;
2977     return range;
2978 }
2979
2980 #endif
2981
2982 void ArgumentCoder<MediaSelectionOption>::encode(Encoder& encoder, const MediaSelectionOption& option)
2983 {
2984     encoder << option.displayName;
2985     encoder << option.type;
2986 }
2987
2988 Optional<MediaSelectionOption> ArgumentCoder<MediaSelectionOption>::decode(Decoder& decoder)
2989 {
2990     Optional<String> displayName;
2991     decoder >> displayName;
2992     if (!displayName)
2993         return WTF::nullopt;
2994     
2995     Optional<MediaSelectionOption::Type> type;
2996     decoder >> type;
2997     if (!type)
2998         return WTF::nullopt;
2999     
3000     return {{ WTFMove(*displayName), WTFMove(*type) }};
3001 }
3002
3003 void ArgumentCoder<PromisedAttachmentInfo>::encode(Encoder& encoder, const PromisedAttachmentInfo& info)
3004 {
3005     encoder << info.blobURL;
3006     encoder << info.contentType;
3007     encoder << info.fileName;
3008 #if ENABLE(ATTACHMENT_ELEMENT)
3009     encoder << info.attachmentIdentifier;
3010 #endif
3011     encodeTypesAndData(encoder, info.additionalTypes, info.additionalData);
3012 }
3013
3014 bool ArgumentCoder<PromisedAttachmentInfo>::decode(Decoder& decoder, PromisedAttachmentInfo& info)
3015 {
3016     if (!decoder.decode(info.blobURL))
3017         return false;
3018
3019     if (!decoder.decode(info.contentType))
3020         return false;
3021
3022     if (!decoder.decode(info.fileName))
3023         return false;
3024
3025 #if ENABLE(ATTACHMENT_ELEMENT)
3026     if (!decoder.decode(info.attachmentIdentifier))
3027         return false;
3028 #endif
3029
3030     if (!decodeTypesAndData(decoder, info.additionalTypes, info.additionalData))
3031         return false;
3032
3033     return true;
3034 }
3035
3036 void ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::encode(Encoder& encoder, const Vector<RefPtr<SecurityOrigin>>& origins)
3037 {
3038     encoder << static_cast<uint64_t>(origins.size());
3039     for (auto& origin : origins)
3040         encoder << *origin;
3041 }
3042     
3043 bool ArgumentCoder<Vector<RefPtr<SecurityOrigin>>>::decode(Decoder& decoder, Vector<RefPtr<SecurityOrigin>>& origins)
3044 {
3045     uint64_t dataSize;
3046     if (!decoder.decode(dataSize))
3047         return false;
3048
3049     for (uint64_t i = 0; i < dataSize; ++i) {
3050         auto decodedOriginRefPtr = SecurityOrigin::decode(decoder);
3051         if (!decodedOriginRefPtr)
3052             return false;
3053         origins.append(decodedOriginRefPtr.releaseNonNull());
3054     }
3055     origins.shrinkToFit();
3056
3057     return true;
3058 }
3059
3060 void ArgumentCoder<FontAttributes>::encode(Encoder& encoder, const FontAttributes& attributes)
3061 {
3062     encoder << attributes.backgroundColor << attributes.foregroundColor << attributes.fontShadow << attributes.hasUnderline << attributes.hasStrikeThrough << attributes.textLists;
3063     encoder.encodeEnum(attributes.horizontalAlignment);
3064     encoder.encodeEnum(attributes.subscriptOrSuperscript);
3065
3066     if (attributes.encodingRequiresPlatformData()) {
3067         encoder << true;
3068         encodePlatformData(encoder, attributes);
3069         return;
3070     }
3071 }
3072
3073 Optional<FontAttributes> ArgumentCoder<FontAttributes>::decode(Decoder& decoder)
3074 {
3075     FontAttributes attributes;
3076
3077     if (!decoder.decode(attributes.backgroundColor))
3078         return WTF::nullopt;
3079
3080     if (!decoder.decode(attributes.foregroundColor))
3081         return WTF::nullopt;
3082
3083     if (!decoder.decode(attributes.fontShadow))
3084         return WTF::nullopt;
3085
3086     if (!decoder.decode(attributes.hasUnderline))
3087         return WTF::nullopt;
3088
3089     if (!decoder.decode(attributes.hasStrikeThrough))
3090         return WTF::nullopt;
3091
3092     if (!decoder.decode(attributes.textLists))
3093         return WTF::nullopt;
3094
3095     if (!decoder.decodeEnum(attributes.horizontalAlignment))
3096         return WTF::nullopt;
3097
3098     if (!decoder.decodeEnum(attributes.subscriptOrSuperscript))
3099         return WTF::nullopt;
3100
3101     bool hasPlatformData;
3102     if (!decoder.decode(hasPlatformData))
3103         return WTF::nullopt;
3104     if (hasPlatformData)
3105         return decodePlatformData(decoder, attributes);
3106
3107     return attributes;
3108 }
3109
3110 #if ENABLE(ATTACHMENT_ELEMENT)
3111
3112 void ArgumentCoder<SerializedAttachmentData>::encode(IPC::Encoder& encoder, const WebCore::SerializedAttachmentData& data)
3113 {
3114     encoder << data.identifier << data.mimeType << IPC::SharedBufferDataReference { data.data.get() };
3115 }
3116
3117 Optional<SerializedAttachmentData> ArgumentCoder<WebCore::SerializedAttachmentData>::decode(IPC::Decoder& decoder)
3118 {
3119     String identifier;
3120     if (!decoder.decode(identifier))
3121         return WTF::nullopt;
3122
3123     String mimeType;
3124     if (!decoder.decode(mimeType))
3125         return WTF::nullopt;
3126
3127     IPC::DataReference data;
3128     if (!decoder.decode(data))
3129         return WTF::nullopt;
3130
3131     return {{ WTFMove(identifier), WTFMove(mimeType), WebCore::SharedBuffer::create(data.data(), data.size()) }};
3132 }
3133
3134 #endif // ENABLE(ATTACHMENT_ELEMENT)
3135
3136 #if ENABLE(VIDEO)
3137 void ArgumentCoder<WebCore::SerializedPlatformDataCueValue>::encode(Encoder& encoder, const SerializedPlatformDataCueValue& value)
3138 {
3139     bool hasPlatformData = value.encodingRequiresPlatformData();
3140     encoder << hasPlatformData;
3141
3142     encoder.encodeEnum(value.platformType());
3143     if (hasPlatformData)
3144         encodePlatformData(encoder, value);
3145 }
3146
3147 Optional<SerializedPlatformDataCueValue> ArgumentCoder<WebCore::SerializedPlatformDataCueValue>::decode(IPC::Decoder& decoder)
3148 {
3149     bool hasPlatformData;
3150     if (!decoder.decode(hasPlatformData))
3151         return WTF::nullopt;
3152
3153     WebCore::SerializedPlatformDataCueValue::PlatformType type;
3154     if (!decoder.decodeEnum(type))
3155         return WTF::nullopt;
3156
3157     if (hasPlatformData)
3158         return decodePlatformData(decoder, type);
3159
3160     return {{ }};
3161 }
3162 #endif
3163
3164 void ArgumentCoder<RefPtr<WebCore::SharedBuffer>>::encode(Encoder& encoder, const RefPtr<WebCore::SharedBuffer>& buffer)
3165 {
3166     encodeSharedBuffer(encoder, buffer.get());
3167 }
3168
3169 Optional<RefPtr<SharedBuffer>> ArgumentCoder<RefPtr<WebCore::SharedBuffer>>::decode(Decoder& decoder)
3170 {
3171     RefPtr<SharedBuffer> buffer;
3172     if (!decodeSharedBuffer(decoder, buffer))
3173         return WTF::nullopt;
3174
3175     return buffer;
3176 }
3177
3178 void ArgumentCoder<Ref<WebCore::SharedBuffer>>::encode(Encoder& encoder, const Ref<WebCore::SharedBuffer>& buffer)
3179 {
3180     encodeSharedBuffer(encoder, buffer.ptr());
3181 }
3182
3183 Optional<Ref<SharedBuffer>> ArgumentCoder<Ref<WebCore::SharedBuffer>>::decode(Decoder& decoder)
3184 {
3185     RefPtr<SharedBuffer> buffer;
3186     if (!decodeSharedBuffer(decoder, buffer) || !buffer)
3187         return WTF::nullopt;
3188
3189     return buffer.releaseNonNull();
3190 }
3191
3192 #if ENABLE(ENCRYPTED_MEDIA)
3193 void ArgumentCoder<WebCore::CDMInstanceSession::Message>::encode(Encoder& encoder, const WebCore::CDMInstanceSession::Message& message)
3194 {
3195     encoder << message.first;
3196
3197     RefPtr<SharedBuffer> messageData = message.second.copyRef();
3198     encoder << messageData;
3199 }
3200
3201 Optional<WebCore::CDMInstanceSession::Message>  ArgumentCoder<WebCore::CDMInstanceSession::Message>::decode(Decoder& decoder)
3202 {
3203     WebCore::CDMInstanceSession::MessageType type;
3204     if (!decoder.decode(type))
3205         return WTF::nullopt;
3206
3207     RefPtr<SharedBuffer> buffer;
3208     if (!decoder.decode(buffer) || !buffer)
3209         return WTF::nullopt;
3210
3211     return makeOptional<WebCore::CDMInstanceSession::Message>({ type, buffer.releaseNonNull() });
3212 }
3213
3214 void ArgumentCoder<WebCore::CDMInstanceSession::KeyStatusVector>::encode(Encoder& encoder, const WebCore::CDMInstanceSession::KeyStatusVector& keyStatuses)
3215 {
3216     encoder << static_cast<uint64_t>(keyStatuses.size());
3217     for (auto& keyStatus : keyStatuses) {
3218         RefPtr<SharedBuffer> key = keyStatus.first.copyRef();
3219         encoder << key << keyStatus.second;
3220     }
3221 }
3222
3223 Optional<WebCore::CDMInstanceSession::KeyStatusVector> ArgumentCoder<WebCore::CDMInstanceSession::KeyStatusVector>::decode(Decoder& decoder)
3224 {
3225     uint64_t dataSize;
3226     if (!decoder.decode(dataSize))
3227         return WTF::nullopt;
3228
3229     WebCore::CDMInstanceSession::KeyStatusVector keyStatuses;
3230     keyStatuses.reserveInitialCapacity(dataSize);
3231
3232     for (uint64_t i = 0; i < dataSize; ++i) {
3233         RefPtr<SharedBuffer> key;
3234         if (!decoder.decode(key) || !key)
3235             return WTF::nullopt;
3236
3237         WebCore::CDMInstanceSessionClient::KeyStatus status;
3238         if (!decoder.decode(status))
3239             return WTF::nullopt;
3240
3241         keyStatuses.uncheckedAppend({ key.releaseNonNull(), status });
3242     }
3243     return keyStatuses;
3244 }
3245 #endif // ENABLE(ENCRYPTED_MEDIA)
3246
3247 void ArgumentCoder<Ref<WebCore::ImageData>>::encode(Encoder& encoder, const Ref<WebCore::ImageData>& imageData)
3248 {
3249     // FIXME: Copying from the ImageData to the SharedBuffer is slow. Invent some way for the SharedBuffer to be populated directly.
3250     auto sharedBuffer = WebCore::SharedBuffer::create(imageData->data()->data(), imageData->data()->byteLength());
3251     encoder << imageData->size();
3252     encoder << sharedBuffer;
3253 }
3254
3255 Optional<Ref<WebCore::ImageData>> ArgumentCoder<Ref<WebCore::ImageData>>::decode(Decoder& decoder)
3256 {
3257     Optional<IntSize> imageDataSize;
3258     Optional<Ref<SharedBuffer>> data;
3259
3260     decoder >> imageDataSize;
3261     if (!imageDataSize)
3262         return WTF::nullopt;
3263
3264     decoder >> data;
3265     if (!data)
3266         return WTF::nullopt;
3267
3268     // FIXME: Copying from the SharedBuffer into the ImageData is slow. Invent some way for the ImageData to simply just retain the SharedBuffer, and use it internally.
3269     // Alternatively, we could create an overload for putImageData() which operates on the SharedBuffer directly.
3270     auto imageData = ImageData::create(*imageDataSize, Uint8ClampedArray::create(reinterpret_cast<const uint8_t*>((*data)->data()), (*data)->size()));
3271     if (!imageData)
3272         return WTF::nullopt;
3273
3274     return { imageData.releaseNonNull() };
3275 }
3276
3277 void ArgumentCoder<RefPtr<WebCore::ImageData>>::encode(Encoder& encoder, const RefPtr<WebCore::ImageData>& imageData)
3278 {
3279     if (!imageData) {
3280         encoder << false;
3281         return;
3282     }
3283
3284     encoder << true;
3285     ArgumentCoder<Ref<WebCore::ImageData>>::encode(encoder, imageData.copyRef().releaseNonNull());
3286 }
3287
3288 Optional<RefPtr<WebCore::ImageData>> ArgumentCoder<RefPtr<WebCore::ImageData>>::decode(Decoder& decoder)
3289 {
3290     bool isEngaged;
3291     if (!decoder.decode(isEngaged))
3292         return WTF::nullopt;
3293
3294     if (!isEngaged)
3295         return RefPtr<WebCore::ImageData>();
3296
3297     auto result = ArgumentCoder<Ref<WebCore::ImageData>>::decode(decoder);
3298     if (!result)
3299         return WTF::nullopt;
3300     return { WTFMove(*result) };
3301 }
3302
3303 } // namespace IPC