1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebCoreArgumentCoders.h"
28
29#include "DataReference.h"
30#include "ShareableBitmap.h"
31#include <WebCore/AuthenticationChallenge.h>
32#include <WebCore/BlobPart.h>
33#include <WebCore/CertificateInfo.h>
34#include <WebCore/Cookie.h>
35#include <WebCore/Credential.h>
36#include <WebCore/Cursor.h>
37#include <WebCore/DatabaseDetails.h>
38#include <WebCore/DictationAlternative.h>
39#include <WebCore/Editor.h>
40#include <WebCore/FileChooser.h>
41#include <WebCore/FilterOperation.h>
42#include <WebCore/FilterOperations.h>
43#include <WebCore/GraphicsContext.h>
44#include <WebCore/GraphicsLayer.h>
45#include <WebCore/IDBDatabaseMetadata.h>
46#include <WebCore/IDBGetResult.h>
47#include <WebCore/IDBKeyData.h>
48#include <WebCore/IDBKeyPath.h>
49#include <WebCore/IDBKeyRangeData.h>
50#include <WebCore/Image.h>
51#include <WebCore/Length.h>
52#include <WebCore/PluginData.h>
53#include <WebCore/ProtectionSpace.h>
54#include <WebCore/Region.h>
55#include <WebCore/ResourceError.h>
56#include <WebCore/ResourceRequest.h>
57#include <WebCore/ResourceResponse.h>
58#include <WebCore/ScrollingConstraints.h>
59#include <WebCore/ScrollingCoordinator.h>
60#include <WebCore/SessionID.h>
61#include <WebCore/TextCheckerClient.h>
62#include <WebCore/TimingFunction.h>
63#include <WebCore/TransformationMatrix.h>
64#include <WebCore/URL.h>
65#include <WebCore/UserScript.h>
66#include <WebCore/UserStyleSheet.h>
67#include <WebCore/ViewportArguments.h>
68#include <WebCore/WindowFeatures.h>
69#include <wtf/text/CString.h>
70#include <wtf/text/StringHash.h>
71
72#if PLATFORM(COCOA)
73#include "ArgumentCodersCF.h"
74#endif
75
76#if PLATFORM(IOS)
77#include <WebCore/FloatQuad.h>
78#include <WebCore/InspectorOverlay.h>
79#include <WebCore/Pasteboard.h>
80#include <WebCore/SelectionRect.h>
81#include <WebCore/SharedBuffer.h>
82#endif // PLATFORM(IOS)
83
84using namespace WebCore;
85using namespace WebKit;
86
87namespace IPC {
88
89void ArgumentCoder<AffineTransform>::encode(ArgumentEncoder& encoder, const AffineTransform& affineTransform)
90{
91    SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
92}
93
94bool ArgumentCoder<AffineTransform>::decode(ArgumentDecoder& decoder, AffineTransform& affineTransform)
95{
96    return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
97}
98
99void ArgumentCoder<TransformationMatrix>::encode(ArgumentEncoder& encoder, const TransformationMatrix& transformationMatrix)
100{
101    SimpleArgumentCoder<TransformationMatrix>::encode(encoder, transformationMatrix);
102}
103
104bool ArgumentCoder<TransformationMatrix>::decode(ArgumentDecoder& decoder, TransformationMatrix& transformationMatrix)
105{
106    return SimpleArgumentCoder<TransformationMatrix>::decode(decoder, transformationMatrix);
107}
108
109void ArgumentCoder<LinearTimingFunction>::encode(ArgumentEncoder& encoder, const LinearTimingFunction& timingFunction)
110{
111    encoder.encodeEnum(timingFunction.type());
112}
113
114bool ArgumentCoder<LinearTimingFunction>::decode(ArgumentDecoder&, LinearTimingFunction&)
115{
116    // Type is decoded by the caller. Nothing else to decode.
117    return true;
118}
119
120void ArgumentCoder<CubicBezierTimingFunction>::encode(ArgumentEncoder& encoder, const CubicBezierTimingFunction& timingFunction)
121{
122    encoder.encodeEnum(timingFunction.type());
123
124    encoder << timingFunction.x1();
125    encoder << timingFunction.y1();
126    encoder << timingFunction.x2();
127    encoder << timingFunction.y2();
128
129    encoder.encodeEnum(timingFunction.timingFunctionPreset());
130}
131
132bool ArgumentCoder<CubicBezierTimingFunction>::decode(ArgumentDecoder& decoder, CubicBezierTimingFunction& timingFunction)
133{
134    // Type is decoded by the caller.
135    double x1;
136    if (!decoder.decode(x1))
137        return false;
138
139    double y1;
140    if (!decoder.decode(y1))
141        return false;
142
143    double x2;
144    if (!decoder.decode(x2))
145        return false;
146
147    double y2;
148    if (!decoder.decode(y2))
149        return false;
150
151    CubicBezierTimingFunction::TimingFunctionPreset preset;
152    if (!decoder.decodeEnum(preset))
153        return false;
154
155    timingFunction.setValues(x1, y1, x2, y2);
156    timingFunction.setTimingFunctionPreset(preset);
157
158    return true;
159}
160
161void ArgumentCoder<StepsTimingFunction>::encode(ArgumentEncoder& encoder, const StepsTimingFunction& timingFunction)
162{
163    encoder.encodeEnum(timingFunction.type());
164
165    encoder << timingFunction.numberOfSteps();
166    encoder << timingFunction.stepAtStart();
167}
168
169bool ArgumentCoder<StepsTimingFunction>::decode(ArgumentDecoder& decoder, StepsTimingFunction& timingFunction)
170{
171    // Type is decoded by the caller.
172    int numSteps;
173    if (!decoder.decode(numSteps))
174        return false;
175
176    bool stepAtStart;
177    if (!decoder.decode(stepAtStart))
178        return false;
179
180    timingFunction.setNumberOfSteps(numSteps);
181    timingFunction.setStepAtStart(stepAtStart);
182
183    return true;
184}
185
186void ArgumentCoder<FloatPoint>::encode(ArgumentEncoder& encoder, const FloatPoint& floatPoint)
187{
188    SimpleArgumentCoder<FloatPoint>::encode(encoder, floatPoint);
189}
190
191bool ArgumentCoder<FloatPoint>::decode(ArgumentDecoder& decoder, FloatPoint& floatPoint)
192{
193    return SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint);
194}
195
196
197void ArgumentCoder<FloatPoint3D>::encode(ArgumentEncoder& encoder, const FloatPoint3D& floatPoint)
198{
199    SimpleArgumentCoder<FloatPoint3D>::encode(encoder, floatPoint);
200}
201
202bool ArgumentCoder<FloatPoint3D>::decode(ArgumentDecoder& decoder, FloatPoint3D& floatPoint)
203{
204    return SimpleArgumentCoder<FloatPoint3D>::decode(decoder, floatPoint);
205}
206
207
208void ArgumentCoder<FloatRect>::encode(ArgumentEncoder& encoder, const FloatRect& floatRect)
209{
210    SimpleArgumentCoder<FloatRect>::encode(encoder, floatRect);
211}
212
213bool ArgumentCoder<FloatRect>::decode(ArgumentDecoder& decoder, FloatRect& floatRect)
214{
215    return SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect);
216}
217
218
219void ArgumentCoder<FloatSize>::encode(ArgumentEncoder& encoder, const FloatSize& floatSize)
220{
221    SimpleArgumentCoder<FloatSize>::encode(encoder, floatSize);
222}
223
224bool ArgumentCoder<FloatSize>::decode(ArgumentDecoder& decoder, FloatSize& floatSize)
225{
226    return SimpleArgumentCoder<FloatSize>::decode(decoder, floatSize);
227}
228
229
230#if PLATFORM(IOS)
231void ArgumentCoder<FloatQuad>::encode(ArgumentEncoder& encoder, const FloatQuad& floatQuad)
232{
233    SimpleArgumentCoder<FloatQuad>::encode(encoder, floatQuad);
234}
235
236bool ArgumentCoder<FloatQuad>::decode(ArgumentDecoder& decoder, FloatQuad& floatQuad)
237{
238    return SimpleArgumentCoder<FloatQuad>::decode(decoder, floatQuad);
239}
240
241void ArgumentCoder<ViewportArguments>::encode(ArgumentEncoder& encoder, const ViewportArguments& viewportArguments)
242{
243    SimpleArgumentCoder<ViewportArguments>::encode(encoder, viewportArguments);
244}
245
246bool ArgumentCoder<ViewportArguments>::decode(ArgumentDecoder& decoder, ViewportArguments& viewportArguments)
247{
248    return SimpleArgumentCoder<ViewportArguments>::decode(decoder, viewportArguments);
249}
250#endif // PLATFORM(IOS)
251
252
253void ArgumentCoder<IntPoint>::encode(ArgumentEncoder& encoder, const IntPoint& intPoint)
254{
255    SimpleArgumentCoder<IntPoint>::encode(encoder, intPoint);
256}
257
258bool ArgumentCoder<IntPoint>::decode(ArgumentDecoder& decoder, IntPoint& intPoint)
259{
260    return SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint);
261}
262
263
264void ArgumentCoder<IntRect>::encode(ArgumentEncoder& encoder, const IntRect& intRect)
265{
266    SimpleArgumentCoder<IntRect>::encode(encoder, intRect);
267}
268
269bool ArgumentCoder<IntRect>::decode(ArgumentDecoder& decoder, IntRect& intRect)
270{
271    return SimpleArgumentCoder<IntRect>::decode(decoder, intRect);
272}
273
274
275void ArgumentCoder<IntSize>::encode(ArgumentEncoder& encoder, const IntSize& intSize)
276{
277    SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
278}
279
280bool ArgumentCoder<IntSize>::decode(ArgumentDecoder& decoder, IntSize& intSize)
281{
282    return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
283}
284
285template<> struct ArgumentCoder<Region::Span> {
286    static void encode(ArgumentEncoder&, const Region::Span&);
287    static bool decode(ArgumentDecoder&, Region::Span&);
288};
289
290void ArgumentCoder<Region::Span>::encode(ArgumentEncoder& encoder, const Region::Span& span)
291{
292    encoder << span.y;
293    encoder << (uint64_t)span.segmentIndex;
294}
295
296bool ArgumentCoder<Region::Span>::decode(ArgumentDecoder& decoder, Region::Span& span)
297{
298    if (!decoder.decode(span.y))
299        return false;
300
301    uint64_t segmentIndex;
302    if (!decoder.decode(segmentIndex))
303        return false;
304
305    span.segmentIndex = segmentIndex;
306    return true;
307}
308
309void ArgumentCoder<Region>::encode(ArgumentEncoder& encoder, const Region& region)
310{
311    encoder.encode(region.shapeSegments());
312    encoder.encode(region.shapeSpans());
313}
314
315bool ArgumentCoder<Region>::decode(ArgumentDecoder& decoder, Region& region)
316{
317    Vector<int> segments;
318    if (!decoder.decode(segments))
319        return false;
320
321    Vector<Region::Span> spans;
322    if (!decoder.decode(spans))
323        return false;
324
325    region.setShapeSegments(segments);
326    region.setShapeSpans(spans);
327    region.updateBoundsFromShape();
328
329    if (!region.isValid())
330        return false;
331
332    return true;
333}
334
335void ArgumentCoder<Length>::encode(ArgumentEncoder& encoder, const Length& length)
336{
337    SimpleArgumentCoder<Length>::encode(encoder, length);
338}
339
340bool ArgumentCoder<Length>::decode(ArgumentDecoder& decoder, Length& length)
341{
342    return SimpleArgumentCoder<Length>::decode(decoder, length);
343}
344
345
346void ArgumentCoder<ViewportAttributes>::encode(ArgumentEncoder& encoder, const ViewportAttributes& viewportAttributes)
347{
348    SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
349}
350
351bool ArgumentCoder<ViewportAttributes>::decode(ArgumentDecoder& decoder, ViewportAttributes& viewportAttributes)
352{
353    return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
354}
355
356
357void ArgumentCoder<MimeClassInfo>::encode(ArgumentEncoder& encoder, const MimeClassInfo& mimeClassInfo)
358{
359    encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions;
360}
361
362bool ArgumentCoder<MimeClassInfo>::decode(ArgumentDecoder& decoder, MimeClassInfo& mimeClassInfo)
363{
364    if (!decoder.decode(mimeClassInfo.type))
365        return false;
366    if (!decoder.decode(mimeClassInfo.desc))
367        return false;
368    if (!decoder.decode(mimeClassInfo.extensions))
369        return false;
370
371    return true;
372}
373
374
375void ArgumentCoder<PluginInfo>::encode(ArgumentEncoder& encoder, const PluginInfo& pluginInfo)
376{
377    encoder << pluginInfo.name << pluginInfo.file << pluginInfo.desc << pluginInfo.mimes << pluginInfo.isApplicationPlugin;
378}
379
380bool ArgumentCoder<PluginInfo>::decode(ArgumentDecoder& decoder, PluginInfo& pluginInfo)
381{
382    if (!decoder.decode(pluginInfo.name))
383        return false;
384    if (!decoder.decode(pluginInfo.file))
385        return false;
386    if (!decoder.decode(pluginInfo.desc))
387        return false;
388    if (!decoder.decode(pluginInfo.mimes))
389        return false;
390    if (!decoder.decode(pluginInfo.isApplicationPlugin))
391        return false;
392
393    return true;
394}
395
396
397void ArgumentCoder<HTTPHeaderMap>::encode(ArgumentEncoder& encoder, const HTTPHeaderMap& headerMap)
398{
399    encoder << static_cast<uint64_t>(headerMap.size());
400    for (auto& keyValuePair : headerMap) {
401        encoder << keyValuePair.key;
402        encoder << keyValuePair.value;
403    }
404}
405
406bool ArgumentCoder<HTTPHeaderMap>::decode(ArgumentDecoder& decoder, HTTPHeaderMap& headerMap)
407{
408    uint64_t size;
409    if (!decoder.decode(size))
410        return false;
411
412    for (size_t i = 0; i < size; ++i) {
413        String name;
414        if (!decoder.decode(name))
415            return false;
416
417        String value;
418        if (!decoder.decode(value))
419            return false;
420
421        headerMap.set(name, value);
422    }
423
424    return true;
425}
426
427
428void ArgumentCoder<AuthenticationChallenge>::encode(ArgumentEncoder& encoder, const AuthenticationChallenge& challenge)
429{
430    encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error();
431}
432
433bool ArgumentCoder<AuthenticationChallenge>::decode(ArgumentDecoder& decoder, AuthenticationChallenge& challenge)
434{
435    ProtectionSpace protectionSpace;
436    if (!decoder.decode(protectionSpace))
437        return false;
438
439    Credential proposedCredential;
440    if (!decoder.decode(proposedCredential))
441        return false;
442
443    unsigned previousFailureCount;
444    if (!decoder.decode(previousFailureCount))
445        return false;
446
447    ResourceResponse failureResponse;
448    if (!decoder.decode(failureResponse))
449        return false;
450
451    ResourceError error;
452    if (!decoder.decode(error))
453        return false;
454
455    challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
456    return true;
457}
458
459
460void ArgumentCoder<ProtectionSpace>::encode(ArgumentEncoder& encoder, const ProtectionSpace& space)
461{
462    if (space.encodingRequiresPlatformData()) {
463        encoder << true;
464        encodePlatformData(encoder, space);
465        return;
466    }
467
468    encoder << false;
469    encoder << space.host() << space.port() << space.realm();
470    encoder.encodeEnum(space.authenticationScheme());
471    encoder.encodeEnum(space.serverType());
472}
473
474bool ArgumentCoder<ProtectionSpace>::decode(ArgumentDecoder& decoder, ProtectionSpace& space)
475{
476    bool hasPlatformData;
477    if (!decoder.decode(hasPlatformData))
478        return false;
479
480    if (hasPlatformData)
481        return decodePlatformData(decoder, space);
482
483    String host;
484    if (!decoder.decode(host))
485        return false;
486
487    int port;
488    if (!decoder.decode(port))
489        return false;
490
491    String realm;
492    if (!decoder.decode(realm))
493        return false;
494
495    ProtectionSpaceAuthenticationScheme authenticationScheme;
496    if (!decoder.decodeEnum(authenticationScheme))
497        return false;
498
499    ProtectionSpaceServerType serverType;
500    if (!decoder.decodeEnum(serverType))
501        return false;
502
503    space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
504    return true;
505}
506
507void ArgumentCoder<Credential>::encode(ArgumentEncoder& encoder, const Credential& credential)
508{
509#if CERTIFICATE_CREDENTIALS_SUPPORTED
510    encoder.encodeEnum(credential.type());
511
512    if (credential.type() == CredentialTypeClientCertificate) {
513        IPC::encode(encoder, credential.identity());
514
515        encoder << !!credential.certificates();
516        if (credential.certificates())
517            IPC::encode(encoder, credential.certificates());
518
519        encoder.encodeEnum(credential.persistence());
520        return;
521    }
522#endif
523    encoder << credential.user() << credential.password();
524
525    encoder.encodeEnum(credential.persistence());
526}
527
528bool ArgumentCoder<Credential>::decode(ArgumentDecoder& decoder, Credential& credential)
529{
530#if CERTIFICATE_CREDENTIALS_SUPPORTED
531    CredentialType type;
532
533    if (!decoder.decodeEnum(type))
534        return false;
535
536    if (type == CredentialTypeClientCertificate) {
537        RetainPtr<SecIdentityRef> identity;
538        if (!IPC::decode(decoder, identity))
539            return false;
540
541        bool hasCertificates;
542        if (!decoder.decode(hasCertificates))
543            return false;
544
545        RetainPtr<CFArrayRef> certificates;
546        if (hasCertificates) {
547            if (!IPC::decode(decoder, certificates))
548                return false;
549        }
550
551        CredentialPersistence persistence;
552        if (!decoder.decodeEnum(persistence))
553            return false;
554
555        credential = Credential(identity.get(), certificates.get(), persistence);
556        return true;
557    }
558#endif
559
560    String user;
561    if (!decoder.decode(user))
562        return false;
563
564    String password;
565    if (!decoder.decode(password))
566        return false;
567
568    CredentialPersistence persistence;
569    if (!decoder.decodeEnum(persistence))
570        return false;
571
572    credential = Credential(user, password, persistence);
573    return true;
574}
575
576static void encodeImage(ArgumentEncoder& encoder, Image* image)
577{
578    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(image->size()), ShareableBitmap::SupportsAlpha);
579    bitmap->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
580
581    ShareableBitmap::Handle handle;
582    bitmap->createHandle(handle);
583
584    encoder << handle;
585}
586
587static bool decodeImage(ArgumentDecoder& decoder, RefPtr<Image>& image)
588{
589    ShareableBitmap::Handle handle;
590    if (!decoder.decode(handle))
591        return false;
592
593    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
594    if (!bitmap)
595        return false;
596    image = bitmap->createImage();
597    if (!image)
598        return false;
599    return true;
600}
601
602#if !PLATFORM(IOS)
603void ArgumentCoder<Cursor>::encode(ArgumentEncoder& encoder, const Cursor& cursor)
604{
605    encoder.encodeEnum(cursor.type());
606
607    if (cursor.type() != Cursor::Custom)
608        return;
609
610    if (cursor.image()->isNull()) {
611        encoder << false; // There is no valid image being encoded.
612        return;
613    }
614
615    encoder << true;
616    encodeImage(encoder, cursor.image());
617    encoder << cursor.hotSpot();
618}
619
620bool ArgumentCoder<Cursor>::decode(ArgumentDecoder& decoder, Cursor& cursor)
621{
622    Cursor::Type type;
623    if (!decoder.decodeEnum(type))
624        return false;
625
626    if (type > Cursor::Custom)
627        return false;
628
629    if (type != Cursor::Custom) {
630        const Cursor& cursorReference = Cursor::fromType(type);
631        // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
632        // This will avoid having to re-create the platform cursors over and over.
633        (void)cursorReference.platformCursor();
634
635        cursor = cursorReference;
636        return true;
637    }
638
639    bool isValidImagePresent;
640    if (!decoder.decode(isValidImagePresent))
641        return false;
642
643    if (!isValidImagePresent) {
644        cursor = Cursor(Image::nullImage(), IntPoint());
645        return true;
646    }
647
648    RefPtr<Image> image;
649    if (!decodeImage(decoder, image))
650        return false;
651
652    IntPoint hotSpot;
653    if (!decoder.decode(hotSpot))
654        return false;
655
656    if (!image->rect().contains(hotSpot))
657        return false;
658
659    cursor = Cursor(image.get(), hotSpot);
660    return true;
661}
662#endif
663
664void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
665{
666    if (kShouldSerializeWebCoreData) {
667        encoder << resourceRequest.url().string();
668        encoder << resourceRequest.httpMethod();
669        encoder << resourceRequest.httpHeaderFields();
670
671        // FIXME: Do not encode HTTP message body.
672        // 1. It can be large and thus costly to send across.
673        // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all.
674        FormData* httpBody = resourceRequest.httpBody();
675        encoder << static_cast<bool>(httpBody);
676        if (httpBody)
677            encoder << httpBody->flattenToString();
678
679        encoder << resourceRequest.firstPartyForCookies().string();
680    }
681
682#if ENABLE(CACHE_PARTITIONING)
683    encoder << resourceRequest.cachePartition();
684#endif
685
686#if ENABLE(INSPECTOR)
687    encoder << resourceRequest.hiddenFromInspector();
688#endif
689
690    if (resourceRequest.encodingRequiresPlatformData()) {
691        encoder << true;
692        encodePlatformData(encoder, resourceRequest);
693        return;
694    }
695    encoder << false;
696    resourceRequest.encodeWithoutPlatformData(encoder);
697}
698
699bool ArgumentCoder<ResourceRequest>::decode(ArgumentDecoder& decoder, ResourceRequest& resourceRequest)
700{
701    if (kShouldSerializeWebCoreData) {
702        ResourceRequest request;
703
704        String url;
705        if (!decoder.decode(url))
706            return false;
707        request.setURL(URL(URL(), url));
708
709        String httpMethod;
710        if (!decoder.decode(httpMethod))
711            return false;
712        request.setHTTPMethod(httpMethod);
713
714        HTTPHeaderMap headers;
715        if (!decoder.decode(headers))
716            return false;
717        request.setHTTPHeaderFields(WTF::move(headers));
718
719        bool hasHTTPBody;
720        if (!decoder.decode(hasHTTPBody))
721            return false;
722        if (hasHTTPBody) {
723            String httpBody;
724            if (!decoder.decode(httpBody))
725                return false;
726            request.setHTTPBody(FormData::create(httpBody.utf8()));
727        }
728
729        String firstPartyForCookies;
730        if (!decoder.decode(firstPartyForCookies))
731            return false;
732        request.setFirstPartyForCookies(URL(URL(), firstPartyForCookies));
733
734        resourceRequest = request;
735    }
736
737#if ENABLE(CACHE_PARTITIONING)
738    String cachePartition;
739    if (!decoder.decode(cachePartition))
740        return false;
741    resourceRequest.setCachePartition(cachePartition);
742#endif
743
744#if ENABLE(INSPECTOR)
745    bool isHiddenFromInspector;
746    if (!decoder.decode(isHiddenFromInspector))
747        return false;
748    resourceRequest.setHiddenFromInspector(isHiddenFromInspector);
749#endif
750
751    bool hasPlatformData;
752    if (!decoder.decode(hasPlatformData))
753        return false;
754    if (hasPlatformData)
755        return decodePlatformData(decoder, resourceRequest);
756
757    return resourceRequest.decodeWithoutPlatformData(decoder);
758}
759
760void ArgumentCoder<ResourceResponse>::encode(ArgumentEncoder& encoder, const ResourceResponse& resourceResponse)
761{
762#if PLATFORM(COCOA)
763    bool shouldSerializeWebCoreData = !resourceResponse.platformResponseIsUpToDate();
764    encoder << shouldSerializeWebCoreData;
765#else
766    bool shouldSerializeWebCoreData = true;
767#endif
768
769    encodePlatformData(encoder, resourceResponse);
770
771    if (shouldSerializeWebCoreData) {
772        bool responseIsNull = resourceResponse.isNull();
773        encoder << responseIsNull;
774        if (responseIsNull)
775            return;
776
777        encoder << resourceResponse.url().string();
778        encoder << static_cast<int32_t>(resourceResponse.httpStatusCode());
779        encoder << resourceResponse.httpHeaderFields();
780
781        encoder << resourceResponse.mimeType();
782        encoder << resourceResponse.textEncodingName();
783        encoder << static_cast<int64_t>(resourceResponse.expectedContentLength());
784        encoder << resourceResponse.httpStatusText();
785        encoder << resourceResponse.suggestedFilename();
786    }
787
788#if ENABLE(WEB_TIMING)
789    const ResourceLoadTiming& timing = resourceResponse.resourceLoadTiming();
790    encoder << timing.domainLookupStart;
791    encoder << timing.domainLookupEnd;
792    encoder << timing.connectStart;
793    encoder << timing.connectEnd;
794    encoder << timing.requestStart;
795    encoder << timing.responseStart;
796    encoder << timing.secureConnectionStart;
797#endif
798}
799
800bool ArgumentCoder<ResourceResponse>::decode(ArgumentDecoder& decoder, ResourceResponse& resourceResponse)
801{
802#if PLATFORM(COCOA)
803    bool hasSerializedWebCoreData;
804    if (!decoder.decode(hasSerializedWebCoreData))
805        return false;
806#else
807    bool hasSerializedWebCoreData = true;
808#endif
809
810    ResourceResponse response;
811
812    if (!decodePlatformData(decoder, response))
813        return false;
814
815    if (hasSerializedWebCoreData) {
816        bool responseIsNull;
817        if (!decoder.decode(responseIsNull))
818            return false;
819        if (responseIsNull) {
820            resourceResponse = ResourceResponse();
821            return true;
822        }
823
824        String url;
825        if (!decoder.decode(url))
826            return false;
827        response.setURL(URL(URL(), url));
828
829        int32_t httpStatusCode;
830        if (!decoder.decode(httpStatusCode))
831            return false;
832        response.setHTTPStatusCode(httpStatusCode);
833
834        HTTPHeaderMap headers;
835        if (!decoder.decode(headers))
836            return false;
837        for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it)
838            response.setHTTPHeaderField(it->key, it->value);
839
840        String mimeType;
841        if (!decoder.decode(mimeType))
842            return false;
843        response.setMimeType(mimeType);
844
845        String textEncodingName;
846        if (!decoder.decode(textEncodingName))
847            return false;
848        response.setTextEncodingName(textEncodingName);
849
850        int64_t contentLength;
851        if (!decoder.decode(contentLength))
852            return false;
853        response.setExpectedContentLength(contentLength);
854
855        String httpStatusText;
856        if (!decoder.decode(httpStatusText))
857            return false;
858        response.setHTTPStatusText(httpStatusText);
859
860        String suggestedFilename;
861        if (!decoder.decode(suggestedFilename))
862            return false;
863        response.setSuggestedFilename(suggestedFilename);
864    }
865
866#if ENABLE(WEB_TIMING)
867    ResourceLoadTiming& timing = response.resourceLoadTiming();
868    if (!decoder.decode(timing.domainLookupStart)
869        || !decoder.decode(timing.domainLookupEnd)
870        || !decoder.decode(timing.connectStart)
871        || !decoder.decode(timing.connectEnd)
872        || !decoder.decode(timing.requestStart)
873        || !decoder.decode(timing.responseStart)
874        || !decoder.decode(timing.secureConnectionStart))
875        return false;
876#endif
877
878    resourceResponse = response;
879
880    return true;
881}
882
883void ArgumentCoder<ResourceError>::encode(ArgumentEncoder& encoder, const ResourceError& resourceError)
884{
885    if (kShouldSerializeWebCoreData) {
886        bool errorIsNull = resourceError.isNull();
887        encoder << errorIsNull;
888        if (errorIsNull)
889            return;
890
891        encoder << resourceError.domain();
892        encoder << resourceError.errorCode();
893        encoder << resourceError.failingURL();
894        encoder << resourceError.localizedDescription();
895        encoder << resourceError.isCancellation();
896        encoder << resourceError.isTimeout();
897    }
898
899    encodePlatformData(encoder, resourceError);
900}
901
902bool ArgumentCoder<ResourceError>::decode(ArgumentDecoder& decoder, ResourceError& resourceError)
903{
904    if (kShouldSerializeWebCoreData) {
905        bool errorIsNull;
906        if (!decoder.decode(errorIsNull))
907            return false;
908        if (errorIsNull) {
909            resourceError = ResourceError();
910            return true;
911        }
912
913        String domain;
914        if (!decoder.decode(domain))
915            return false;
916
917        int errorCode;
918        if (!decoder.decode(errorCode))
919            return false;
920
921        String failingURL;
922        if (!decoder.decode(failingURL))
923            return false;
924
925        String localizedDescription;
926        if (!decoder.decode(localizedDescription))
927            return false;
928
929        bool isCancellation;
930        if (!decoder.decode(isCancellation))
931            return false;
932
933        bool isTimeout;
934        if (!decoder.decode(isTimeout))
935            return false;
936
937        resourceError = ResourceError(domain, errorCode, failingURL, localizedDescription);
938        resourceError.setIsCancellation(isCancellation);
939        resourceError.setIsTimeout(isTimeout);
940    }
941
942    return decodePlatformData(decoder, resourceError);
943}
944
945#if PLATFORM(IOS)
946
947void ArgumentCoder<SelectionRect>::encode(ArgumentEncoder& encoder, const SelectionRect& selectionRect)
948{
949    encoder << selectionRect.rect();
950    encoder << static_cast<uint32_t>(selectionRect.direction());
951    encoder << selectionRect.minX();
952    encoder << selectionRect.maxX();
953    encoder << selectionRect.maxY();
954    encoder << selectionRect.lineNumber();
955    encoder << selectionRect.isLineBreak();
956    encoder << selectionRect.isFirstOnLine();
957    encoder << selectionRect.isLastOnLine();
958    encoder << selectionRect.containsStart();
959    encoder << selectionRect.containsEnd();
960    encoder << selectionRect.isHorizontal();
961}
962
963bool ArgumentCoder<SelectionRect>::decode(ArgumentDecoder& decoder, SelectionRect& selectionRect)
964{
965    IntRect rect;
966    if (!decoder.decode(rect))
967        return false;
968    selectionRect.setRect(rect);
969
970    uint32_t direction;
971    if (!decoder.decode(direction))
972        return false;
973    selectionRect.setDirection((TextDirection)direction);
974
975    int intValue;
976    if (!decoder.decode(intValue))
977        return false;
978    selectionRect.setMinX(intValue);
979
980    if (!decoder.decode(intValue))
981        return false;
982    selectionRect.setMaxX(intValue);
983
984    if (!decoder.decode(intValue))
985        return false;
986    selectionRect.setMaxY(intValue);
987
988    if (!decoder.decode(intValue))
989        return false;
990    selectionRect.setLineNumber(intValue);
991
992    bool boolValue;
993    if (!decoder.decode(boolValue))
994        return false;
995    selectionRect.setIsLineBreak(boolValue);
996
997    if (!decoder.decode(boolValue))
998        return false;
999    selectionRect.setIsFirstOnLine(boolValue);
1000
1001    if (!decoder.decode(boolValue))
1002        return false;
1003    selectionRect.setIsLastOnLine(boolValue);
1004
1005    if (!decoder.decode(boolValue))
1006        return false;
1007    selectionRect.setContainsStart(boolValue);
1008
1009    if (!decoder.decode(boolValue))
1010        return false;
1011    selectionRect.setContainsEnd(boolValue);
1012
1013    if (!decoder.decode(boolValue))
1014        return false;
1015    selectionRect.setIsHorizontal(boolValue);
1016
1017    return true;
1018}
1019
1020#endif
1021
1022void ArgumentCoder<WindowFeatures>::encode(ArgumentEncoder& encoder, const WindowFeatures& windowFeatures)
1023{
1024    encoder << windowFeatures.x;
1025    encoder << windowFeatures.y;
1026    encoder << windowFeatures.width;
1027    encoder << windowFeatures.height;
1028    encoder << windowFeatures.xSet;
1029    encoder << windowFeatures.ySet;
1030    encoder << windowFeatures.widthSet;
1031    encoder << windowFeatures.heightSet;
1032    encoder << windowFeatures.menuBarVisible;
1033    encoder << windowFeatures.statusBarVisible;
1034    encoder << windowFeatures.toolBarVisible;
1035    encoder << windowFeatures.locationBarVisible;
1036    encoder << windowFeatures.scrollbarsVisible;
1037    encoder << windowFeatures.resizable;
1038    encoder << windowFeatures.fullscreen;
1039    encoder << windowFeatures.dialog;
1040}
1041
1042bool ArgumentCoder<WindowFeatures>::decode(ArgumentDecoder& decoder, WindowFeatures& windowFeatures)
1043{
1044    if (!decoder.decode(windowFeatures.x))
1045        return false;
1046    if (!decoder.decode(windowFeatures.y))
1047        return false;
1048    if (!decoder.decode(windowFeatures.width))
1049        return false;
1050    if (!decoder.decode(windowFeatures.height))
1051        return false;
1052    if (!decoder.decode(windowFeatures.xSet))
1053        return false;
1054    if (!decoder.decode(windowFeatures.ySet))
1055        return false;
1056    if (!decoder.decode(windowFeatures.widthSet))
1057        return false;
1058    if (!decoder.decode(windowFeatures.heightSet))
1059        return false;
1060    if (!decoder.decode(windowFeatures.menuBarVisible))
1061        return false;
1062    if (!decoder.decode(windowFeatures.statusBarVisible))
1063        return false;
1064    if (!decoder.decode(windowFeatures.toolBarVisible))
1065        return false;
1066    if (!decoder.decode(windowFeatures.locationBarVisible))
1067        return false;
1068    if (!decoder.decode(windowFeatures.scrollbarsVisible))
1069        return false;
1070    if (!decoder.decode(windowFeatures.resizable))
1071        return false;
1072    if (!decoder.decode(windowFeatures.fullscreen))
1073        return false;
1074    if (!decoder.decode(windowFeatures.dialog))
1075        return false;
1076    return true;
1077}
1078
1079
1080void ArgumentCoder<Color>::encode(ArgumentEncoder& encoder, const Color& color)
1081{
1082    if (!color.isValid()) {
1083        encoder << false;
1084        return;
1085    }
1086
1087    encoder << true;
1088    encoder << color.rgb();
1089}
1090
1091bool ArgumentCoder<Color>::decode(ArgumentDecoder& decoder, Color& color)
1092{
1093    bool isValid;
1094    if (!decoder.decode(isValid))
1095        return false;
1096
1097    if (!isValid) {
1098        color = Color();
1099        return true;
1100    }
1101
1102    RGBA32 rgba;
1103    if (!decoder.decode(rgba))
1104        return false;
1105
1106    color = Color(rgba);
1107    return true;
1108}
1109
1110
1111void ArgumentCoder<CompositionUnderline>::encode(ArgumentEncoder& encoder, const CompositionUnderline& underline)
1112{
1113    encoder << underline.startOffset;
1114    encoder << underline.endOffset;
1115    encoder << underline.thick;
1116    encoder << underline.color;
1117}
1118
1119bool ArgumentCoder<CompositionUnderline>::decode(ArgumentDecoder& decoder, CompositionUnderline& underline)
1120{
1121    if (!decoder.decode(underline.startOffset))
1122        return false;
1123    if (!decoder.decode(underline.endOffset))
1124        return false;
1125    if (!decoder.decode(underline.thick))
1126        return false;
1127    if (!decoder.decode(underline.color))
1128        return false;
1129
1130    return true;
1131}
1132
1133
1134void ArgumentCoder<Cookie>::encode(ArgumentEncoder& encoder, const Cookie& cookie)
1135{
1136    encoder << cookie.name;
1137    encoder << cookie.value;
1138    encoder << cookie.domain;
1139    encoder << cookie.path;
1140    encoder << cookie.expires;
1141    encoder << cookie.httpOnly;
1142    encoder << cookie.secure;
1143    encoder << cookie.session;
1144}
1145
1146bool ArgumentCoder<Cookie>::decode(ArgumentDecoder& decoder, Cookie& cookie)
1147{
1148    if (!decoder.decode(cookie.name))
1149        return false;
1150    if (!decoder.decode(cookie.value))
1151        return false;
1152    if (!decoder.decode(cookie.domain))
1153        return false;
1154    if (!decoder.decode(cookie.path))
1155        return false;
1156    if (!decoder.decode(cookie.expires))
1157        return false;
1158    if (!decoder.decode(cookie.httpOnly))
1159        return false;
1160    if (!decoder.decode(cookie.secure))
1161        return false;
1162    if (!decoder.decode(cookie.session))
1163        return false;
1164
1165    return true;
1166}
1167
1168
1169#if ENABLE(SQL_DATABASE)
1170void ArgumentCoder<DatabaseDetails>::encode(ArgumentEncoder& encoder, const DatabaseDetails& details)
1171{
1172    encoder << details.name();
1173    encoder << details.displayName();
1174    encoder << details.expectedUsage();
1175    encoder << details.currentUsage();
1176    encoder << details.creationTime();
1177    encoder << details.modificationTime();
1178}
1179
1180bool ArgumentCoder<DatabaseDetails>::decode(ArgumentDecoder& decoder, DatabaseDetails& details)
1181{
1182    String name;
1183    if (!decoder.decode(name))
1184        return false;
1185
1186    String displayName;
1187    if (!decoder.decode(displayName))
1188        return false;
1189
1190    uint64_t expectedUsage;
1191    if (!decoder.decode(expectedUsage))
1192        return false;
1193
1194    uint64_t currentUsage;
1195    if (!decoder.decode(currentUsage))
1196        return false;
1197
1198    double creationTime;
1199    if (!decoder.decode(creationTime))
1200        return false;
1201
1202    double modificationTime;
1203    if (!decoder.decode(modificationTime))
1204        return false;
1205
1206    details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime);
1207    return true;
1208}
1209
1210#endif
1211
1212#if PLATFORM(IOS)
1213
1214void ArgumentCoder<Highlight>::encode(ArgumentEncoder& encoder, const Highlight& highlight)
1215{
1216    encoder << static_cast<uint32_t>(highlight.type);
1217    encoder << highlight.usePageCoordinates;
1218    encoder << highlight.contentColor;
1219    encoder << highlight.contentOutlineColor;
1220    encoder << highlight.paddingColor;
1221    encoder << highlight.borderColor;
1222    encoder << highlight.marginColor;
1223    encoder << highlight.quads;
1224}
1225
1226bool ArgumentCoder<Highlight>::decode(ArgumentDecoder& decoder, Highlight& highlight)
1227{
1228    uint32_t type;
1229    if (!decoder.decode(type))
1230        return false;
1231    highlight.type = (HighlightType)type;
1232
1233    if (!decoder.decode(highlight.usePageCoordinates))
1234        return false;
1235    if (!decoder.decode(highlight.contentColor))
1236        return false;
1237    if (!decoder.decode(highlight.contentOutlineColor))
1238        return false;
1239    if (!decoder.decode(highlight.paddingColor))
1240        return false;
1241    if (!decoder.decode(highlight.borderColor))
1242        return false;
1243    if (!decoder.decode(highlight.marginColor))
1244        return false;
1245    if (!decoder.decode(highlight.quads))
1246        return false;
1247    return true;
1248}
1249
1250static void encodeSharedBuffer(ArgumentEncoder& encoder, SharedBuffer* buffer)
1251{
1252    SharedMemory::Handle handle;
1253    encoder << (buffer ? static_cast<uint64_t>(buffer->size()): 0);
1254    if (buffer) {
1255        RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(buffer->size());
1256        memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
1257        sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly);
1258        encoder << handle;
1259    }
1260}
1261
1262static bool decodeSharedBuffer(ArgumentDecoder& decoder, RefPtr<SharedBuffer>& buffer)
1263{
1264    uint64_t bufferSize = 0;
1265    if (!decoder.decode(bufferSize))
1266        return false;
1267
1268    if (bufferSize) {
1269        SharedMemory::Handle handle;
1270        if (!decoder.decode(handle))
1271            return false;
1272
1273        RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly);
1274        buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), bufferSize);
1275    }
1276
1277    return true;
1278}
1279
1280void ArgumentCoder<PasteboardWebContent>::encode(ArgumentEncoder& encoder, const PasteboardWebContent& content)
1281{
1282    encoder << content.canSmartCopyOrDelete;
1283    encoder << content.dataInStringFormat;
1284
1285    encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get());
1286    encodeSharedBuffer(encoder, content.dataInRTFDFormat.get());
1287    encodeSharedBuffer(encoder, content.dataInRTFFormat.get());
1288
1289    encoder << content.clientTypes;
1290    encoder << static_cast<uint64_t>(content.clientData.size());
1291    for (size_t i = 0; i < content.clientData.size(); i++)
1292        encodeSharedBuffer(encoder, content.clientData[i].get());
1293}
1294
1295bool ArgumentCoder<PasteboardWebContent>::decode(ArgumentDecoder& decoder, PasteboardWebContent& content)
1296{
1297    if (!decoder.decode(content.canSmartCopyOrDelete))
1298        return false;
1299    if (!decoder.decode(content.dataInStringFormat))
1300        return false;
1301    if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat))
1302        return false;
1303    if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat))
1304        return false;
1305    if (!decodeSharedBuffer(decoder, content.dataInRTFFormat))
1306        return false;
1307    if (!decoder.decode(content.clientTypes))
1308        return false;
1309    uint64_t clientDataSize;
1310    if (!decoder.decode(clientDataSize))
1311        return false;
1312    if (clientDataSize)
1313        content.clientData.resize(clientDataSize);
1314    for (size_t i = 0; i < clientDataSize; i++)
1315        decodeSharedBuffer(decoder, content.clientData[i]);
1316    return true;
1317}
1318
1319void ArgumentCoder<PasteboardImage>::encode(ArgumentEncoder& encoder, const PasteboardImage& pasteboardImage)
1320{
1321    encodeImage(encoder, pasteboardImage.image.get());
1322    encoder << pasteboardImage.url.url;
1323    encoder << pasteboardImage.url.title;
1324    encoder << pasteboardImage.resourceMIMEType;
1325    if (pasteboardImage.resourceData)
1326        encodeSharedBuffer(encoder, pasteboardImage.resourceData.get());
1327}
1328
1329bool ArgumentCoder<PasteboardImage>::decode(ArgumentDecoder& decoder, PasteboardImage& pasteboardImage)
1330{
1331    if (!decodeImage(decoder, pasteboardImage.image))
1332        return false;
1333    if (!decoder.decode(pasteboardImage.url.url))
1334        return false;
1335    if (!decoder.decode(pasteboardImage.url.title))
1336        return false;
1337    if (!decoder.decode(pasteboardImage.resourceMIMEType))
1338        return false;
1339    if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData))
1340        return false;
1341    return true;
1342}
1343
1344#endif
1345
1346void ArgumentCoder<DictationAlternative>::encode(ArgumentEncoder& encoder, const DictationAlternative& dictationAlternative)
1347{
1348    encoder << dictationAlternative.rangeStart;
1349    encoder << dictationAlternative.rangeLength;
1350    encoder << dictationAlternative.dictationContext;
1351}
1352
1353bool ArgumentCoder<DictationAlternative>::decode(ArgumentDecoder& decoder, DictationAlternative& dictationAlternative)
1354{
1355    if (!decoder.decode(dictationAlternative.rangeStart))
1356        return false;
1357    if (!decoder.decode(dictationAlternative.rangeLength))
1358        return false;
1359    if (!decoder.decode(dictationAlternative.dictationContext))
1360        return false;
1361    return true;
1362}
1363
1364
1365void ArgumentCoder<FileChooserSettings>::encode(ArgumentEncoder& encoder, const FileChooserSettings& settings)
1366{
1367    encoder << settings.allowsMultipleFiles;
1368    encoder << settings.acceptMIMETypes;
1369    encoder << settings.selectedFiles;
1370#if ENABLE(MEDIA_CAPTURE)
1371    encoder << settings.capture;
1372#endif
1373}
1374
1375bool ArgumentCoder<FileChooserSettings>::decode(ArgumentDecoder& decoder, FileChooserSettings& settings)
1376{
1377    if (!decoder.decode(settings.allowsMultipleFiles))
1378        return false;
1379    if (!decoder.decode(settings.acceptMIMETypes))
1380        return false;
1381    if (!decoder.decode(settings.selectedFiles))
1382        return false;
1383#if ENABLE(MEDIA_CAPTURE)
1384    if (!decoder.decode(settings.capture))
1385        return false;
1386#endif
1387
1388    return true;
1389}
1390
1391
1392void ArgumentCoder<GrammarDetail>::encode(ArgumentEncoder& encoder, const GrammarDetail& detail)
1393{
1394    encoder << detail.location;
1395    encoder << detail.length;
1396    encoder << detail.guesses;
1397    encoder << detail.userDescription;
1398}
1399
1400bool ArgumentCoder<GrammarDetail>::decode(ArgumentDecoder& decoder, GrammarDetail& detail)
1401{
1402    if (!decoder.decode(detail.location))
1403        return false;
1404    if (!decoder.decode(detail.length))
1405        return false;
1406    if (!decoder.decode(detail.guesses))
1407        return false;
1408    if (!decoder.decode(detail.userDescription))
1409        return false;
1410
1411    return true;
1412}
1413
1414void ArgumentCoder<TextCheckingRequestData>::encode(ArgumentEncoder& encoder, const TextCheckingRequestData& request)
1415{
1416    encoder << request.sequence();
1417    encoder << request.text();
1418    encoder << request.mask();
1419    encoder.encodeEnum(request.processType());
1420}
1421
1422bool ArgumentCoder<TextCheckingRequestData>::decode(ArgumentDecoder& decoder, TextCheckingRequestData& request)
1423{
1424    int sequence;
1425    if (!decoder.decode(sequence))
1426        return false;
1427
1428    String text;
1429    if (!decoder.decode(text))
1430        return false;
1431
1432    TextCheckingTypeMask mask;
1433    if (!decoder.decode(mask))
1434        return false;
1435
1436    TextCheckingProcessType processType;
1437    if (!decoder.decodeEnum(processType))
1438        return false;
1439
1440    request = TextCheckingRequestData(sequence, text, mask, processType);
1441    return true;
1442}
1443
1444void ArgumentCoder<TextCheckingResult>::encode(ArgumentEncoder& encoder, const TextCheckingResult& result)
1445{
1446    encoder.encodeEnum(result.type);
1447    encoder << result.location;
1448    encoder << result.length;
1449    encoder << result.details;
1450    encoder << result.replacement;
1451}
1452
1453bool ArgumentCoder<TextCheckingResult>::decode(ArgumentDecoder& decoder, TextCheckingResult& result)
1454{
1455    if (!decoder.decodeEnum(result.type))
1456        return false;
1457    if (!decoder.decode(result.location))
1458        return false;
1459    if (!decoder.decode(result.length))
1460        return false;
1461    if (!decoder.decode(result.details))
1462        return false;
1463    if (!decoder.decode(result.replacement))
1464        return false;
1465    return true;
1466}
1467
1468void ArgumentCoder<URL>::encode(ArgumentEncoder& encoder, const URL& result)
1469{
1470    encoder << result.string();
1471}
1472
1473bool ArgumentCoder<URL>::decode(ArgumentDecoder& decoder, URL& result)
1474{
1475    String urlAsString;
1476    if (!decoder.decode(urlAsString))
1477        return false;
1478    result = URL(ParsedURLString, urlAsString);
1479    return true;
1480}
1481
1482void ArgumentCoder<UserStyleSheet>::encode(ArgumentEncoder& encoder, const UserStyleSheet& userStyleSheet)
1483{
1484    encoder << userStyleSheet.source();
1485    encoder << userStyleSheet.url();
1486    encoder << userStyleSheet.whitelist();
1487    encoder << userStyleSheet.blacklist();
1488    encoder.encodeEnum(userStyleSheet.injectedFrames());
1489    encoder.encodeEnum(userStyleSheet.level());
1490}
1491
1492bool ArgumentCoder<UserStyleSheet>::decode(ArgumentDecoder& decoder, UserStyleSheet& userStyleSheet)
1493{
1494    String source;
1495    if (!decoder.decode(source))
1496        return false;
1497
1498    URL url;
1499    if (!decoder.decode(url))
1500        return false;
1501
1502    Vector<String> whitelist;
1503    if (!decoder.decode(whitelist))
1504        return false;
1505
1506    Vector<String> blacklist;
1507    if (!decoder.decode(blacklist))
1508        return false;
1509
1510    UserContentInjectedFrames injectedFrames;
1511    if (!decoder.decodeEnum(injectedFrames))
1512        return false;
1513
1514    UserStyleLevel level;
1515    if (!decoder.decodeEnum(level))
1516        return false;
1517
1518    userStyleSheet = UserStyleSheet(source, url, whitelist, blacklist, injectedFrames, level);
1519    return true;
1520}
1521
1522void ArgumentCoder<UserScript>::encode(ArgumentEncoder& encoder, const UserScript& userScript)
1523{
1524    encoder << userScript.source();
1525    encoder << userScript.url();
1526    encoder << userScript.whitelist();
1527    encoder << userScript.blacklist();
1528    encoder.encodeEnum(userScript.injectionTime());
1529    encoder.encodeEnum(userScript.injectedFrames());
1530}
1531
1532bool ArgumentCoder<UserScript>::decode(ArgumentDecoder& decoder, UserScript& userScript)
1533{
1534    String source;
1535    if (!decoder.decode(source))
1536        return false;
1537
1538    URL url;
1539    if (!decoder.decode(url))
1540        return false;
1541
1542    Vector<String> whitelist;
1543    if (!decoder.decode(whitelist))
1544        return false;
1545
1546    Vector<String> blacklist;
1547    if (!decoder.decode(blacklist))
1548        return false;
1549
1550    UserScriptInjectionTime injectionTime;
1551    if (!decoder.decodeEnum(injectionTime))
1552        return false;
1553
1554    UserContentInjectedFrames injectedFrames;
1555    if (!decoder.decodeEnum(injectedFrames))
1556        return false;
1557
1558    userScript = UserScript(source, url, whitelist, blacklist, injectionTime, injectedFrames);
1559    return true;
1560}
1561
1562void ArgumentCoder<ScrollableAreaParameters>::encode(ArgumentEncoder& encoder, const ScrollableAreaParameters& parameters)
1563{
1564    encoder.encodeEnum(parameters.horizontalScrollElasticity);
1565    encoder.encodeEnum(parameters.verticalScrollElasticity);
1566
1567    encoder.encodeEnum(parameters.horizontalScrollbarMode);
1568    encoder.encodeEnum(parameters.verticalScrollbarMode);
1569
1570    encoder << parameters.hasEnabledHorizontalScrollbar;
1571    encoder << parameters.hasEnabledVerticalScrollbar;
1572}
1573
1574bool ArgumentCoder<ScrollableAreaParameters>::decode(ArgumentDecoder& decoder, ScrollableAreaParameters& params)
1575{
1576    if (!decoder.decodeEnum(params.horizontalScrollElasticity))
1577        return false;
1578    if (!decoder.decodeEnum(params.verticalScrollElasticity))
1579        return false;
1580
1581    if (!decoder.decodeEnum(params.horizontalScrollbarMode))
1582        return false;
1583    if (!decoder.decodeEnum(params.verticalScrollbarMode))
1584        return false;
1585
1586    if (!decoder.decode(params.hasEnabledHorizontalScrollbar))
1587        return false;
1588    if (!decoder.decode(params.hasEnabledVerticalScrollbar))
1589        return false;
1590
1591    return true;
1592}
1593
1594void ArgumentCoder<FixedPositionViewportConstraints>::encode(ArgumentEncoder& encoder, const FixedPositionViewportConstraints& viewportConstraints)
1595{
1596    encoder << viewportConstraints.alignmentOffset();
1597    encoder << viewportConstraints.anchorEdges();
1598
1599    encoder << viewportConstraints.viewportRectAtLastLayout();
1600    encoder << viewportConstraints.layerPositionAtLastLayout();
1601}
1602
1603bool ArgumentCoder<FixedPositionViewportConstraints>::decode(ArgumentDecoder& decoder, FixedPositionViewportConstraints& viewportConstraints)
1604{
1605    FloatSize alignmentOffset;
1606    if (!decoder.decode(alignmentOffset))
1607        return false;
1608
1609    ViewportConstraints::AnchorEdges anchorEdges;
1610    if (!decoder.decode(anchorEdges))
1611        return false;
1612
1613    FloatRect viewportRectAtLastLayout;
1614    if (!decoder.decode(viewportRectAtLastLayout))
1615        return false;
1616
1617    FloatPoint layerPositionAtLastLayout;
1618    if (!decoder.decode(layerPositionAtLastLayout))
1619        return false;
1620
1621    viewportConstraints = FixedPositionViewportConstraints();
1622    viewportConstraints.setAlignmentOffset(alignmentOffset);
1623    viewportConstraints.setAnchorEdges(anchorEdges);
1624
1625    viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout);
1626    viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
1627
1628    return true;
1629}
1630
1631void ArgumentCoder<StickyPositionViewportConstraints>::encode(ArgumentEncoder& encoder, const StickyPositionViewportConstraints& viewportConstraints)
1632{
1633    encoder << viewportConstraints.alignmentOffset();
1634    encoder << viewportConstraints.anchorEdges();
1635
1636    encoder << viewportConstraints.leftOffset();
1637    encoder << viewportConstraints.rightOffset();
1638    encoder << viewportConstraints.topOffset();
1639    encoder << viewportConstraints.bottomOffset();
1640
1641    encoder << viewportConstraints.constrainingRectAtLastLayout();
1642    encoder << viewportConstraints.containingBlockRect();
1643    encoder << viewportConstraints.stickyBoxRect();
1644
1645    encoder << viewportConstraints.stickyOffsetAtLastLayout();
1646    encoder << viewportConstraints.layerPositionAtLastLayout();
1647}
1648
1649bool ArgumentCoder<StickyPositionViewportConstraints>::decode(ArgumentDecoder& decoder, StickyPositionViewportConstraints& viewportConstraints)
1650{
1651    FloatSize alignmentOffset;
1652    if (!decoder.decode(alignmentOffset))
1653        return false;
1654
1655    ViewportConstraints::AnchorEdges anchorEdges;
1656    if (!decoder.decode(anchorEdges))
1657        return false;
1658
1659    float leftOffset;
1660    if (!decoder.decode(leftOffset))
1661        return false;
1662
1663    float rightOffset;
1664    if (!decoder.decode(rightOffset))
1665        return false;
1666
1667    float topOffset;
1668    if (!decoder.decode(topOffset))
1669        return false;
1670
1671    float bottomOffset;
1672    if (!decoder.decode(bottomOffset))
1673        return false;
1674
1675    FloatRect constrainingRectAtLastLayout;
1676    if (!decoder.decode(constrainingRectAtLastLayout))
1677        return false;
1678
1679    FloatRect containingBlockRect;
1680    if (!decoder.decode(containingBlockRect))
1681        return false;
1682
1683    FloatRect stickyBoxRect;
1684    if (!decoder.decode(stickyBoxRect))
1685        return false;
1686
1687    FloatSize stickyOffsetAtLastLayout;
1688    if (!decoder.decode(stickyOffsetAtLastLayout))
1689        return false;
1690
1691    FloatPoint layerPositionAtLastLayout;
1692    if (!decoder.decode(layerPositionAtLastLayout))
1693        return false;
1694
1695    viewportConstraints = StickyPositionViewportConstraints();
1696    viewportConstraints.setAlignmentOffset(alignmentOffset);
1697    viewportConstraints.setAnchorEdges(anchorEdges);
1698
1699    viewportConstraints.setLeftOffset(leftOffset);
1700    viewportConstraints.setRightOffset(rightOffset);
1701    viewportConstraints.setTopOffset(topOffset);
1702    viewportConstraints.setBottomOffset(bottomOffset);
1703
1704    viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout);
1705    viewportConstraints.setContainingBlockRect(containingBlockRect);
1706    viewportConstraints.setStickyBoxRect(stickyBoxRect);
1707
1708    viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout);
1709    viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout);
1710
1711    return true;
1712}
1713
1714#if ENABLE(CSS_FILTERS) && !USE(COORDINATED_GRAPHICS)
1715void ArgumentCoder<FilterOperation>::encode(ArgumentEncoder& encoder, const FilterOperation& filter)
1716{
1717    encoder.encodeEnum(filter.type());
1718
1719    switch (filter.type()) {
1720    case FilterOperation::NONE:
1721    case FilterOperation::REFERENCE:
1722        ASSERT_NOT_REACHED();
1723        break;
1724    case FilterOperation::GRAYSCALE:
1725    case FilterOperation::SEPIA:
1726    case FilterOperation::SATURATE:
1727    case FilterOperation::HUE_ROTATE:
1728        encoder << toBasicColorMatrixFilterOperation(filter).amount();
1729        break;
1730    case FilterOperation::INVERT:
1731    case FilterOperation::OPACITY:
1732    case FilterOperation::BRIGHTNESS:
1733    case FilterOperation::CONTRAST:
1734        encoder << toBasicComponentTransferFilterOperation(filter).amount();
1735        break;
1736    case FilterOperation::BLUR:
1737        encoder << toBlurFilterOperation(filter).stdDeviation();
1738        break;
1739    case FilterOperation::DROP_SHADOW: {
1740        const auto& dropShadowFilter = toDropShadowFilterOperation(filter);
1741        encoder << dropShadowFilter.location();
1742        encoder << dropShadowFilter.stdDeviation();
1743        encoder << dropShadowFilter.color();
1744        break;
1745    }
1746    case FilterOperation::DEFAULT:
1747        encoder.encodeEnum(toDefaultFilterOperation(filter).representedType());
1748        break;
1749    case FilterOperation::PASSTHROUGH:
1750        break;
1751    }
1752}
1753
1754bool decodeFilterOperation(ArgumentDecoder& decoder, RefPtr<FilterOperation>& filter)
1755{
1756    FilterOperation::OperationType type;
1757    if (!decoder.decodeEnum(type))
1758        return false;
1759
1760    switch (type) {
1761    case FilterOperation::NONE:
1762    case FilterOperation::REFERENCE:
1763        ASSERT_NOT_REACHED();
1764        decoder.markInvalid();
1765        return false;
1766    case FilterOperation::GRAYSCALE:
1767    case FilterOperation::SEPIA:
1768    case FilterOperation::SATURATE:
1769    case FilterOperation::HUE_ROTATE: {
1770        double amount;
1771        if (!decoder.decode(amount))
1772            return false;
1773        filter = BasicColorMatrixFilterOperation::create(amount, type);
1774        break;
1775    }
1776    case FilterOperation::INVERT:
1777    case FilterOperation::OPACITY:
1778    case FilterOperation::BRIGHTNESS:
1779    case FilterOperation::CONTRAST: {
1780        double amount;
1781        if (!decoder.decode(amount))
1782            return false;
1783        filter = BasicComponentTransferFilterOperation::create(amount, type);
1784        break;
1785    }
1786    case FilterOperation::BLUR: {
1787        Length stdDeviation;
1788        if (!decoder.decode(stdDeviation))
1789            return false;
1790        filter = BlurFilterOperation::create(stdDeviation);
1791        break;
1792    }
1793    case FilterOperation::DROP_SHADOW: {
1794        IntPoint location;
1795        int stdDeviation;
1796        Color color;
1797        if (!decoder.decode(location))
1798            return false;
1799        if (!decoder.decode(stdDeviation))
1800            return false;
1801        if (!decoder.decode(color))
1802            return false;
1803        filter = DropShadowFilterOperation::create(location, stdDeviation, color);
1804        break;
1805    }
1806    case FilterOperation::DEFAULT: {
1807        FilterOperation::OperationType representedType;
1808        if (!decoder.decodeEnum(representedType))
1809            return false;
1810        filter = DefaultFilterOperation::create(representedType);
1811        break;
1812    }
1813    case FilterOperation::PASSTHROUGH:
1814        filter = PassthroughFilterOperation::create();
1815        break;
1816    }
1817
1818    return true;
1819}
1820
1821
1822void ArgumentCoder<FilterOperations>::encode(ArgumentEncoder& encoder, const FilterOperations& filters)
1823{
1824    encoder << static_cast<uint64_t>(filters.size());
1825
1826    for (const auto& filter : filters.operations())
1827        encoder << *filter;
1828}
1829
1830bool ArgumentCoder<FilterOperations>::decode(ArgumentDecoder& decoder, FilterOperations& filters)
1831{
1832    uint64_t filterCount;
1833    if (!decoder.decode(filterCount))
1834        return false;
1835
1836    for (uint64_t i = 0; i < filterCount; ++i) {
1837        RefPtr<FilterOperation> filter;
1838        if (!decodeFilterOperation(decoder, filter))
1839            return false;
1840        filters.operations().append(WTF::move(filter));
1841    }
1842
1843    return true;
1844}
1845#endif // ENABLE(CSS_FILTERS) && !USE(COORDINATED_GRAPHICS)
1846
1847#if ENABLE(INDEXED_DATABASE)
1848void ArgumentCoder<IDBDatabaseMetadata>::encode(ArgumentEncoder& encoder, const IDBDatabaseMetadata& metadata)
1849{
1850    encoder << metadata.name << metadata.id << metadata.version << metadata.maxObjectStoreId << metadata.objectStores;
1851}
1852
1853bool ArgumentCoder<IDBDatabaseMetadata>::decode(ArgumentDecoder& decoder, IDBDatabaseMetadata& metadata)
1854{
1855    if (!decoder.decode(metadata.name))
1856        return false;
1857
1858    if (!decoder.decode(metadata.id))
1859        return false;
1860
1861    if (!decoder.decode(metadata.version))
1862        return false;
1863
1864    if (!decoder.decode(metadata.maxObjectStoreId))
1865        return false;
1866
1867    if (!decoder.decode(metadata.objectStores))
1868        return false;
1869
1870    return true;
1871}
1872
1873void ArgumentCoder<IDBIndexMetadata>::encode(ArgumentEncoder& encoder, const IDBIndexMetadata& metadata)
1874{
1875    encoder << metadata.name << metadata.id << metadata.keyPath << metadata.unique << metadata.multiEntry;
1876}
1877
1878bool ArgumentCoder<IDBIndexMetadata>::decode(ArgumentDecoder& decoder, IDBIndexMetadata& metadata)
1879{
1880    if (!decoder.decode(metadata.name))
1881        return false;
1882
1883    if (!decoder.decode(metadata.id))
1884        return false;
1885
1886    if (!decoder.decode(metadata.keyPath))
1887        return false;
1888
1889    if (!decoder.decode(metadata.unique))
1890        return false;
1891
1892    if (!decoder.decode(metadata.multiEntry))
1893        return false;
1894
1895    return true;
1896}
1897
1898void ArgumentCoder<IDBGetResult>::encode(ArgumentEncoder& encoder, const IDBGetResult& result)
1899{
1900    bool nullData = !result.valueBuffer;
1901    encoder << nullData;
1902
1903    if (!nullData)
1904        encoder << DataReference(reinterpret_cast<const uint8_t*>(result.valueBuffer->data()), result.valueBuffer->size());
1905
1906    encoder << result.keyData << result.keyPath;
1907}
1908
1909bool ArgumentCoder<IDBGetResult>::decode(ArgumentDecoder& decoder, IDBGetResult& result)
1910{
1911    bool nullData;
1912    if (!decoder.decode(nullData))
1913        return false;
1914
1915    if (nullData)
1916        result.valueBuffer = nullptr;
1917    else {
1918        DataReference data;
1919        if (!decoder.decode(data))
1920            return false;
1921
1922        result.valueBuffer = SharedBuffer::create(data.data(), data.size());
1923    }
1924
1925    if (!decoder.decode(result.keyData))
1926        return false;
1927
1928    if (!decoder.decode(result.keyPath))
1929        return false;
1930
1931    return true;
1932}
1933
1934void ArgumentCoder<IDBKeyData>::encode(ArgumentEncoder& encoder, const IDBKeyData& keyData)
1935{
1936    encoder << keyData.isNull;
1937    if (keyData.isNull)
1938        return;
1939
1940    encoder.encodeEnum(keyData.type);
1941
1942    switch (keyData.type) {
1943    case IDBKey::InvalidType:
1944        break;
1945    case IDBKey::ArrayType:
1946        encoder << keyData.arrayValue;
1947        break;
1948    case IDBKey::StringType:
1949        encoder << keyData.stringValue;
1950        break;
1951    case IDBKey::DateType:
1952    case IDBKey::NumberType:
1953        encoder << keyData.numberValue;
1954        break;
1955    case IDBKey::MaxType:
1956    case IDBKey::MinType:
1957        // MaxType and MinType are only used for comparison to other keys.
1958        // They should never be sent across the wire.
1959        ASSERT_NOT_REACHED();
1960        break;
1961    }
1962}
1963
1964bool ArgumentCoder<IDBKeyData>::decode(ArgumentDecoder& decoder, IDBKeyData& keyData)
1965{
1966    if (!decoder.decode(keyData.isNull))
1967        return false;
1968
1969    if (keyData.isNull)
1970        return true;
1971
1972    if (!decoder.decodeEnum(keyData.type))
1973        return false;
1974
1975    switch (keyData.type) {
1976    case IDBKey::InvalidType:
1977        break;
1978    case IDBKey::ArrayType:
1979        if (!decoder.decode(keyData.arrayValue))
1980            return false;
1981        break;
1982    case IDBKey::StringType:
1983        if (!decoder.decode(keyData.stringValue))
1984            return false;
1985        break;
1986    case IDBKey::DateType:
1987    case IDBKey::NumberType:
1988        if (!decoder.decode(keyData.numberValue))
1989            return false;
1990        break;
1991    case IDBKey::MaxType:
1992    case IDBKey::MinType:
1993        // MaxType and MinType are only used for comparison to other keys.
1994        // They should never be sent across the wire.
1995        ASSERT_NOT_REACHED();
1996        decoder.markInvalid();
1997        return false;
1998    }
1999
2000    return true;
2001}
2002
2003void ArgumentCoder<IDBKeyPath>::encode(ArgumentEncoder& encoder, const IDBKeyPath& keyPath)
2004{
2005    encoder.encodeEnum(keyPath.type());
2006
2007    switch (keyPath.type()) {
2008    case IDBKeyPath::NullType:
2009        break;
2010    case IDBKeyPath::StringType:
2011        encoder << keyPath.string();
2012        break;
2013    case IDBKeyPath::ArrayType:
2014        encoder << keyPath.array();
2015        break;
2016    default:
2017        ASSERT_NOT_REACHED();
2018    }
2019}
2020
2021bool ArgumentCoder<IDBKeyPath>::decode(ArgumentDecoder& decoder, IDBKeyPath& keyPath)
2022{
2023    IDBKeyPath::Type type;
2024    if (!decoder.decodeEnum(type))
2025        return false;
2026
2027    switch (type) {
2028    case IDBKeyPath::NullType:
2029        keyPath = IDBKeyPath();
2030        return true;
2031
2032    case IDBKeyPath::StringType: {
2033        String string;
2034        if (!decoder.decode(string))
2035            return false;
2036
2037        keyPath = IDBKeyPath(string);
2038        return true;
2039    }
2040    case IDBKeyPath::ArrayType: {
2041        Vector<String> array;
2042        if (!decoder.decode(array))
2043            return false;
2044
2045        keyPath = IDBKeyPath(array);
2046        return true;
2047    }
2048    default:
2049        return false;
2050    }
2051}
2052
2053void ArgumentCoder<IDBKeyRangeData>::encode(ArgumentEncoder& encoder, const IDBKeyRangeData& keyRange)
2054{
2055    encoder << keyRange.isNull;
2056    if (keyRange.isNull)
2057        return;
2058
2059    encoder << keyRange.upperKey << keyRange.lowerKey << keyRange.upperOpen << keyRange.lowerOpen;
2060}
2061
2062bool ArgumentCoder<IDBKeyRangeData>::decode(ArgumentDecoder& decoder, IDBKeyRangeData& keyRange)
2063{
2064    if (!decoder.decode(keyRange.isNull))
2065        return false;
2066
2067    if (keyRange.isNull)
2068        return true;
2069
2070    if (!decoder.decode(keyRange.upperKey))
2071        return false;
2072
2073    if (!decoder.decode(keyRange.lowerKey))
2074        return false;
2075
2076    if (!decoder.decode(keyRange.upperOpen))
2077        return false;
2078
2079    if (!decoder.decode(keyRange.lowerOpen))
2080        return false;
2081
2082    return true;
2083}
2084
2085void ArgumentCoder<IDBObjectStoreMetadata>::encode(ArgumentEncoder& encoder, const IDBObjectStoreMetadata& metadata)
2086{
2087    encoder << metadata.name << metadata.id << metadata.keyPath << metadata.autoIncrement << metadata.maxIndexId << metadata.indexes;
2088}
2089
2090bool ArgumentCoder<IDBObjectStoreMetadata>::decode(ArgumentDecoder& decoder, IDBObjectStoreMetadata& metadata)
2091{
2092    if (!decoder.decode(metadata.name))
2093        return false;
2094
2095    if (!decoder.decode(metadata.id))
2096        return false;
2097
2098    if (!decoder.decode(metadata.keyPath))
2099        return false;
2100
2101    if (!decoder.decode(metadata.autoIncrement))
2102        return false;
2103
2104    if (!decoder.decode(metadata.maxIndexId))
2105        return false;
2106
2107    if (!decoder.decode(metadata.indexes))
2108        return false;
2109
2110    return true;
2111}
2112
2113#endif // ENABLE(INDEXED_DATABASE)
2114
2115void ArgumentCoder<SessionID>::encode(ArgumentEncoder& encoder, const SessionID& sessionID)
2116{
2117    encoder << sessionID.sessionID();
2118}
2119
2120bool ArgumentCoder<SessionID>::decode(ArgumentDecoder& decoder, SessionID& sessionID)
2121{
2122    uint64_t session;
2123    if (!decoder.decode(session))
2124        return false;
2125
2126    sessionID = SessionID(session);
2127
2128    return true;
2129}
2130
2131void ArgumentCoder<BlobPart>::encode(ArgumentEncoder& encoder, const BlobPart& blobPart)
2132{
2133    encoder << static_cast<uint32_t>(blobPart.type());
2134    switch (blobPart.type()) {
2135    case BlobPart::Data:
2136        encoder << blobPart.data();
2137        break;
2138    case BlobPart::Blob:
2139        encoder << blobPart.url();
2140        break;
2141    }
2142}
2143
2144bool ArgumentCoder<BlobPart>::decode(ArgumentDecoder& decoder, BlobPart& blobPart)
2145{
2146    uint32_t type;
2147    if (!decoder.decode(type))
2148        return false;
2149
2150    switch (type) {
2151    case BlobPart::Data: {
2152        Vector<char> data;
2153        if (!decoder.decode(data))
2154            return false;
2155        blobPart = BlobPart(WTF::move(data));
2156        break;
2157    }
2158    case BlobPart::Blob: {
2159        String url;
2160        if (!decoder.decode(url))
2161            return false;
2162        blobPart = BlobPart(URL(URL(), url));
2163        break;
2164    }
2165    default:
2166        return false;
2167    }
2168
2169    return true;
2170}
2171
2172} // namespace IPC
2173