Home | History | Annotate | Download | only in Shared
      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