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 45 uint64_t destinationID() const { return m_destinationID; } 46 47 bool isInvalid() const { return m_bufferPos > m_bufferEnd; } 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 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> 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. 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. 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 124 template<> inline bool ArgumentDecoder::decode(bool& n) 125 { 126 return decodeBool(n); 127 } 128 129 template<> inline bool ArgumentDecoder::decode(uint32_t& n) 130 { 131 return decodeUInt32(n); 132 } 133 134 template<> inline bool ArgumentDecoder::decode(uint64_t& n) 135 { 136 return decodeUInt64(n); 137 } 138 139 template<> inline bool ArgumentDecoder::decode(int32_t& n) 140 { 141 return decodeInt32(n); 142 } 143 144 template<> inline bool ArgumentDecoder::decode(int64_t& n) 145 { 146 return decodeInt64(n); 147 } 148 149 template<> inline bool ArgumentDecoder::decode(float& n) 150 { 151 return decodeFloat(n); 152 } 153 154 template<> inline bool ArgumentDecoder::decode(double& n) 155 { 156 return decodeDouble(n); 157 } 158 159 } // namespace CoreIPC 160 161 #endif // ArgumentDecoder_h 162