1/* 2 * Copyright (C) 2011 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#include "config.h" 27#include "ArgumentCoders.h" 28 29#include "DataReference.h" 30#include <wtf/text/CString.h> 31#include <wtf/text/WTFString.h> 32 33namespace IPC { 34 35void ArgumentCoder<AtomicString>::encode(ArgumentEncoder& encoder, const AtomicString& atomicString) 36{ 37 encoder << atomicString.string(); 38} 39 40bool ArgumentCoder<AtomicString>::decode(ArgumentDecoder& decoder, AtomicString& atomicString) 41{ 42 String string; 43 if (!decoder.decode(string)) 44 return false; 45 46 atomicString = string; 47 return true; 48} 49 50void ArgumentCoder<CString>::encode(ArgumentEncoder& encoder, const CString& string) 51{ 52 // Special case the null string. 53 if (string.isNull()) { 54 encoder << std::numeric_limits<uint32_t>::max(); 55 return; 56 } 57 58 uint32_t length = string.length(); 59 encoder << length; 60 encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(string.data()), length, 1); 61} 62 63bool ArgumentCoder<CString>::decode(ArgumentDecoder& decoder, CString& result) 64{ 65 uint32_t length; 66 if (!decoder.decode(length)) 67 return false; 68 69 if (length == std::numeric_limits<uint32_t>::max()) { 70 // This is the null string. 71 result = CString(); 72 return true; 73 } 74 75 // Before allocating the string, make sure that the decoder buffer is big enough. 76 if (!decoder.bufferIsLargeEnoughToContain<char>(length)) { 77 decoder.markInvalid(); 78 return false; 79 } 80 81 char* buffer; 82 CString string = CString::newUninitialized(length, buffer); 83 if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(buffer), length, 1)) 84 return false; 85 86 result = string; 87 return true; 88} 89 90 91void ArgumentCoder<String>::encode(ArgumentEncoder& encoder, const String& string) 92{ 93 // Special case the null string. 94 if (string.isNull()) { 95 encoder << std::numeric_limits<uint32_t>::max(); 96 return; 97 } 98 99 uint32_t length = string.length(); 100 bool is8Bit = string.is8Bit(); 101 102 encoder << length << is8Bit; 103 104 if (is8Bit) 105 encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(string.characters8()), length * sizeof(LChar), alignof(LChar)); 106 else 107 encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(string.characters16()), length * sizeof(UChar), alignof(UChar)); 108} 109 110template <typename CharacterType> 111static inline bool decodeStringText(ArgumentDecoder& decoder, uint32_t length, String& result) 112{ 113 // Before allocating the string, make sure that the decoder buffer is big enough. 114 if (!decoder.bufferIsLargeEnoughToContain<CharacterType>(length)) { 115 decoder.markInvalid(); 116 return false; 117 } 118 119 CharacterType* buffer; 120 String string = String::createUninitialized(length, buffer); 121 if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(buffer), length * sizeof(CharacterType), alignof(CharacterType))) 122 return false; 123 124 result = string; 125 return true; 126} 127 128bool ArgumentCoder<String>::decode(ArgumentDecoder& decoder, String& result) 129{ 130 uint32_t length; 131 if (!decoder.decode(length)) 132 return false; 133 134 if (length == std::numeric_limits<uint32_t>::max()) { 135 // This is the null string. 136 result = String(); 137 return true; 138 } 139 140 bool is8Bit; 141 142 if (!decoder.decode(is8Bit)) 143 return false; 144 145 if (is8Bit) 146 return decodeStringText<LChar>(decoder, length, result); 147 return decodeStringText<UChar>(decoder, length, result); 148} 149 150} // namespace IPC 151