165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met:
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer.
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    documentation and/or other materials provided with the distribution.
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h"
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ArgumentCodersCF.h"
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ArgumentDecoder.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ArgumentEncoder.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "DataReference.h"
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/Vector.h>
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace CoreIPC {
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochCFTypeRef tokenNullTypeRef()
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static CFStringRef tokenNullType = CFSTR("WKNull");
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return tokenNullType;
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochenum CFType {
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFArray,
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFBoolean,
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFData,
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFDictionary,
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFNull,
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFNumber,
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFString,
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFURL,
512bde8e466a4451c7319e3a072d118917957d6554Steve Block#if PLATFORM(MAC)
522bde8e466a4451c7319e3a072d118917957d6554Steve Block    SecCertificate,
532bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Null,
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Unknown,
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic CFType typeFromCFTypeRef(CFTypeRef type)
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(type);
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (type == tokenNullTypeRef())
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return Null;
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFTypeID typeID = CFGetTypeID(type);
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFArrayGetTypeID())
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFArray;
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFBooleanGetTypeID())
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFBoolean;
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFDataGetTypeID())
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFData;
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFDictionaryGetTypeID())
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFDictionary;
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFNullGetTypeID())
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFNull;
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFNumberGetTypeID())
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFNumber;
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFStringGetTypeID())
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFString;
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (typeID == CFURLGetTypeID())
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return CFURL;
822bde8e466a4451c7319e3a072d118917957d6554Steve Block#if PLATFORM(MAC)
832bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (typeID == SecCertificateGetTypeID())
842bde8e466a4451c7319e3a072d118917957d6554Steve Block        return SecCertificate;
852bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT_NOT_REACHED();
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return Unknown;
8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic void encode(ArgumentEncoder* encoder, CFTypeRef typeRef)
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFType type = typeFromCFTypeRef(typeRef);
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeEnum(type);
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    switch (type) {
9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFArray:
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFArrayRef>(typeRef));
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFBoolean:
10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFBooleanRef>(typeRef));
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFData:
10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFDataRef>(typeRef));
10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFDictionary:
10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFDictionaryRef>(typeRef));
10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFNull:
11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFNumber:
11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFNumberRef>(typeRef));
11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFString:
11565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFStringRef>(typeRef));
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFURL:
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFURLRef>(typeRef));
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block#if PLATFORM(MAC)
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block    case SecCertificate:
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block        encode(encoder, (SecCertificateRef)typeRef);
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case Null:
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case Unknown:
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        break;
12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT_NOT_REACHED();
13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool decode(ArgumentDecoder* decoder, RetainPtr<CFTypeRef>& result)
13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFType type;
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decodeEnum(type))
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    switch (type) {
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFArray: {
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFArrayRef> array;
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, array))
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(array.leakRef());
14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFBoolean: {
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFBooleanRef> boolean;
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, boolean))
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(boolean.leakRef());
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFData: {
15665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFDataRef> data;
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, data))
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(data.leakRef());
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFDictionary: {
16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFDictionaryRef> dictionary;
16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, dictionary))
16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(dictionary.leakRef());
16765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
16865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
16965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFNull:
17065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(kCFNull);
17165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
17265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFNumber: {
17365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFNumberRef> number;
17465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, number))
17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(number.leakRef());
17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFString: {
18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFStringRef> string;
18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, string))
18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(string.leakRef());
18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
18565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
18665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case CFURL: {
18765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFURLRef> url;
18865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, url))
18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result.adoptCF(url.leakRef());
19165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
1932bde8e466a4451c7319e3a072d118917957d6554Steve Block#if PLATFORM(MAC)
1942bde8e466a4451c7319e3a072d118917957d6554Steve Block    case SecCertificate: {
1952bde8e466a4451c7319e3a072d118917957d6554Steve Block        RetainPtr<SecCertificateRef> certificate;
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!decode(decoder, certificate))
1972bde8e466a4451c7319e3a072d118917957d6554Steve Block            return false;
1982bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.adoptCF(certificate.leakRef());
1992bde8e466a4451c7319e3a072d118917957d6554Steve Block        return true;
2002bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2012bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case Null:
20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result = tokenNullTypeRef();
20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case Unknown:
20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT_NOT_REACHED();
20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return false;
21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFArrayRef array)
21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFIndex size = CFArrayGetCount(array);
21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<CFTypeRef, 32> values(size);
21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFArrayGetValues(array, CFRangeMake(0, size), values.data());
21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeUInt64(size);
22165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (CFIndex i = 0; i < size; ++i) {
22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(values[i]);
22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, values[i]);
22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFArrayRef>& result)
22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint64_t size;
23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decodeUInt64(size))
23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (size_t i = 0; i < size; ++i) {
23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFTypeRef> element;
23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, element))
23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        CFArrayAppendValue(array.get(), element.get());
24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(array.leakRef());
24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFBooleanRef boolean)
24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeBool(CFBooleanGetValue(boolean));
25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFBooleanRef>& result)
25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool boolean;
25665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decode(boolean))
25765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(boolean ? kCFBooleanTrue : kCFBooleanFalse);
26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFDataRef data)
26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFIndex length = CFDataGetLength(data);
26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    const UInt8* bytePtr = CFDataGetBytePtr(data);
26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeBytes(bytePtr, length);
26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
27065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
27165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFDataRef>& result)
27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
27365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CoreIPC::DataReference dataReference;
27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decode(dataReference))
27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(CFDataCreate(0, dataReference.data(), dataReference.size()));
27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFDictionaryRef dictionary)
28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
28365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFIndex size = CFDictionaryGetCount(dictionary);
28465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<CFTypeRef, 32> keys(size);
28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<CFTypeRef, 32> values(size);
28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
28765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFDictionaryGetKeysAndValues(dictionary, keys.data(), values.data());
28865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeUInt64(size);
29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (CFIndex i = 0; i < size; ++i) {
29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(keys[i]);
29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(CFGetTypeID(keys[i]) == CFStringGetTypeID());
29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(values[i]);
29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
29665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Ignore values we don't recognize.
29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (typeFromCFTypeRef(values[i]) == Unknown)
29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            continue;
29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, static_cast<CFStringRef>(keys[i]));
30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, values[i]);
30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFDictionaryRef>& result)
30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint64_t size;
30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decodeUInt64(size))
30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RetainPtr<CFMutableDictionaryRef> dictionary(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (uint64_t i = 0; i < size; ++i) {
31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Try to decode the key name.
31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFStringRef> key;
31565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, key))
31665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RetainPtr<CFTypeRef> value;
31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, value))
32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        CFDictionarySetValue(dictionary.get(), key.get(), value.get());
32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(dictionary.releaseRef());
32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
32865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFNumberRef number)
33065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
33165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFNumberType numberType = CFNumberGetType(number);
33265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
33365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<uint8_t> buffer(CFNumberGetByteSize(number));
33465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool result = CFNumberGetValue(number, numberType, buffer.data());
33565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT_UNUSED(result, result);
33665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
33765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeEnum(numberType);
33865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeBytes(buffer.data(), buffer.size());
33965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
34065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
34165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic size_t sizeForNumberType(CFNumberType numberType)
34265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
34365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    switch (numberType) {
34465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberSInt8Type:
34565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(SInt8);
34665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberSInt16Type:
34765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(SInt16);
34865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberSInt32Type:
34965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(SInt32);
35065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberSInt64Type:
35165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(SInt64);
35265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberFloat32Type:
35365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(Float32);
35465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberFloat64Type:
35565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(Float64);
35665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberCharType:
35765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(char);
35865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberShortType:
35965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(short);
36065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberIntType:
36165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(int);
36265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberLongType:
36365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(long);
36465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberLongLongType:
36565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(long long);
36665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberFloatType:
36765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(float);
36865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberDoubleType:
36965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(double);
37065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberCFIndexType:
37165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(CFIndex);
37265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberNSIntegerType:
37365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifdef __LP64__
37465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(long);
37565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else
37665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(int);
37765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif
37865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    case kCFNumberCGFloatType:
37965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifdef __LP64__
38065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(double);
38165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else
38265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return sizeof(float);
38365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif
38465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
38565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
38665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return 0;
38765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
38865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
38965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFNumberRef>& result)
39065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
39165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFNumberType numberType;
39265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decodeEnum(numberType))
39365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
39465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
39565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CoreIPC::DataReference dataReference;
39665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decode(dataReference))
39765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
39865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
39965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    size_t neededBufferSize = sizeForNumberType(numberType);
40065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!neededBufferSize || dataReference.size() != neededBufferSize)
40165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
40265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
40365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(dataReference.data());
40465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFNumberRef number = CFNumberCreate(0, numberType, dataReference.data());
40565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(number);
40665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
40765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
40865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
40965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
41065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFStringRef string)
41165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
41265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFIndex length = CFStringGetLength(string);
41365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFStringEncoding encoding = CFStringGetFastestEncoding(string);
41465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
41565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFRange range = CFRangeMake(0, length);
41665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFIndex bufferLength = 0;
41765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
41865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFIndex numConvertedBytes = CFStringGetBytes(string, range, encoding, 0, false, 0, 0, &bufferLength);
41965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(numConvertedBytes == length);
42065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
42165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<UInt8, 128> buffer(bufferLength);
42265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    numConvertedBytes = CFStringGetBytes(string, range, encoding, 0, false, buffer.data(), buffer.size(), &bufferLength);
42365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(numConvertedBytes == length);
42465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
42565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeEnum(encoding);
42665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeBytes(buffer.data(), bufferLength);
42765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
42865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
42965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFStringRef>& result)
43065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
43165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFStringEncoding encoding;
43265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decodeEnum(encoding))
43365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
43465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
43565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!CFStringIsEncodingAvailable(encoding))
43665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
43765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
43865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CoreIPC::DataReference dataReference;
43965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decode(dataReference))
44065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
44165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
44265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFStringRef string = CFStringCreateWithBytes(0, dataReference.data(), dataReference.size(), encoding, false);
44365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!string)
44465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
44565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
44665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(string);
44765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
44865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
44965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
45065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid encode(ArgumentEncoder* encoder, CFURLRef url)
45165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
45265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFURLRef baseURL = CFURLGetBaseURL(url);
45365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encoder->encodeBool(baseURL);
45465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (baseURL)
45565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encode(encoder, baseURL);
45665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
45765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    encode(encoder, CFURLGetString(url));
45865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
45965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
46065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool decode(ArgumentDecoder* decoder, RetainPtr<CFURLRef>& result)
46165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
46265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RetainPtr<CFURLRef> baseURL;
46365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool hasBaseURL;
46465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decoder->decodeBool(hasBaseURL))
46565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
46665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (hasBaseURL) {
46765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decode(decoder, baseURL))
46865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
46965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
47065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
47165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RetainPtr<CFStringRef> string;
47265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!decode(decoder, string))
47365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
47465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
47565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    CFURLRef url = CFURLCreateWithString(0, string.get(), baseURL.get());
47665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!url)
47765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
47865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
47965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    result.adoptCF(url);
48065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
48165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
48265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4832bde8e466a4451c7319e3a072d118917957d6554Steve Block#if PLATFORM(MAC)
4842bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid encode(ArgumentEncoder* encoder, SecCertificateRef certificate)
4852bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4862bde8e466a4451c7319e3a072d118917957d6554Steve Block    RetainPtr<CFDataRef> data(AdoptCF, SecCertificateCopyData(certificate));
4872bde8e466a4451c7319e3a072d118917957d6554Steve Block    encode(encoder, data.get());
4882bde8e466a4451c7319e3a072d118917957d6554Steve Block}
48965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4902bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool decode(ArgumentDecoder* decoder, RetainPtr<SecCertificateRef>& result)
4912bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4922bde8e466a4451c7319e3a072d118917957d6554Steve Block    RetainPtr<CFDataRef> data;
4932bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!decode(decoder, data))
4942bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
4952bde8e466a4451c7319e3a072d118917957d6554Steve Block
4962bde8e466a4451c7319e3a072d118917957d6554Steve Block    result.adoptCF(SecCertificateCreateWithData(0, data.get()));
4972bde8e466a4451c7319e3a072d118917957d6554Steve Block    return true;
4982bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4992bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
5002bde8e466a4451c7319e3a072d118917957d6554Steve Block
5012bde8e466a4451c7319e3a072d118917957d6554Steve Block} // namespace CoreIPC
502