/* * Copyright (C) 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UserMessageCoders_h #define UserMessageCoders_h #include "ArgumentDecoder.h" #include "ArgumentEncoder.h" #include "ImmutableArray.h" #include "ImmutableDictionary.h" #include "ShareableBitmap.h" #include "WebCertificateInfo.h" #include "WebCoreArgumentCoders.h" #include "WebData.h" #include "WebImage.h" #include "WebNumber.h" #include "WebSerializedScriptValue.h" #include "WebString.h" #include "WebURL.h" #include "WebUserContentURLPattern.h" namespace WebKit { // - Null -> Null // - Array -> Array // - Dictionary -> Dictionary // - SerializedScriptValue -> SerializedScriptValue // - String -> String // - UserContentURLPattern -> UserContentURLPattern // - WebCertificateInfo -> WebCertificateInfo // - WebData -> WebData // - WebDouble -> WebDouble // - WebImage -> WebImage // - WebUInt64 -> WebUInt64 // - WebURL -> WebURL template<typename Owner> class UserMessageEncoder { public: bool baseEncode(CoreIPC::ArgumentEncoder* encoder, APIObject::Type& type) const { if (!m_root) { encoder->encodeUInt32(APIObject::TypeNull); return true; } type = m_root->type(); encoder->encodeUInt32(type); switch (type) { case APIObject::TypeArray: { ImmutableArray* array = static_cast<ImmutableArray*>(m_root); encoder->encode(static_cast<uint64_t>(array->size())); for (size_t i = 0; i < array->size(); ++i) encoder->encode(Owner(array->at(i))); return true; } case APIObject::TypeDictionary: { ImmutableDictionary* dictionary = static_cast<ImmutableDictionary*>(m_root); const ImmutableDictionary::MapType& map = dictionary->map(); encoder->encode(static_cast<uint64_t>(map.size())); ImmutableDictionary::MapType::const_iterator it = map.begin(); ImmutableDictionary::MapType::const_iterator end = map.end(); for (; it != end; ++it) { encoder->encode(it->first); encoder->encode(Owner(it->second.get())); } return true; } case APIObject::TypeString: { WebString* string = static_cast<WebString*>(m_root); encoder->encode(string->string()); return true; } case APIObject::TypeSerializedScriptValue: { WebSerializedScriptValue* scriptValue = static_cast<WebSerializedScriptValue*>(m_root); encoder->encodeBytes(scriptValue->data().data(), scriptValue->data().size()); return true; } case APIObject::TypeDouble: { WebDouble* doubleObject = static_cast<WebDouble*>(m_root); encoder->encode(doubleObject->value()); return true; } case APIObject::TypeUInt64: { WebUInt64* uint64Object = static_cast<WebUInt64*>(m_root); encoder->encode(uint64Object->value()); return true; } case APIObject::TypeBoolean: { WebBoolean* booleanObject = static_cast<WebBoolean*>(m_root); encoder->encode(booleanObject->value()); return true; } case APIObject::TypeURL: { WebURL* urlObject = static_cast<WebURL*>(m_root); encoder->encode(urlObject->string()); return true; } case APIObject::TypeUserContentURLPattern: { WebUserContentURLPattern* urlPattern = static_cast<WebUserContentURLPattern*>(m_root); encoder->encode(urlPattern->patternString()); return true; } case APIObject::TypeImage: { WebImage* image = static_cast<WebImage*>(m_root); if (!image->bitmap()->isBackedBySharedMemory()) { encoder->encode(false); return true; } ShareableBitmap::Handle handle; if (!image->bitmap()->createHandle(handle)) return false; encoder->encode(true); encoder->encode(handle); return true; } case APIObject::TypeData: { WebData* data = static_cast<WebData*>(m_root); encoder->encodeBytes(data->bytes(), data->size()); return true; } case APIObject::TypeCertificateInfo: { WebCertificateInfo* certificateInfo = static_cast<WebCertificateInfo*>(m_root); encoder->encode(certificateInfo->platformCertificateInfo()); return true; } default: break; } return false; } protected: UserMessageEncoder(APIObject* root) : m_root(root) { } APIObject* m_root; }; // Handles // - Null -> Null // - Array -> Array // - Dictionary -> Dictionary // - SerializedScriptValue -> SerializedScriptValue // - String -> String // - UserContentURLPattern -> UserContentURLPattern // - WebCertificateInfo -> WebCertificateInfo // - WebData -> WebData // - WebDouble -> WebDouble // - WebImage -> WebImage // - WebUInt64 -> WebUInt64 // - WebURL -> WebURL template<typename Owner> class UserMessageDecoder { public: static bool baseDecode(CoreIPC::ArgumentDecoder* decoder, Owner& coder, APIObject::Type& type) { uint32_t typeAsUInt32; if (!decoder->decode(typeAsUInt32)) return false; type = static_cast<APIObject::Type>(typeAsUInt32); switch (type) { case APIObject::TypeArray: { uint64_t size; if (!decoder->decode(size)) return false; Vector<RefPtr<APIObject> > vector; for (size_t i = 0; i < size; ++i) { RefPtr<APIObject> element; Owner messageCoder(coder, element); if (!decoder->decode(messageCoder)) return false; vector.append(element.release()); } coder.m_root = ImmutableArray::adopt(vector); break; } case APIObject::TypeDictionary: { uint64_t size; if (!decoder->decode(size)) return false; ImmutableDictionary::MapType map; for (size_t i = 0; i < size; ++i) { String key; if (!decoder->decode(key)) return false; RefPtr<APIObject> element; Owner messageCoder(coder, element); if (!decoder->decode(messageCoder)) return false; std::pair<ImmutableDictionary::MapType::iterator, bool> result = map.set(key, element.release()); if (!result.second) return false; } coder.m_root = ImmutableDictionary::adopt(map); break; } case APIObject::TypeString: { String string; if (!decoder->decode(string)) return false; coder.m_root = WebString::create(string); break; } case APIObject::TypeSerializedScriptValue: { Vector<uint8_t> buffer; if (!decoder->decodeBytes(buffer)) return false; coder.m_root = WebSerializedScriptValue::adopt(buffer); break; } case APIObject::TypeDouble: { double value; if (!decoder->decode(value)) return false; coder.m_root = WebDouble::create(value); break; } case APIObject::TypeUInt64: { uint64_t value; if (!decoder->decode(value)) return false; coder.m_root = WebUInt64::create(value); break; } case APIObject::TypeBoolean: { bool value; if (!decoder->decode(value)) return false; coder.m_root = WebBoolean::create(value); break; } case APIObject::TypeURL: { String string; if (!decoder->decode(string)) return false; coder.m_root = WebURL::create(string); break; } case APIObject::TypeUserContentURLPattern: { String string; if (!decoder->decode(string)) return false; coder.m_root = WebUserContentURLPattern::create(string); break; } case APIObject::TypeImage: { bool didEncode = false; if (!decoder->decode(didEncode)) return false; if (!didEncode) break; ShareableBitmap::Handle handle; if (!decoder->decode(handle)) return false; coder.m_root = WebImage::create(ShareableBitmap::create(handle)); return true; } case APIObject::TypeData: { Vector<uint8_t> buffer; if (!decoder->decodeBytes(buffer)) return false; coder.m_root = WebData::create(buffer); break; } case APIObject::TypeCertificateInfo: { PlatformCertificateInfo platformCertificateInfo; if (!decoder->decode(platformCertificateInfo)) return false; coder.m_root = WebCertificateInfo::create(platformCertificateInfo); break; } default: break; } return true; } protected: UserMessageDecoder(RefPtr<APIObject>& root) : m_root(root) { } RefPtr<APIObject>& m_root; }; } // namespace WebKit #endif // UserMessageCoders_h