1 /* 2 * Copyright (C) 2010, 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 #ifndef WebCoreArgumentCoders_h 27 #define WebCoreArgumentCoders_h 28 29 #include "ArgumentCoders.h" 30 #include "ArgumentDecoder.h" 31 #include "ArgumentEncoder.h" 32 #include "Arguments.h" 33 #include "ShareableBitmap.h" 34 #include <WebCore/AuthenticationChallenge.h> 35 #include <WebCore/BitmapImage.h> 36 #include <WebCore/Credential.h> 37 #include <WebCore/Cursor.h> 38 #include <WebCore/DatabaseDetails.h> 39 #include <WebCore/Editor.h> 40 #include <WebCore/EditorClient.h> 41 #include <WebCore/FloatRect.h> 42 #include <WebCore/GraphicsContext.h> 43 #include <WebCore/IntRect.h> 44 #include <WebCore/KeyboardEvent.h> 45 #include <WebCore/PluginData.h> 46 #include <WebCore/ProtectionSpace.h> 47 #include <WebCore/ResourceError.h> 48 #include <WebCore/ResourceRequest.h> 49 #include <WebCore/TextCheckerClient.h> 50 #include <WebCore/ViewportArguments.h> 51 #include <WebCore/WindowFeatures.h> 52 #include <limits> 53 54 namespace CoreIPC { 55 56 template<> struct ArgumentCoder<WebCore::IntPoint> : SimpleArgumentCoder<WebCore::IntPoint> { }; 57 template<> struct ArgumentCoder<WebCore::IntSize> : SimpleArgumentCoder<WebCore::IntSize> { }; 58 template<> struct ArgumentCoder<WebCore::IntRect> : SimpleArgumentCoder<WebCore::IntRect> { }; 59 template<> struct ArgumentCoder<WebCore::ViewportArguments> : SimpleArgumentCoder<WebCore::ViewportArguments> { }; 60 61 template<> struct ArgumentCoder<WebCore::FloatPoint> : SimpleArgumentCoder<WebCore::FloatPoint> { }; 62 template<> struct ArgumentCoder<WebCore::FloatSize> : SimpleArgumentCoder<WebCore::FloatSize> { }; 63 template<> struct ArgumentCoder<WebCore::FloatRect> : SimpleArgumentCoder<WebCore::FloatRect> { }; 64 65 template<> struct ArgumentCoder<WebCore::MimeClassInfo> { 66 static void encode(ArgumentEncoder* encoder, const WebCore::MimeClassInfo& mimeClassInfo) 67 { 68 encoder->encode(mimeClassInfo.type); 69 encoder->encode(mimeClassInfo.desc); 70 encoder->encode(mimeClassInfo.extensions); 71 } 72 73 static bool decode(ArgumentDecoder* decoder, WebCore::MimeClassInfo& mimeClassInfo) 74 { 75 if (!decoder->decode(mimeClassInfo.type)) 76 return false; 77 if (!decoder->decode(mimeClassInfo.desc)) 78 return false; 79 if (!decoder->decode(mimeClassInfo.extensions)) 80 return false; 81 82 return true; 83 } 84 }; 85 86 template<> struct ArgumentCoder<WebCore::PluginInfo> { 87 static void encode(ArgumentEncoder* encoder, const WebCore::PluginInfo& pluginInfo) 88 { 89 encoder->encode(pluginInfo.name); 90 encoder->encode(pluginInfo.file); 91 encoder->encode(pluginInfo.desc); 92 encoder->encode(pluginInfo.mimes); 93 } 94 95 static bool decode(ArgumentDecoder* decoder, WebCore::PluginInfo& pluginInfo) 96 { 97 if (!decoder->decode(pluginInfo.name)) 98 return false; 99 if (!decoder->decode(pluginInfo.file)) 100 return false; 101 if (!decoder->decode(pluginInfo.desc)) 102 return false; 103 if (!decoder->decode(pluginInfo.mimes)) 104 return false; 105 106 return true; 107 } 108 }; 109 110 template<> struct ArgumentCoder<WebCore::HTTPHeaderMap> { 111 static void encode(ArgumentEncoder* encoder, const WebCore::HTTPHeaderMap& headerMap) 112 { 113 encoder->encode(static_cast<const HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap)); 114 } 115 116 static bool decode(ArgumentDecoder* decoder, WebCore::HTTPHeaderMap& headerMap) 117 { 118 return decoder->decode(static_cast<HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap)); 119 } 120 }; 121 122 template<> struct ArgumentCoder<WebCore::AuthenticationChallenge> { 123 static void encode(ArgumentEncoder* encoder, const WebCore::AuthenticationChallenge& challenge) 124 { 125 encoder->encode(CoreIPC::In(challenge.protectionSpace(), challenge.proposedCredential(), challenge.previousFailureCount(), challenge.failureResponse(), challenge.error())); 126 } 127 128 static bool decode(ArgumentDecoder* decoder, WebCore::AuthenticationChallenge& challenge) 129 { 130 WebCore::ProtectionSpace protectionSpace; 131 WebCore::Credential proposedCredential; 132 unsigned previousFailureCount; 133 WebCore::ResourceResponse failureResponse; 134 WebCore::ResourceError error; 135 136 if (!decoder->decode(CoreIPC::Out(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error))) 137 return false; 138 139 challenge = WebCore::AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error); 140 141 return true; 142 } 143 }; 144 145 template<> struct ArgumentCoder<WebCore::ProtectionSpace> { 146 static void encode(ArgumentEncoder* encoder, const WebCore::ProtectionSpace& space) 147 { 148 encoder->encode(CoreIPC::In(space.host(), space.port(), static_cast<uint32_t>(space.serverType()), space.realm(), static_cast<uint32_t>(space.authenticationScheme()))); 149 } 150 151 static bool decode(ArgumentDecoder* decoder, WebCore::ProtectionSpace& space) 152 { 153 String host; 154 int port; 155 uint32_t serverType; 156 String realm; 157 uint32_t authenticationScheme; 158 159 if (!decoder->decode(CoreIPC::Out(host, port, serverType, realm, authenticationScheme))) 160 return false; 161 162 space = WebCore::ProtectionSpace(host, port, static_cast<WebCore::ProtectionSpaceServerType>(serverType), realm, static_cast<WebCore::ProtectionSpaceAuthenticationScheme>(authenticationScheme)); 163 164 return true; 165 } 166 }; 167 168 template<> struct ArgumentCoder<WebCore::Credential> { 169 static void encode(ArgumentEncoder* encoder, const WebCore::Credential& credential) 170 { 171 encoder->encode(CoreIPC::In(credential.user(), credential.password(), static_cast<uint32_t>(credential.persistence()))); 172 } 173 174 static bool decode(ArgumentDecoder* decoder, WebCore::Credential& credential) 175 { 176 String user; 177 String password; 178 int persistence; 179 if (!decoder->decode(CoreIPC::Out(user, password, persistence))) 180 return false; 181 182 credential = WebCore::Credential(user, password, static_cast<WebCore::CredentialPersistence>(persistence)); 183 return true; 184 } 185 }; 186 187 #if USE(LAZY_NATIVE_CURSOR) 188 189 void encodeImage(ArgumentEncoder*, WebCore::Image*); 190 bool decodeImage(ArgumentDecoder*, RefPtr<WebCore::Image>&); 191 RefPtr<WebCore::Image> createImage(WebKit::ShareableBitmap*); 192 193 template<> struct ArgumentCoder<WebCore::Cursor> { 194 static void encode(ArgumentEncoder* encoder, const WebCore::Cursor& cursor) 195 { 196 WebCore::Cursor::Type type = cursor.type(); 197 #if !USE(CG) 198 // FIXME: Currently we only have the createImage function implemented for CG. 199 // Once we implement it for other platforms we can remove this conditional, 200 // and the other conditionals below and in WebCoreArgumentCoders.cpp. 201 if (type == WebCore::Cursor::Custom) 202 type = WebCore::Cursor::Pointer; 203 #endif 204 encoder->encode(static_cast<uint32_t>(type)); 205 #if USE(CG) 206 if (type != WebCore::Cursor::Custom) 207 return; 208 209 encodeImage(encoder, cursor.image()); 210 encoder->encode(cursor.hotSpot()); 211 #endif 212 } 213 214 static bool decode(ArgumentDecoder* decoder, WebCore::Cursor& cursor) 215 { 216 uint32_t typeInt; 217 if (!decoder->decode(typeInt)) 218 return false; 219 if (typeInt > WebCore::Cursor::Custom) 220 return false; 221 WebCore::Cursor::Type type = static_cast<WebCore::Cursor::Type>(typeInt); 222 223 if (type != WebCore::Cursor::Custom) { 224 cursor = WebCore::Cursor::fromType(type); 225 return true; 226 } 227 228 #if !USE(CG) 229 return false; 230 #else 231 RefPtr<WebCore::Image> image; 232 if (!decodeImage(decoder, image)) 233 return false; 234 WebCore::IntPoint hotSpot; 235 if (!decoder->decode(hotSpot)) 236 return false; 237 if (!image->rect().contains(WebCore::IntRect(hotSpot, WebCore::IntSize()))) 238 return false; 239 240 cursor = WebCore::Cursor(image.get(), hotSpot); 241 return true; 242 #endif 243 } 244 }; 245 246 #endif 247 248 // These two functions are implemented in a platform specific manner. 249 void encodeResourceRequest(ArgumentEncoder*, const WebCore::ResourceRequest&); 250 bool decodeResourceRequest(ArgumentDecoder*, WebCore::ResourceRequest&); 251 252 template<> struct ArgumentCoder<WebCore::ResourceRequest> { 253 static void encode(ArgumentEncoder* encoder, const WebCore::ResourceRequest& resourceRequest) 254 { 255 encodeResourceRequest(encoder, resourceRequest); 256 } 257 258 static bool decode(ArgumentDecoder* decoder, WebCore::ResourceRequest& resourceRequest) 259 { 260 return decodeResourceRequest(decoder, resourceRequest); 261 } 262 }; 263 264 // These two functions are implemented in a platform specific manner. 265 void encodeResourceResponse(ArgumentEncoder*, const WebCore::ResourceResponse&); 266 bool decodeResourceResponse(ArgumentDecoder*, WebCore::ResourceResponse&); 267 268 template<> struct ArgumentCoder<WebCore::ResourceResponse> { 269 static void encode(ArgumentEncoder* encoder, const WebCore::ResourceResponse& resourceResponse) 270 { 271 encodeResourceResponse(encoder, resourceResponse); 272 } 273 274 static bool decode(ArgumentDecoder* decoder, WebCore::ResourceResponse& resourceResponse) 275 { 276 return decodeResourceResponse(decoder, resourceResponse); 277 } 278 }; 279 280 // These two functions are implemented in a platform specific manner. 281 void encodeResourceError(ArgumentEncoder*, const WebCore::ResourceError&); 282 bool decodeResourceError(ArgumentDecoder*, WebCore::ResourceError&); 283 284 template<> struct ArgumentCoder<WebCore::ResourceError> { 285 static void encode(ArgumentEncoder* encoder, const WebCore::ResourceError& resourceError) 286 { 287 encodeResourceError(encoder, resourceError); 288 } 289 290 static bool decode(ArgumentDecoder* decoder, WebCore::ResourceError& resourceError) 291 { 292 return decodeResourceError(decoder, resourceError); 293 } 294 }; 295 296 template<> struct ArgumentCoder<WebCore::WindowFeatures> { 297 static void encode(ArgumentEncoder* encoder, const WebCore::WindowFeatures& windowFeatures) 298 { 299 encoder->encode(windowFeatures.x); 300 encoder->encode(windowFeatures.y); 301 encoder->encode(windowFeatures.width); 302 encoder->encode(windowFeatures.height); 303 encoder->encode(windowFeatures.xSet); 304 encoder->encode(windowFeatures.ySet); 305 encoder->encode(windowFeatures.widthSet); 306 encoder->encode(windowFeatures.heightSet); 307 encoder->encode(windowFeatures.menuBarVisible); 308 encoder->encode(windowFeatures.statusBarVisible); 309 encoder->encode(windowFeatures.toolBarVisible); 310 encoder->encode(windowFeatures.locationBarVisible); 311 encoder->encode(windowFeatures.scrollbarsVisible); 312 encoder->encode(windowFeatures.resizable); 313 encoder->encode(windowFeatures.fullscreen); 314 encoder->encode(windowFeatures.dialog); 315 } 316 317 static bool decode(ArgumentDecoder* decoder, WebCore::WindowFeatures& windowFeatures) 318 { 319 if (!decoder->decode(windowFeatures.x)) 320 return false; 321 if (!decoder->decode(windowFeatures.y)) 322 return false; 323 if (!decoder->decode(windowFeatures.width)) 324 return false; 325 if (!decoder->decode(windowFeatures.height)) 326 return false; 327 if (!decoder->decode(windowFeatures.xSet)) 328 return false; 329 if (!decoder->decode(windowFeatures.ySet)) 330 return false; 331 if (!decoder->decode(windowFeatures.widthSet)) 332 return false; 333 if (!decoder->decode(windowFeatures.heightSet)) 334 return false; 335 if (!decoder->decode(windowFeatures.menuBarVisible)) 336 return false; 337 if (!decoder->decode(windowFeatures.statusBarVisible)) 338 return false; 339 if (!decoder->decode(windowFeatures.toolBarVisible)) 340 return false; 341 if (!decoder->decode(windowFeatures.locationBarVisible)) 342 return false; 343 if (!decoder->decode(windowFeatures.scrollbarsVisible)) 344 return false; 345 if (!decoder->decode(windowFeatures.resizable)) 346 return false; 347 if (!decoder->decode(windowFeatures.fullscreen)) 348 return false; 349 if (!decoder->decode(windowFeatures.dialog)) 350 return false; 351 return true; 352 } 353 }; 354 355 template<> struct ArgumentCoder<WebCore::Color> { 356 static void encode(ArgumentEncoder* encoder, const WebCore::Color& color) 357 { 358 if (!color.isValid()) { 359 encoder->encodeBool(false); 360 return; 361 } 362 363 encoder->encodeBool(true); 364 encoder->encode(color.rgb()); 365 } 366 367 static bool decode(ArgumentDecoder* decoder, WebCore::Color& color) 368 { 369 bool isValid; 370 if (!decoder->decode(isValid)) 371 return false; 372 373 if (!isValid) { 374 color = WebCore::Color(); 375 return true; 376 } 377 378 WebCore::RGBA32 rgba; 379 if (!decoder->decode(rgba)) 380 return false; 381 382 color = WebCore::Color(rgba); 383 return true; 384 } 385 }; 386 387 #if PLATFORM(MAC) 388 template<> struct ArgumentCoder<WebCore::KeypressCommand> { 389 static void encode(ArgumentEncoder* encoder, const WebCore::KeypressCommand& keypressCommand) 390 { 391 encoder->encode(CoreIPC::In(keypressCommand.commandName, keypressCommand.text)); 392 } 393 394 static bool decode(ArgumentDecoder* decoder, WebCore::KeypressCommand& keypressCommand) 395 { 396 return decoder->decode(CoreIPC::Out(keypressCommand.commandName, keypressCommand.text)); 397 } 398 }; 399 #endif 400 401 template<> struct ArgumentCoder<WebCore::CompositionUnderline> { 402 static void encode(ArgumentEncoder* encoder, const WebCore::CompositionUnderline& underline) 403 { 404 encoder->encode(CoreIPC::In(underline.startOffset, underline.endOffset, underline.thick, underline.color)); 405 } 406 407 static bool decode(ArgumentDecoder* decoder, WebCore::CompositionUnderline& underline) 408 { 409 return decoder->decode(CoreIPC::Out(underline.startOffset, underline.endOffset, underline.thick, underline.color)); 410 } 411 }; 412 413 template<> struct ArgumentCoder<WebCore::DatabaseDetails> { 414 static void encode(ArgumentEncoder* encoder, const WebCore::DatabaseDetails& details) 415 { 416 encoder->encode(CoreIPC::In(details.name(), details.displayName(), details.expectedUsage(), details.currentUsage())); 417 } 418 419 static bool decode(ArgumentDecoder* decoder, WebCore::DatabaseDetails& details) 420 { 421 String name; 422 String displayName; 423 uint64_t expectedUsage; 424 uint64_t currentUsage; 425 if (!decoder->decode(CoreIPC::Out(name, displayName, expectedUsage, currentUsage))) 426 return false; 427 428 details = WebCore::DatabaseDetails(name, displayName, expectedUsage, currentUsage); 429 return true; 430 } 431 }; 432 433 template<> struct ArgumentCoder<WebCore::GrammarDetail> { 434 static void encode(ArgumentEncoder* encoder, const WebCore::GrammarDetail& detail) 435 { 436 encoder->encodeInt32(detail.location); 437 encoder->encodeInt32(detail.length); 438 encoder->encode(detail.guesses); 439 encoder->encode(detail.userDescription); 440 } 441 442 static bool decode(ArgumentDecoder* decoder, WebCore::GrammarDetail& detail) 443 { 444 if (!decoder->decodeInt32(detail.location)) 445 return false; 446 if (!decoder->decodeInt32(detail.length)) 447 return false; 448 if (!decoder->decode(detail.guesses)) 449 return false; 450 if (!decoder->decode(detail.userDescription)) 451 return false; 452 453 return true; 454 } 455 }; 456 457 template<> struct ArgumentCoder<WebCore::TextCheckingResult> { 458 static void encode(ArgumentEncoder* encoder, const WebCore::TextCheckingResult& result) 459 { 460 encoder->encodeEnum(result.type); 461 encoder->encodeInt32(result.location); 462 encoder->encodeInt32(result.length); 463 encoder->encode(result.details); 464 encoder->encode(result.replacement); 465 } 466 467 static bool decode(ArgumentDecoder* decoder, WebCore::TextCheckingResult& result) 468 { 469 if (!decoder->decodeEnum(result.type)) 470 return false; 471 if (!decoder->decodeInt32(result.location)) 472 return false; 473 if (!decoder->decodeInt32(result.length)) 474 return false; 475 if (!decoder->decode(result.details)) 476 return false; 477 if (!decoder->decode(result.replacement)) 478 return false; 479 return true; 480 } 481 }; 482 483 } // namespace CoreIPC 484 485 #endif // WebCoreArgumentCoders_h 486