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