• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/Deque.h>
32 #include <wtf/TypeTraits.h>
33 #include <wtf/Vector.h>
34 
35 namespace CoreIPC {
36 
37 class DataReference;
38 
39 class ArgumentDecoder {
40 public:
41     ArgumentDecoder(const uint8_t* buffer, size_t bufferSize);
42     ArgumentDecoder(const uint8_t* buffer, size_t bufferSize, Deque<Attachment>&);
43     ~ArgumentDecoder();
44 
destinationID()45     uint64_t destinationID() const { return m_destinationID; }
46 
isInvalid()47     bool isInvalid() const { return m_bufferPos > m_bufferEnd; }
markInvalid()48     void markInvalid() { m_bufferPos = m_bufferEnd + 1; }
49 
50     bool decodeBytes(Vector<uint8_t>&);
51     bool decodeBytes(uint8_t*, size_t);
52 
53     // The data in the data reference here will only be valid for the lifetime of the ArgumentDecoder object.
54     bool decodeBytes(DataReference&);
55 
56     bool decodeBool(bool&);
57     bool decodeUInt32(uint32_t&);
58     bool decodeUInt64(uint64_t&);
59     bool decodeInt32(int32_t&);
60     bool decodeInt64(int64_t&);
61     bool decodeFloat(float&);
62     bool decodeDouble(double&);
63 
decodeEnum(T & result)64     template<typename T> bool decodeEnum(T& result)
65     {
66         COMPILE_ASSERT(sizeof(T) <= sizeof(uint64_t), enum_type_must_not_be_larger_than_64_bits);
67 
68         uint64_t value;
69         if (!decodeUInt64(value))
70             return false;
71 
72         result = static_cast<T>(value);
73         return true;
74     }
75 
76     template<typename T>
bufferIsLargeEnoughToContain(size_t numElements)77     bool bufferIsLargeEnoughToContain(size_t numElements) const
78     {
79         COMPILE_ASSERT(WTF::IsArithmetic<T>::value, type_must_have_known_encoded_size);
80 
81         if (numElements > std::numeric_limits<size_t>::max() / sizeof(T))
82             return false;
83 
84         return bufferIsLargeEnoughToContain(__alignof(T), numElements * sizeof(T));
85     }
86 
87     // Generic type decode function.
decode(T & t)88     template<typename T> bool decode(T& t)
89     {
90         return ArgumentCoder<T>::decode(this, t);
91     }
92 
93     // This overload exists so we can pass temporaries to decode. In the Star Trek future, it
94     // can take an rvalue reference instead.
decode(const T & t)95     template<typename T> bool decode(const T& t)
96     {
97         return decode(const_cast<T&>(t));
98     }
99 
100     bool removeAttachment(Attachment&);
101 
102 #ifndef NDEBUG
103     void debug();
104 #endif
105 
106 private:
107     ArgumentDecoder(const ArgumentDecoder*);
108     ArgumentDecoder* operator=(const ArgumentDecoder*);
109 
110     void initialize(const uint8_t* buffer, size_t bufferSize);
111 
112     bool alignBufferPosition(unsigned alignment, size_t size);
113     bool bufferIsLargeEnoughToContain(unsigned alignment, size_t size) const;
114 
115     uint64_t m_destinationID;
116 
117     uint8_t* m_buffer;
118     uint8_t* m_bufferPos;
119     uint8_t* m_bufferEnd;
120 
121     Deque<Attachment> m_attachments;
122 };
123 
decode(bool & n)124 template<> inline bool ArgumentDecoder::decode(bool& n)
125 {
126     return decodeBool(n);
127 }
128 
decode(uint32_t & n)129 template<> inline bool ArgumentDecoder::decode(uint32_t& n)
130 {
131     return decodeUInt32(n);
132 }
133 
decode(uint64_t & n)134 template<> inline bool ArgumentDecoder::decode(uint64_t& n)
135 {
136     return decodeUInt64(n);
137 }
138 
decode(int32_t & n)139 template<> inline bool ArgumentDecoder::decode(int32_t& n)
140 {
141     return decodeInt32(n);
142 }
143 
decode(int64_t & n)144 template<> inline bool ArgumentDecoder::decode(int64_t& n)
145 {
146     return decodeInt64(n);
147 }
148 
decode(float & n)149 template<> inline bool ArgumentDecoder::decode(float& n)
150 {
151     return decodeFloat(n);
152 }
153 
decode(double & n)154 template<> inline bool ArgumentDecoder::decode(double& n)
155 {
156     return decodeDouble(n);
157 }
158 
159 } // namespace CoreIPC
160 
161 #endif // ArgumentDecoder_h
162