1/*
2 * Copyright (C) 2010 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#ifndef ArgumentDecoder_h
27#define ArgumentDecoder_h
28
29#include "ArgumentCoder.h"
30#include "Attachment.h"
31#include <wtf/Vector.h>
32
33namespace IPC {
34
35class DataReference;
36
37class ArgumentDecoder {
38    WTF_MAKE_FAST_ALLOCATED;
39public:
40    ArgumentDecoder(const uint8_t* buffer, size_t bufferSize);
41    virtual ~ArgumentDecoder();
42
43    size_t length() const { return m_bufferEnd - m_buffer; }
44
45    bool isInvalid() const { return m_bufferPos > m_bufferEnd; }
46    void markInvalid() { m_bufferPos = m_bufferEnd + 1; }
47
48    bool decodeFixedLengthData(uint8_t*, size_t, unsigned alignment);
49
50    // The data in the data reference here will only be valid for the lifetime of the ArgumentDecoder object.
51    bool decodeVariableLengthByteArray(DataReference&);
52
53    bool decode(bool&);
54    bool decode(uint8_t&);
55    bool decode(uint16_t&);
56    bool decode(uint32_t&);
57    bool decode(uint64_t&);
58    bool decode(int32_t&);
59    bool decode(int64_t&);
60    bool decode(float&);
61    bool decode(double&);
62
63    template<typename T> bool decodeEnum(T& result)
64    {
65        static_assert(sizeof(T) <= 8, "Enum type T must not be larger than 64 bits!");
66
67        uint64_t value;
68        if (!decode(value))
69            return false;
70
71        result = static_cast<T>(value);
72        return true;
73    }
74
75    template<typename T>
76    bool bufferIsLargeEnoughToContain(size_t numElements) const
77    {
78        static_assert(std::is_arithmetic<T>::value, "Type T must have a fixed, known encoded size!");
79
80        if (numElements > std::numeric_limits<size_t>::max() / sizeof(T))
81            return false;
82
83        return bufferIsLargeEnoughToContain(alignof(T), numElements * sizeof(T));
84    }
85
86    // Generic type decode function.
87    template<typename T> bool decode(T& t)
88    {
89        return ArgumentCoder<T>::decode(*this, t);
90    }
91
92    bool removeAttachment(Attachment&);
93
94protected:
95    ArgumentDecoder(const uint8_t* buffer, size_t bufferSize, Vector<Attachment>);
96
97    void initialize(const uint8_t* buffer, size_t bufferSize);
98
99    bool alignBufferPosition(unsigned alignment, size_t size);
100    bool bufferIsLargeEnoughToContain(unsigned alignment, size_t size) const;
101
102private:
103    uint8_t* m_buffer;
104    uint8_t* m_bufferPos;
105    uint8_t* m_bufferEnd;
106
107    Vector<Attachment> m_attachments;
108};
109
110} // namespace IPC
111
112#endif // ArgumentDecoder_h
113