/*
* Copyright (C) 2010, 2011 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 WebCoreArgumentCoders_h
#define WebCoreArgumentCoders_h
#include "ArgumentCoders.h"
#include "ArgumentDecoder.h"
#include "ArgumentEncoder.h"
#include "Arguments.h"
#include "ShareableBitmap.h"
#include <WebCore/AuthenticationChallenge.h>
#include <WebCore/BitmapImage.h>
#include <WebCore/Credential.h>
#include <WebCore/Cursor.h>
#include <WebCore/DatabaseDetails.h>
#include <WebCore/Editor.h>
#include <WebCore/EditorClient.h>
#include <WebCore/FloatRect.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/IntRect.h>
#include <WebCore/KeyboardEvent.h>
#include <WebCore/PluginData.h>
#include <WebCore/ProtectionSpace.h>
#include <WebCore/ResourceError.h>
#include <WebCore/ResourceRequest.h>
#include <WebCore/TextCheckerClient.h>
#include <WebCore/ViewportArguments.h>
#include <WebCore/WindowFeatures.h>
#include <limits>
namespace CoreIPC {
template<> struct ArgumentCoder<WebCore::IntPoint> : SimpleArgumentCoder<WebCore::IntPoint> { };
template<> struct ArgumentCoder<WebCore::IntSize> : SimpleArgumentCoder<WebCore::IntSize> { };
template<> struct ArgumentCoder<WebCore::IntRect> : SimpleArgumentCoder<WebCore::IntRect> { };
template<> struct ArgumentCoder<WebCore::ViewportArguments> : SimpleArgumentCoder<WebCore::ViewportArguments> { };
template<> struct ArgumentCoder<WebCore::FloatPoint> : SimpleArgumentCoder<WebCore::FloatPoint> { };
template<> struct ArgumentCoder<WebCore::FloatSize> : SimpleArgumentCoder<WebCore::FloatSize> { };
template<> struct ArgumentCoder<WebCore::FloatRect> : SimpleArgumentCoder<WebCore::FloatRect> { };
template<> struct ArgumentCoder<WebCore::MimeClassInfo> {
static void encode(ArgumentEncoder* encoder, const WebCore::MimeClassInfo& mimeClassInfo)
{
encoder->encode(mimeClassInfo.type);
encoder->encode(mimeClassInfo.desc);
encoder->encode(mimeClassInfo.extensions);
}
static bool decode(ArgumentDecoder* decoder, WebCore::MimeClassInfo& mimeClassInfo)
{
if (!decoder->decode(mimeClassInfo.type))
return false;
if (!decoder->decode(mimeClassInfo.desc))
return false;
if (!decoder->decode(mimeClassInfo.extensions))
return false;
return true;
}
};
template<> struct ArgumentCoder<WebCore::PluginInfo> {
static void encode(ArgumentEncoder* encoder, const WebCore::PluginInfo& pluginInfo)
{
encoder->encode(pluginInfo.name);
encoder->encode(pluginInfo.file);
encoder->encode(pluginInfo.desc);
encoder->encode(pluginInfo.mimes);
}
static bool decode(ArgumentDecoder* decoder, WebCore::PluginInfo& pluginInfo)
{
if (!decoder->decode(pluginInfo.name))
return false;
if (!decoder->decode(pluginInfo.file))
return false;
if (!decoder->decode(pluginInfo.desc))
return false;
if (!decoder->decode(pluginInfo.mimes))
return false;
return true;
}
};
template<> struct ArgumentCoder<WebCore::HTTPHeaderMap> {
static void encode(ArgumentEncoder* encoder, const WebCore::HTTPHeaderMap& headerMap)
{
encoder->encode(static_cast<const HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap));
}
static bool decode(ArgumentDecoder* decoder, WebCore::HTTPHeaderMap& headerMap)
{
return decoder->decode(static_cast<HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap));
}
};
template<> struct ArgumentCoder<WebCore::AuthenticationChallenge> {
static void encode(ArgumentEncoder* encoder, const WebCore::AuthenticationChallenge& challenge)
{
encoder->encode(CoreIPC::In(challenge.protectionSpace(), challenge.proposedCredential(), challenge.previousFailureCount(), challenge.failureResponse(), challenge.error()));
}
static bool decode(ArgumentDecoder* decoder, WebCore::AuthenticationChallenge& challenge)
{
WebCore::ProtectionSpace protectionSpace;
WebCore::Credential proposedCredential;
unsigned previousFailureCount;
WebCore::ResourceResponse failureResponse;
WebCore::ResourceError error;
if (!decoder->decode(CoreIPC::Out(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error)))
return false;
challenge = WebCore::AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
return true;
}
};
template<> struct ArgumentCoder<WebCore::ProtectionSpace> {
static void encode(ArgumentEncoder* encoder, const WebCore::ProtectionSpace& space)
{
encoder->encode(CoreIPC::In(space.host(), space.port(), static_cast<uint32_t>(space.serverType()), space.realm(), static_cast<uint32_t>(space.authenticationScheme())));
}
static bool decode(ArgumentDecoder* decoder, WebCore::ProtectionSpace& space)
{
String host;
int port;
uint32_t serverType;
String realm;
uint32_t authenticationScheme;
if (!decoder->decode(CoreIPC::Out(host, port, serverType, realm, authenticationScheme)))
return false;
space = WebCore::ProtectionSpace(host, port, static_cast<WebCore::ProtectionSpaceServerType>(serverType), realm, static_cast<WebCore::ProtectionSpaceAuthenticationScheme>(authenticationScheme));
return true;
}
};
template<> struct ArgumentCoder<WebCore::Credential> {
static void encode(ArgumentEncoder* encoder, const WebCore::Credential& credential)
{
encoder->encode(CoreIPC::In(credential.user(), credential.password(), static_cast<uint32_t>(credential.persistence())));
}
static bool decode(ArgumentDecoder* decoder, WebCore::Credential& credential)
{
String user;
String password;
int persistence;
if (!decoder->decode(CoreIPC::Out(user, password, persistence)))
return false;
credential = WebCore::Credential(user, password, static_cast<WebCore::CredentialPersistence>(persistence));
return true;
}
};
#if USE(LAZY_NATIVE_CURSOR)
void encodeImage(ArgumentEncoder*, WebCore::Image*);
bool decodeImage(ArgumentDecoder*, RefPtr<WebCore::Image>&);
RefPtr<WebCore::Image> createImage(WebKit::ShareableBitmap*);
template<> struct ArgumentCoder<WebCore::Cursor> {
static void encode(ArgumentEncoder* encoder, const WebCore::Cursor& cursor)
{
WebCore::Cursor::Type type = cursor.type();
#if !USE(CG)
// FIXME: Currently we only have the createImage function implemented for CG.
// Once we implement it for other platforms we can remove this conditional,
// and the other conditionals below and in WebCoreArgumentCoders.cpp.
if (type == WebCore::Cursor::Custom)
type = WebCore::Cursor::Pointer;
#endif
encoder->encode(static_cast<uint32_t>(type));
#if USE(CG)
if (type != WebCore::Cursor::Custom)
return;
encodeImage(encoder, cursor.image());
encoder->encode(cursor.hotSpot());
#endif
}
static bool decode(ArgumentDecoder* decoder, WebCore::Cursor& cursor)
{
uint32_t typeInt;
if (!decoder->decode(typeInt))
return false;
if (typeInt > WebCore::Cursor::Custom)
return false;
WebCore::Cursor::Type type = static_cast<WebCore::Cursor::Type>(typeInt);
if (type != WebCore::Cursor::Custom) {
cursor = WebCore::Cursor::fromType(type);
return true;
}
#if !USE(CG)
return false;
#else
RefPtr<WebCore::Image> image;
if (!decodeImage(decoder, image))
return false;
WebCore::IntPoint hotSpot;
if (!decoder->decode(hotSpot))
return false;
if (!image->rect().contains(WebCore::IntRect(hotSpot, WebCore::IntSize())))
return false;
cursor = WebCore::Cursor(image.get(), hotSpot);
return true;
#endif
}
};
#endif
// These two functions are implemented in a platform specific manner.
void encodeResourceRequest(ArgumentEncoder*, const WebCore::ResourceRequest&);
bool decodeResourceRequest(ArgumentDecoder*, WebCore::ResourceRequest&);
template<> struct ArgumentCoder<WebCore::ResourceRequest> {
static void encode(ArgumentEncoder* encoder, const WebCore::ResourceRequest& resourceRequest)
{
encodeResourceRequest(encoder, resourceRequest);
}
static bool decode(ArgumentDecoder* decoder, WebCore::ResourceRequest& resourceRequest)
{
return decodeResourceRequest(decoder, resourceRequest);
}
};
// These two functions are implemented in a platform specific manner.
void encodeResourceResponse(ArgumentEncoder*, const WebCore::ResourceResponse&);
bool decodeResourceResponse(ArgumentDecoder*, WebCore::ResourceResponse&);
template<> struct ArgumentCoder<WebCore::ResourceResponse> {
static void encode(ArgumentEncoder* encoder, const WebCore::ResourceResponse& resourceResponse)
{
encodeResourceResponse(encoder, resourceResponse);
}
static bool decode(ArgumentDecoder* decoder, WebCore::ResourceResponse& resourceResponse)
{
return decodeResourceResponse(decoder, resourceResponse);
}
};
// These two functions are implemented in a platform specific manner.
void encodeResourceError(ArgumentEncoder*, const WebCore::ResourceError&);
bool decodeResourceError(ArgumentDecoder*, WebCore::ResourceError&);
template<> struct ArgumentCoder<WebCore::ResourceError> {
static void encode(ArgumentEncoder* encoder, const WebCore::ResourceError& resourceError)
{
encodeResourceError(encoder, resourceError);
}
static bool decode(ArgumentDecoder* decoder, WebCore::ResourceError& resourceError)
{
return decodeResourceError(decoder, resourceError);
}
};
template<> struct ArgumentCoder<WebCore::WindowFeatures> {
static void encode(ArgumentEncoder* encoder, const WebCore::WindowFeatures& windowFeatures)
{
encoder->encode(windowFeatures.x);
encoder->encode(windowFeatures.y);
encoder->encode(windowFeatures.width);
encoder->encode(windowFeatures.height);
encoder->encode(windowFeatures.xSet);
encoder->encode(windowFeatures.ySet);
encoder->encode(windowFeatures.widthSet);
encoder->encode(windowFeatures.heightSet);
encoder->encode(windowFeatures.menuBarVisible);
encoder->encode(windowFeatures.statusBarVisible);
encoder->encode(windowFeatures.toolBarVisible);
encoder->encode(windowFeatures.locationBarVisible);
encoder->encode(windowFeatures.scrollbarsVisible);
encoder->encode(windowFeatures.resizable);
encoder->encode(windowFeatures.fullscreen);
encoder->encode(windowFeatures.dialog);
}
static bool decode(ArgumentDecoder* decoder, WebCore::WindowFeatures& windowFeatures)
{
if (!decoder->decode(windowFeatures.x))
return false;
if (!decoder->decode(windowFeatures.y))
return false;
if (!decoder->decode(windowFeatures.width))
return false;
if (!decoder->decode(windowFeatures.height))
return false;
if (!decoder->decode(windowFeatures.xSet))
return false;
if (!decoder->decode(windowFeatures.ySet))
return false;
if (!decoder->decode(windowFeatures.widthSet))
return false;
if (!decoder->decode(windowFeatures.heightSet))
return false;
if (!decoder->decode(windowFeatures.menuBarVisible))
return false;
if (!decoder->decode(windowFeatures.statusBarVisible))
return false;
if (!decoder->decode(windowFeatures.toolBarVisible))
return false;
if (!decoder->decode(windowFeatures.locationBarVisible))
return false;
if (!decoder->decode(windowFeatures.scrollbarsVisible))
return false;
if (!decoder->decode(windowFeatures.resizable))
return false;
if (!decoder->decode(windowFeatures.fullscreen))
return false;
if (!decoder->decode(windowFeatures.dialog))
return false;
return true;
}
};
template<> struct ArgumentCoder<WebCore::Color> {
static void encode(ArgumentEncoder* encoder, const WebCore::Color& color)
{
if (!color.isValid()) {
encoder->encodeBool(false);
return;
}
encoder->encodeBool(true);
encoder->encode(color.rgb());
}
static bool decode(ArgumentDecoder* decoder, WebCore::Color& color)
{
bool isValid;
if (!decoder->decode(isValid))
return false;
if (!isValid) {
color = WebCore::Color();
return true;
}
WebCore::RGBA32 rgba;
if (!decoder->decode(rgba))
return false;
color = WebCore::Color(rgba);
return true;
}
};
#if PLATFORM(MAC)
template<> struct ArgumentCoder<WebCore::KeypressCommand> {
static void encode(ArgumentEncoder* encoder, const WebCore::KeypressCommand& keypressCommand)
{
encoder->encode(CoreIPC::In(keypressCommand.commandName, keypressCommand.text));
}
static bool decode(ArgumentDecoder* decoder, WebCore::KeypressCommand& keypressCommand)
{
return decoder->decode(CoreIPC::Out(keypressCommand.commandName, keypressCommand.text));
}
};
#endif
template<> struct ArgumentCoder<WebCore::CompositionUnderline> {
static void encode(ArgumentEncoder* encoder, const WebCore::CompositionUnderline& underline)
{
encoder->encode(CoreIPC::In(underline.startOffset, underline.endOffset, underline.thick, underline.color));
}
static bool decode(ArgumentDecoder* decoder, WebCore::CompositionUnderline& underline)
{
return decoder->decode(CoreIPC::Out(underline.startOffset, underline.endOffset, underline.thick, underline.color));
}
};
template<> struct ArgumentCoder<WebCore::DatabaseDetails> {
static void encode(ArgumentEncoder* encoder, const WebCore::DatabaseDetails& details)
{
encoder->encode(CoreIPC::In(details.name(), details.displayName(), details.expectedUsage(), details.currentUsage()));
}
static bool decode(ArgumentDecoder* decoder, WebCore::DatabaseDetails& details)
{
String name;
String displayName;
uint64_t expectedUsage;
uint64_t currentUsage;
if (!decoder->decode(CoreIPC::Out(name, displayName, expectedUsage, currentUsage)))
return false;
details = WebCore::DatabaseDetails(name, displayName, expectedUsage, currentUsage);
return true;
}
};
template<> struct ArgumentCoder<WebCore::GrammarDetail> {
static void encode(ArgumentEncoder* encoder, const WebCore::GrammarDetail& detail)
{
encoder->encodeInt32(detail.location);
encoder->encodeInt32(detail.length);
encoder->encode(detail.guesses);
encoder->encode(detail.userDescription);
}
static bool decode(ArgumentDecoder* decoder, WebCore::GrammarDetail& detail)
{
if (!decoder->decodeInt32(detail.location))
return false;
if (!decoder->decodeInt32(detail.length))
return false;
if (!decoder->decode(detail.guesses))
return false;
if (!decoder->decode(detail.userDescription))
return false;
return true;
}
};
template<> struct ArgumentCoder<WebCore::TextCheckingResult> {
static void encode(ArgumentEncoder* encoder, const WebCore::TextCheckingResult& result)
{
encoder->encodeEnum(result.type);
encoder->encodeInt32(result.location);
encoder->encodeInt32(result.length);
encoder->encode(result.details);
encoder->encode(result.replacement);
}
static bool decode(ArgumentDecoder* decoder, WebCore::TextCheckingResult& result)
{
if (!decoder->decodeEnum(result.type))
return false;
if (!decoder->decodeInt32(result.location))
return false;
if (!decoder->decodeInt32(result.length))
return false;
if (!decoder->decode(result.details))
return false;
if (!decoder->decode(result.replacement))
return false;
return true;
}
};
} // namespace CoreIPC
#endif // WebCoreArgumentCoders_h