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 UserMessageCoders_h 27#define UserMessageCoders_h 28 29#include "APIArray.h" 30#include "APIData.h" 31#include "APIError.h" 32#include "APIGeometry.h" 33#include "APINumber.h" 34#include "APIString.h" 35#include "APIURL.h" 36#include "APIURLRequest.h" 37#include "APIURLResponse.h" 38#include "ArgumentDecoder.h" 39#include "ArgumentEncoder.h" 40#include "DataReference.h" 41#include "ImmutableDictionary.h" 42#include "ShareableBitmap.h" 43#include "WebCertificateInfo.h" 44#include "WebCoreArgumentCoders.h" 45#include "WebImage.h" 46#include "WebRenderLayer.h" 47#include "WebRenderObject.h" 48#include "WebSerializedScriptValue.h" 49#include "WebUserContentURLPattern.h" 50 51namespace WebKit { 52 53// - Null -> Null 54// - API::Array -> API::Array 55// - Dictionary -> Dictionary 56// - SerializedScriptValue -> SerializedScriptValue 57// - API::String -> API::String 58// - UserContentURLPattern -> UserContentURLPattern 59// - WebCertificateInfo -> WebCertificateInfo 60// - API::Data -> API::Data 61// - API::Double -> API::Double 62// - WebImage -> WebImage 63// - WebRenderLayer -> WebRenderLayer 64// - WebRenderObject -> WebRenderObject 65// - API::UInt64 -> API::UInt64 66// - API::URL -> API::URL 67// - API::URLRequest -> API::URLRequest 68// - API::URLResponse -> API::URLResponse 69// - API::Error -> API::Error 70 71template<typename Owner> 72class UserMessageEncoder { 73public: 74 bool baseEncode(IPC::ArgumentEncoder& encoder, const Owner& coder, API::Object::Type& type) const 75 { 76 if (!m_root) { 77 encoder << static_cast<uint32_t>(API::Object::Type::Null); 78 return true; 79 } 80 81 type = m_root->type(); 82 encoder << static_cast<uint32_t>(type); 83 84 switch (type) { 85 case API::Object::Type::Array: { 86 API::Array* array = static_cast<API::Array*>(m_root); 87 encoder << static_cast<uint64_t>(array->size()); 88 for (size_t i = 0; i < array->size(); ++i) 89 encoder << Owner(coder, array->at(i)); 90 return true; 91 } 92 case API::Object::Type::Dictionary: { 93 ImmutableDictionary* dictionary = static_cast<ImmutableDictionary*>(m_root); 94 const ImmutableDictionary::MapType& map = dictionary->map(); 95 encoder << static_cast<uint64_t>(map.size()); 96 97 ImmutableDictionary::MapType::const_iterator it = map.begin(); 98 ImmutableDictionary::MapType::const_iterator end = map.end(); 99 for (; it != end; ++it) { 100 encoder << it->key; 101 encoder << Owner(coder, it->value.get()); 102 } 103 return true; 104 } 105 case API::Object::Type::String: { 106 API::String* string = static_cast<API::String*>(m_root); 107 encoder << string->string(); 108 return true; 109 } 110 case API::Object::Type::SerializedScriptValue: { 111 WebSerializedScriptValue* scriptValue = static_cast<WebSerializedScriptValue*>(m_root); 112 encoder << scriptValue->dataReference(); 113 return true; 114 } 115 case API::Object::Type::Boolean: { 116 API::Boolean* booleanObject = static_cast<API::Boolean*>(m_root); 117 encoder << booleanObject->value(); 118 return true; 119 } 120 case API::Object::Type::Double: { 121 API::Double* doubleObject = static_cast<API::Double*>(m_root); 122 encoder << doubleObject->value(); 123 return true; 124 } 125 case API::Object::Type::UInt64: { 126 API::UInt64* uint64Object = static_cast<API::UInt64*>(m_root); 127 encoder << uint64Object->value(); 128 return true; 129 } 130 case API::Object::Type::Point: { 131 API::Point* pointObject = static_cast<API::Point*>(m_root); 132 encoder << pointObject->point().x; 133 encoder << pointObject->point().y; 134 return true; 135 } 136 case API::Object::Type::Size: { 137 API::Size* sizeObject = static_cast<API::Size*>(m_root); 138 encoder << sizeObject->size().width; 139 encoder << sizeObject->size().height; 140 return true; 141 } 142 case API::Object::Type::Rect: { 143 API::Rect* rectObject = static_cast<API::Rect*>(m_root); 144 encoder << rectObject->rect().origin.x; 145 encoder << rectObject->rect().origin.y; 146 encoder << rectObject->rect().size.width; 147 encoder << rectObject->rect().size.height; 148 return true; 149 } 150 case API::Object::Type::RenderLayer: { 151 WebRenderLayer* renderLayer = static_cast<WebRenderLayer*>(m_root); 152 encoder << Owner(coder, renderLayer->renderer()); 153 encoder << renderLayer->isReflection(); 154 encoder << renderLayer->isClipping(); 155 encoder << renderLayer->isClipped(); 156 encoder << static_cast<uint32_t>(renderLayer->compositingLayerType()); 157 encoder << renderLayer->absoluteBoundingBox(); 158 encoder << Owner(coder, renderLayer->negativeZOrderList()); 159 encoder << Owner(coder, renderLayer->normalFlowList()); 160 encoder << Owner(coder, renderLayer->positiveZOrderList()); 161 return true; 162 } 163 case API::Object::Type::RenderObject: { 164 WebRenderObject* renderObject = static_cast<WebRenderObject*>(m_root); 165 encoder << renderObject->name(); 166 encoder << renderObject->elementTagName(); 167 encoder << renderObject->elementID(); 168 encoder << Owner(coder, renderObject->elementClassNames()); 169 encoder << renderObject->absolutePosition(); 170 encoder << renderObject->frameRect(); 171 encoder << Owner(coder, renderObject->children()); 172 return true; 173 } 174 case API::Object::Type::URL: { 175 API::URL* urlObject = static_cast<API::URL*>(m_root); 176 encoder << urlObject->string(); 177 return true; 178 } 179 case API::Object::Type::URLRequest: { 180 API::URLRequest* urlRequestObject = static_cast<API::URLRequest*>(m_root); 181 encoder << urlRequestObject->resourceRequest(); 182 return true; 183 } 184 case API::Object::Type::URLResponse: { 185 API::URLResponse* urlResponseObject = static_cast<API::URLResponse*>(m_root); 186 encoder << urlResponseObject->resourceResponse(); 187 return true; 188 } 189 case API::Object::Type::UserContentURLPattern: { 190 WebUserContentURLPattern* urlPattern = static_cast<WebUserContentURLPattern*>(m_root); 191 encoder << urlPattern->patternString(); 192 return true; 193 } 194 case API::Object::Type::Image: { 195 WebImage* image = static_cast<WebImage*>(m_root); 196 197 ShareableBitmap::Handle handle; 198 ASSERT(!image->bitmap() || image->bitmap()->isBackedBySharedMemory()); 199 if (!image->bitmap() || !image->bitmap()->isBackedBySharedMemory() || !image->bitmap()->createHandle(handle)) { 200 // Initial false indicates no allocated bitmap or is not shareable. 201 encoder << false; 202 return true; 203 } 204 205 // Initial true indicates a bitmap was allocated and is shareable. 206 encoder << true; 207 208 encoder << handle; 209 return true; 210 } 211 case API::Object::Type::Data: { 212 API::Data* data = static_cast<API::Data*>(m_root); 213 encoder << data->dataReference(); 214 return true; 215 } 216 case API::Object::Type::CertificateInfo: { 217 WebCertificateInfo* certificateInfo = static_cast<WebCertificateInfo*>(m_root); 218 encoder << certificateInfo->certificateInfo(); 219 return true; 220 } 221 case API::Object::Type::Error: { 222 API::Error* errorObject = static_cast<API::Error*>(m_root); 223 encoder << errorObject->platformError(); 224 return true; 225 } 226 default: 227 break; 228 } 229 230 return false; 231 } 232 233protected: 234 UserMessageEncoder(API::Object* root) 235 : m_root(root) 236 { 237 } 238 239 API::Object* m_root; 240}; 241 242 243// Handles 244// - Null -> Null 245// - API::Array -> API::Array 246// - Dictionary -> Dictionary 247// - SerializedScriptValue -> SerializedScriptValue 248// - API::String -> API::String 249// - UserContentURLPattern -> UserContentURLPattern 250// - WebCertificateInfo -> WebCertificateInfo 251// - API::Data -> API::Data 252// - API::Double -> API::Double 253// - WebImage -> WebImage 254// - API::UInt64 -> API::UInt64 255// - API::URL -> API::URL 256// - API::URLRequest -> API::URLRequest 257// - API::URLResponse -> API::URLResponse 258// - API::Error -> API::Error 259 260template<typename Owner> 261class UserMessageDecoder { 262public: 263 static bool baseDecode(IPC::ArgumentDecoder& decoder, Owner& coder, API::Object::Type& type) 264 { 265 uint32_t typeAsUInt32; 266 if (!decoder.decode(typeAsUInt32)) 267 return false; 268 269 type = static_cast<API::Object::Type>(typeAsUInt32); 270 271 switch (type) { 272 case API::Object::Type::Array: { 273 uint64_t size; 274 if (!decoder.decode(size)) 275 return false; 276 277 Vector<RefPtr<API::Object>> vector; 278 for (size_t i = 0; i < size; ++i) { 279 RefPtr<API::Object> element; 280 Owner messageCoder(coder, element); 281 if (!decoder.decode(messageCoder)) 282 return false; 283 vector.append(element.release()); 284 } 285 286 coder.m_root = API::Array::create(WTF::move(vector)); 287 break; 288 } 289 case API::Object::Type::Dictionary: { 290 uint64_t size; 291 if (!decoder.decode(size)) 292 return false; 293 294 ImmutableDictionary::MapType map; 295 for (size_t i = 0; i < size; ++i) { 296 String key; 297 if (!decoder.decode(key)) 298 return false; 299 300 RefPtr<API::Object> element; 301 Owner messageCoder(coder, element); 302 if (!decoder.decode(messageCoder)) 303 return false; 304 305 ImmutableDictionary::MapType::AddResult result = map.set(key, element.release()); 306 if (!result.isNewEntry) 307 return false; 308 } 309 310 coder.m_root = ImmutableDictionary::create(WTF::move(map)); 311 break; 312 } 313 case API::Object::Type::String: { 314 String string; 315 if (!decoder.decode(string)) 316 return false; 317 coder.m_root = API::String::create(string); 318 break; 319 } 320 case API::Object::Type::SerializedScriptValue: { 321 IPC::DataReference dataReference; 322 if (!decoder.decode(dataReference)) 323 return false; 324 325 Vector<uint8_t> vector = dataReference.vector(); 326 coder.m_root = WebSerializedScriptValue::adopt(vector); 327 break; 328 } 329 case API::Object::Type::Double: { 330 double value; 331 if (!decoder.decode(value)) 332 return false; 333 coder.m_root = API::Double::create(value); 334 break; 335 } 336 case API::Object::Type::UInt64: { 337 uint64_t value; 338 if (!decoder.decode(value)) 339 return false; 340 coder.m_root = API::UInt64::create(value); 341 break; 342 } 343 case API::Object::Type::Boolean: { 344 bool value; 345 if (!decoder.decode(value)) 346 return false; 347 coder.m_root = API::Boolean::create(value); 348 break; 349 } 350 case API::Object::Type::Size: { 351 double width; 352 double height; 353 if (!decoder.decode(width)) 354 return false; 355 if (!decoder.decode(height)) 356 return false; 357 coder.m_root = API::Size::create(WKSizeMake(width, height)); 358 break; 359 } 360 case API::Object::Type::Point: { 361 double x; 362 double y; 363 if (!decoder.decode(x)) 364 return false; 365 if (!decoder.decode(y)) 366 return false; 367 coder.m_root = API::Point::create(WKPointMake(x, y)); 368 break; 369 } 370 case API::Object::Type::Rect: { 371 double x; 372 double y; 373 double width; 374 double height; 375 if (!decoder.decode(x)) 376 return false; 377 if (!decoder.decode(y)) 378 return false; 379 if (!decoder.decode(width)) 380 return false; 381 if (!decoder.decode(height)) 382 return false; 383 coder.m_root = API::Rect::create(WKRectMake(x, y, width, height)); 384 break; 385 } 386 case API::Object::Type::RenderLayer: { 387 RefPtr<API::Object> renderer; 388 bool isReflection; 389 bool isClipping; 390 bool isClipped; 391 uint32_t compositingLayerTypeAsUInt32; 392 WebCore::IntRect absoluteBoundingBox; 393 RefPtr<API::Object> negativeZOrderList; 394 RefPtr<API::Object> normalFlowList; 395 RefPtr<API::Object> positiveZOrderList; 396 397 Owner rendererCoder(coder, renderer); 398 if (!decoder.decode(rendererCoder)) 399 return false; 400 if (renderer->type() != API::Object::Type::RenderObject) 401 return false; 402 if (!decoder.decode(isReflection)) 403 return false; 404 if (!decoder.decode(isClipping)) 405 return false; 406 if (!decoder.decode(isClipped)) 407 return false; 408 if (!decoder.decode(compositingLayerTypeAsUInt32)) 409 return false; 410 if (!decoder.decode(absoluteBoundingBox)) 411 return false; 412 Owner negativeZOrderListCoder(coder, negativeZOrderList); 413 if (!decoder.decode(negativeZOrderListCoder)) 414 return false; 415 Owner normalFlowListCoder(coder, normalFlowList); 416 if (!decoder.decode(normalFlowListCoder)) 417 return false; 418 Owner positiveZOrderListCoder(coder, positiveZOrderList); 419 if (!decoder.decode(positiveZOrderListCoder)) 420 return false; 421 coder.m_root = WebRenderLayer::create(static_pointer_cast<WebRenderObject>(renderer), isReflection, isClipping, isClipped, static_cast<WebRenderLayer::CompositingLayerType>(compositingLayerTypeAsUInt32), 422 absoluteBoundingBox, static_pointer_cast<API::Array>(negativeZOrderList), static_pointer_cast<API::Array>(normalFlowList), 423 static_pointer_cast<API::Array>(positiveZOrderList)); 424 break; 425 } 426 case API::Object::Type::RenderObject: { 427 String name; 428 String elementTagName; 429 String elementID; 430 RefPtr<API::Object> elementClassNames; 431 WebCore::IntPoint absolutePosition; 432 WebCore::IntRect frameRect; 433 RefPtr<API::Object> children; 434 435 if (!decoder.decode(name)) 436 return false; 437 if (!decoder.decode(elementTagName)) 438 return false; 439 if (!decoder.decode(elementID)) 440 return false; 441 Owner classNamesCoder(coder, elementClassNames); 442 if (!decoder.decode(classNamesCoder)) 443 return false; 444 if (!decoder.decode(absolutePosition)) 445 return false; 446 if (!decoder.decode(frameRect)) 447 return false; 448 Owner messageCoder(coder, children); 449 if (!decoder.decode(messageCoder)) 450 return false; 451 if (children && children->type() != API::Object::Type::Array) 452 return false; 453 coder.m_root = WebRenderObject::create(name, elementTagName, elementID, static_pointer_cast<API::Array>(elementClassNames), absolutePosition, frameRect, static_pointer_cast<API::Array>(children)); 454 break; 455 } 456 case API::Object::Type::URL: { 457 String string; 458 if (!decoder.decode(string)) 459 return false; 460 coder.m_root = API::URL::create(string); 461 break; 462 } 463 case API::Object::Type::URLRequest: { 464 WebCore::ResourceRequest request; 465 if (!decoder.decode(request)) 466 return false; 467 coder.m_root = API::URLRequest::create(request); 468 break; 469 } 470 case API::Object::Type::URLResponse: { 471 WebCore::ResourceResponse response; 472 if (!decoder.decode(response)) 473 return false; 474 coder.m_root = API::URLResponse::create(response); 475 break; 476 } 477 case API::Object::Type::UserContentURLPattern: { 478 String string; 479 if (!decoder.decode(string)) 480 return false; 481 coder.m_root = WebUserContentURLPattern::create(string); 482 break; 483 } 484 case API::Object::Type::Image: { 485 bool didEncode = false; 486 if (!decoder.decode(didEncode)) 487 return false; 488 489 if (!didEncode) 490 break; 491 492 ShareableBitmap::Handle handle; 493 if (!decoder.decode(handle)) 494 return false; 495 496 coder.m_root = WebImage::create(ShareableBitmap::create(handle)); 497 return true; 498 } 499 case API::Object::Type::Data: { 500 IPC::DataReference dataReference; 501 if (!decoder.decode(dataReference)) 502 return false; 503 coder.m_root = API::Data::create(dataReference.data(), dataReference.size()); 504 break; 505 } 506 case API::Object::Type::CertificateInfo: { 507 WebCore::CertificateInfo certificateInfo; 508 if (!decoder.decode(certificateInfo)) 509 return false; 510 coder.m_root = WebCertificateInfo::create(certificateInfo); 511 break; 512 } 513 case API::Object::Type::Error: { 514 WebCore::ResourceError resourceError; 515 if (!decoder.decode(resourceError)) 516 return false; 517 coder.m_root = API::Error::create(resourceError); 518 break; 519 } 520 default: 521 break; 522 } 523 524 return true; 525 } 526 527protected: 528 UserMessageDecoder(RefPtr<API::Object>& root) 529 : m_root(root) 530 { 531 } 532 533 RefPtr<API::Object>& m_root; 534}; 535 536} // namespace WebKit 537 538#endif // UserMessageCoders_h 539