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