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
2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifndef SimpleArgumentCoder_h
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#define SimpleArgumentCoder_h
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ArgumentDecoder.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ArgumentEncoder.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <utility>
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/HashMap.h>
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/TypeTraits.h>
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/Vector.h>
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/text/AtomicString.h>
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/text/CString.h>
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/text/WTFString.h>
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace CoreIPC {
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// An argument coder works on POD types
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<typename T> struct SimpleArgumentCoder {
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const T& t)
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeBytes(reinterpret_cast<const uint8_t*>(&t), sizeof(T));
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, T& t)
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return decoder->decodeBytes(reinterpret_cast<uint8_t*>(&t), sizeof(T));
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<typename T, typename U> struct ArgumentCoder<std::pair<T, U> > {
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const std::pair<T, U>& pair)
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encode(pair.first);
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encode(pair.second);
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, std::pair<T, U>& pair)
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        T first;
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decode(first))
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        U second;
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decode(second))
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        pair.first = first;
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        pair.second = second;
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<bool fixedSizeElements, typename T> struct VectorArgumentCoder;
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<typename T> struct VectorArgumentCoder<false, T> {
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const Vector<T>& vector)
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeUInt64(vector.size());
8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (size_t i = 0; i < vector.size(); ++i)
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            encoder->encode(vector[i]);
8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, Vector<T>& vector)
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint64_t size;
8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decodeUInt64(size))
9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        Vector<T> tmp;
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (size_t i = 0; i < size; ++i) {
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            T element;
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (!decoder->decode(element))
9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return false;
9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            tmp.append(element);
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        tmp.shrinkToFit();
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        vector.swap(tmp);
10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<typename T> struct VectorArgumentCoder<true, T> {
10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const Vector<T>& vector)
10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeUInt64(vector.size());
11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // FIXME: If we could tell the encoder to align the buffer, we could just do an encodeBytes here.
11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (size_t i = 0; i < vector.size(); ++i)
11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            encoder->encode(vector[i]);
11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
11565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, Vector<T>& vector)
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint64_t size;
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decodeUInt64(size))
12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Since we know the total size of the elements, we can allocate the vector in
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // one fell swoop. Before allocating we must however make sure that the decoder buffer
12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // is big enough.
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->bufferIsLargeEnoughToContain<T>(size)) {
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            decoder->markInvalid();
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        Vector<T> tmp;
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        tmp.reserveCapacity(size);
13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (size_t i = 0; i < size; ++i) {
13465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            T element;
13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (!decoder->decode(element))
13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return false;
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            tmp.uncheckedAppend(element);
13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        vector.swap(tmp);
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<typename T> struct ArgumentCoder<Vector<T> > : VectorArgumentCoder<WTF::IsArithmetic<T>::value, T> { };
14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// Specialization for Vector<uint8_t>
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> struct ArgumentCoder<Vector<uint8_t> > {
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const Vector<uint8_t>& vector)
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeBytes(vector.data(), vector.size());
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, Vector<uint8_t>& vector)
15665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return decoder->decodeBytes(vector);
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct ArgumentCoder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > {
16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const HashMapType& hashMap)
16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeUInt64(hashMap.size());
16765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it)
16865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            encoder->encode(*it);
16965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
17065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, HashMapType& hashMap)
17265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
17365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint64_t hashMapSize;
17465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decode(hashMapSize))
17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        HashMapType tempHashMap;
17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (uint64_t i = 0; i < hashMapSize; ++i) {
17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            KeyArg key;
18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            MappedArg value;
18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (!decoder->decode(key))
18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return false;
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (!decoder->decode(value))
18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return false;
18565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
18665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (!tempHashMap.add(key, value).second) {
18765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                // The hash map already has the specified key, bail.
18865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                decoder->markInvalid();
18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                return false;
19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            }
19165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
19365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        hashMap.swap(tempHashMap);
19465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
19565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
19665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
19765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
19865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> struct ArgumentCoder<CString> {
19965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const CString& string)
20065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
20165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Special case the null string.
20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (string.isNull()) {
20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            encoder->encodeUInt32(std::numeric_limits<uint32_t>::max());
20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return;
20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint32_t length = string.length();
20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encode(length);
20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeBytes(reinterpret_cast<const uint8_t*>(string.data()), length);
21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, CString& result)
21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint32_t length;
21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decode(length))
21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (length == std::numeric_limits<uint32_t>::max()) {
21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // This is the null string.
22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            result = CString();
22165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return true;
22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Before allocating the string, make sure that the decoder buffer is big enough.
22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->bufferIsLargeEnoughToContain<char>(length)) {
22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            decoder->markInvalid();
22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        char* buffer;
23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        CString string = CString::newUninitialized(length, buffer);
23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decodeBytes(reinterpret_cast<uint8_t*>(buffer), length))
23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result = string;
23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> struct ArgumentCoder<String> {
24165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const String& string)
24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Special case the null string.
24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (string.isNull()) {
24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            encoder->encodeUInt32(std::numeric_limits<uint32_t>::max());
24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return;
24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint32_t length = string.length();
25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encode(length);
25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encodeBytes(reinterpret_cast<const uint8_t*>(string.characters()), length * sizeof(UChar));
25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, String& result)
25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
25665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint32_t length;
25765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decode(length))
25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (length == std::numeric_limits<uint32_t>::max()) {
26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // This is the null string.
26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            result = String();
26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return true;
26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Before allocating the string, make sure that the decoder buffer is big enough.
26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->bufferIsLargeEnoughToContain<UChar>(length)) {
26865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            decoder->markInvalid();
26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
27065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
27165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        UChar* buffer;
27365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        String string = String::createUninitialized(length, buffer);
27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decodeBytes(reinterpret_cast<uint8_t*>(buffer), length * sizeof(UChar)))
27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result = string;
27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> struct ArgumentCoder<AtomicString> {
28365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static void encode(ArgumentEncoder* encoder, const AtomicString& atomicString)
28465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        encoder->encode(atomicString.string());
28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
28765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
28865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    static bool decode(ArgumentDecoder* decoder, AtomicString& atomicString)
28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        String string;
29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decoder->decode(string))
29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        atomicString = string;
29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
29665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace CoreIPC
30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif // SimpleArgumentCoder_h
302