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 ArgumentDecoder_h
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#define ArgumentDecoder_h
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ArgumentCoder.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "Attachment.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/Deque.h>
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/TypeTraits.h>
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <wtf/Vector.h>
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace CoreIPC {
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass DataReference;
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass ArgumentDecoder {
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochpublic:
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ArgumentDecoder(const uint8_t* buffer, size_t bufferSize);
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ArgumentDecoder(const uint8_t* buffer, size_t bufferSize, Deque<Attachment>&);
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ~ArgumentDecoder();
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint64_t destinationID() const { return m_destinationID; }
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool isInvalid() const { return m_bufferPos > m_bufferEnd; }
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    void markInvalid() { m_bufferPos = m_bufferEnd + 1; }
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeBytes(Vector<uint8_t>&);
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeBytes(uint8_t*, size_t);
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // The data in the data reference here will only be valid for the lifetime of the ArgumentDecoder object.
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeBytes(DataReference&);
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeBool(bool&);
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeUInt32(uint32_t&);
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeUInt64(uint64_t&);
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeInt32(int32_t&);
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeInt64(int64_t&);
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeFloat(float&);
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool decodeDouble(double&);
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    template<typename T> bool decodeEnum(T& result)
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        COMPILE_ASSERT(sizeof(T) <= sizeof(uint64_t), enum_type_must_not_be_larger_than_64_bits);
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint64_t value;
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!decodeUInt64(value))
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        result = static_cast<T>(value);
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    template<typename T>
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool bufferIsLargeEnoughToContain(size_t numElements) const
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        COMPILE_ASSERT(WTF::IsArithmetic<T>::value, type_must_have_known_encoded_size);
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (numElements > std::numeric_limits<size_t>::max() / sizeof(T))
8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return false;
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return bufferIsLargeEnoughToContain(__alignof(T), numElements * sizeof(T));
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Generic type decode function.
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    template<typename T> bool decode(T& t)
8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return ArgumentCoder<T>::decode(this, t);
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // This overload exists so we can pass temporaries to decode. In the Star Trek future, it
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // can take an rvalue reference instead.
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    template<typename T> bool decode(const T& t)
9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    {
9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return decode(const_cast<T&>(t));
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool removeAttachment(Attachment&);
10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifndef NDEBUG
10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    void debug();
10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif
10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochprivate:
10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ArgumentDecoder(const ArgumentDecoder*);
10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ArgumentDecoder* operator=(const ArgumentDecoder*);
10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    void initialize(const uint8_t* buffer, size_t bufferSize);
11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool alignBufferPosition(unsigned alignment, size_t size);
11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool bufferIsLargeEnoughToContain(unsigned alignment, size_t size) const;
11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint64_t m_destinationID;
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint8_t* m_buffer;
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint8_t* m_bufferPos;
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint8_t* m_bufferEnd;
12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Deque<Attachment> m_attachments;
12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(bool& n)
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeBool(n);
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(uint32_t& n)
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeUInt32(n);
13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(uint64_t& n)
13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeUInt64(n);
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(int32_t& n)
14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeInt32(n);
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(int64_t& n)
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeInt64(n);
14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(float& n)
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeFloat(n);
15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochtemplate<> inline bool ArgumentDecoder::decode(double& n)
15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
15665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return decodeDouble(n);
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace CoreIPC
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif // ArgumentDecoder_h
162