2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebCoreArgumentCoders.h"
29 #include "ShareableBitmap.h"
30 #include <WebCore/AuthenticationChallenge.h>
31 #include <WebCore/Credential.h>
32 #include <WebCore/Cursor.h>
33 #include <WebCore/DatabaseDetails.h>
34 #include <WebCore/DragSession.h>
35 #include <WebCore/Editor.h>
36 #include <WebCore/FileChooser.h>
37 #include <WebCore/GraphicsContext.h>
38 #include <WebCore/GraphicsLayer.h>
39 #include <WebCore/Image.h>
40 #include <WebCore/KURL.h>
41 #include <WebCore/PluginData.h>
42 #include <WebCore/ProtectionSpace.h>
43 #include <WebCore/TextCheckerClient.h>
44 #include <WebCore/ViewportArguments.h>
45 #include <WebCore/WindowFeatures.h>
46 #include <wtf/text/StringHash.h>
48 #if USE(UI_SIDE_COMPOSITING)
49 #include <WebCore/Animation.h>
50 #include <WebCore/FloatPoint3D.h>
51 #include <WebCore/TransformationMatrix.h>
53 #if ENABLE(CSS_FILTERS)
54 #include <WebCore/FilterOperations.h>
58 using namespace WebCore;
59 using namespace WebKit;
63 void ArgumentCoder<AffineTransform>::encode(ArgumentEncoder* encoder, const AffineTransform& affineTransform)
65 SimpleArgumentCoder<AffineTransform>::encode(encoder, affineTransform);
68 bool ArgumentCoder<AffineTransform>::decode(ArgumentDecoder* decoder, AffineTransform& affineTransform)
70 return SimpleArgumentCoder<AffineTransform>::decode(decoder, affineTransform);
74 void ArgumentCoder<FloatPoint>::encode(ArgumentEncoder* encoder, const FloatPoint& floatPoint)
76 SimpleArgumentCoder<FloatPoint>::encode(encoder, floatPoint);
79 bool ArgumentCoder<FloatPoint>::decode(ArgumentDecoder* decoder, FloatPoint& floatPoint)
81 return SimpleArgumentCoder<FloatPoint>::decode(decoder, floatPoint);
85 void ArgumentCoder<FloatRect>::encode(ArgumentEncoder* encoder, const FloatRect& floatRect)
87 SimpleArgumentCoder<FloatRect>::encode(encoder, floatRect);
90 bool ArgumentCoder<FloatRect>::decode(ArgumentDecoder* decoder, FloatRect& floatRect)
92 return SimpleArgumentCoder<FloatRect>::decode(decoder, floatRect);
96 void ArgumentCoder<FloatSize>::encode(ArgumentEncoder* encoder, const FloatSize& floatSize)
98 SimpleArgumentCoder<FloatSize>::encode(encoder, floatSize);
101 bool ArgumentCoder<FloatSize>::decode(ArgumentDecoder* decoder, FloatSize& floatSize)
103 return SimpleArgumentCoder<FloatSize>::decode(decoder, floatSize);
107 void ArgumentCoder<IntPoint>::encode(ArgumentEncoder* encoder, const IntPoint& intPoint)
109 SimpleArgumentCoder<IntPoint>::encode(encoder, intPoint);
112 bool ArgumentCoder<IntPoint>::decode(ArgumentDecoder* decoder, IntPoint& intPoint)
114 return SimpleArgumentCoder<IntPoint>::decode(decoder, intPoint);
118 void ArgumentCoder<IntRect>::encode(ArgumentEncoder* encoder, const IntRect& intRect)
120 SimpleArgumentCoder<IntRect>::encode(encoder, intRect);
123 bool ArgumentCoder<IntRect>::decode(ArgumentDecoder* decoder, IntRect& intRect)
125 return SimpleArgumentCoder<IntRect>::decode(decoder, intRect);
129 void ArgumentCoder<IntSize>::encode(ArgumentEncoder* encoder, const IntSize& intSize)
131 SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
134 bool ArgumentCoder<IntSize>::decode(ArgumentDecoder* decoder, IntSize& intSize)
136 return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
139 void ArgumentCoder<ViewportAttributes>::encode(ArgumentEncoder* encoder, const ViewportAttributes& viewportAttributes)
141 SimpleArgumentCoder<ViewportAttributes>::encode(encoder, viewportAttributes);
144 bool ArgumentCoder<ViewportAttributes>::decode(ArgumentDecoder* decoder, ViewportAttributes& viewportAttributes)
146 return SimpleArgumentCoder<ViewportAttributes>::decode(decoder, viewportAttributes);
149 void ArgumentCoder<MimeClassInfo>::encode(ArgumentEncoder* encoder, const MimeClassInfo& mimeClassInfo)
151 encoder->encode(mimeClassInfo.type);
152 encoder->encode(mimeClassInfo.desc);
153 encoder->encode(mimeClassInfo.extensions);
156 bool ArgumentCoder<MimeClassInfo>::decode(ArgumentDecoder* decoder, MimeClassInfo& mimeClassInfo)
158 if (!decoder->decode(mimeClassInfo.type))
160 if (!decoder->decode(mimeClassInfo.desc))
162 if (!decoder->decode(mimeClassInfo.extensions))
169 void ArgumentCoder<PluginInfo>::encode(ArgumentEncoder* encoder, const PluginInfo& pluginInfo)
171 encoder->encode(pluginInfo.name);
172 encoder->encode(pluginInfo.file);
173 encoder->encode(pluginInfo.desc);
174 encoder->encode(pluginInfo.mimes);
177 bool ArgumentCoder<PluginInfo>::decode(ArgumentDecoder* decoder, PluginInfo& pluginInfo)
179 if (!decoder->decode(pluginInfo.name))
181 if (!decoder->decode(pluginInfo.file))
183 if (!decoder->decode(pluginInfo.desc))
185 if (!decoder->decode(pluginInfo.mimes))
192 void ArgumentCoder<HTTPHeaderMap>::encode(ArgumentEncoder* encoder, const HTTPHeaderMap& headerMap)
194 encoder->encode(static_cast<const HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap));
197 bool ArgumentCoder<HTTPHeaderMap>::decode(ArgumentDecoder* decoder, HTTPHeaderMap& headerMap)
199 return decoder->decode(static_cast<HashMap<AtomicString, String, CaseFoldingHash>&>(headerMap));
203 void ArgumentCoder<AuthenticationChallenge>::encode(ArgumentEncoder* encoder, const AuthenticationChallenge& challenge)
205 encoder->encode(challenge.protectionSpace());
206 encoder->encode(challenge.proposedCredential());
207 encoder->encode(challenge.previousFailureCount());
208 encoder->encode(challenge.failureResponse());
209 encoder->encode(challenge.error());
212 bool ArgumentCoder<AuthenticationChallenge>::decode(ArgumentDecoder* decoder, AuthenticationChallenge& challenge)
214 ProtectionSpace protectionSpace;
215 if (!decoder->decode(protectionSpace))
218 Credential proposedCredential;
219 if (!decoder->decode(proposedCredential))
222 unsigned previousFailureCount;
223 if (!decoder->decode(previousFailureCount))
226 ResourceResponse failureResponse;
227 if (!decoder->decode(failureResponse))
231 if (!decoder->decode(error))
234 challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
239 void ArgumentCoder<ProtectionSpace>::encode(ArgumentEncoder* encoder, const ProtectionSpace& space)
241 encoder->encode(space.host());
242 encoder->encode(space.port());
243 encoder->encodeEnum(space.serverType());
244 encoder->encode(space.realm());
245 encoder->encodeEnum(space.authenticationScheme());
248 bool ArgumentCoder<ProtectionSpace>::decode(ArgumentDecoder* decoder, ProtectionSpace& space)
251 if (!decoder->decode(host))
255 if (!decoder->decode(port))
258 ProtectionSpaceServerType serverType;
259 if (!decoder->decodeEnum(serverType))
263 if (!decoder->decode(realm))
266 ProtectionSpaceAuthenticationScheme authenticationScheme;
267 if (!decoder->decodeEnum(authenticationScheme))
270 space = ProtectionSpace(host, port, serverType, realm, authenticationScheme);
274 void ArgumentCoder<Credential>::encode(ArgumentEncoder* encoder, const Credential& credential)
276 encoder->encode(credential.user());
277 encoder->encode(credential.password());
278 encoder->encodeEnum(credential.persistence());
281 bool ArgumentCoder<Credential>::decode(ArgumentDecoder* decoder, Credential& credential)
284 if (!decoder->decode(user))
288 if (!decoder->decode(password))
291 CredentialPersistence persistence;
292 if (!decoder->decodeEnum(persistence))
295 credential = Credential(user, password, persistence);
299 static void encodeImage(ArgumentEncoder* encoder, Image* image)
301 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), ShareableBitmap::SupportsAlpha);
302 bitmap->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
304 ShareableBitmap::Handle handle;
305 bitmap->createHandle(handle);
307 encoder->encode(handle);
310 static bool decodeImage(ArgumentDecoder* decoder, RefPtr<Image>& image)
312 ShareableBitmap::Handle handle;
313 if (!decoder->decode(handle))
316 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
319 image = bitmap->createImage();
325 void ArgumentCoder<Cursor>::encode(ArgumentEncoder* encoder, const Cursor& cursor)
327 encoder->encodeEnum(cursor.type());
329 if (cursor.type() != Cursor::Custom)
332 if (cursor.image()->isNull()) {
333 encoder->encodeBool(false); // There is no valid image being encoded.
337 encoder->encodeBool(true);
338 encodeImage(encoder, cursor.image());
339 encoder->encode(cursor.hotSpot());
342 bool ArgumentCoder<Cursor>::decode(ArgumentDecoder* decoder, Cursor& cursor)
345 if (!decoder->decodeEnum(type))
348 if (type > Cursor::Custom)
351 if (type != Cursor::Custom) {
352 const Cursor& cursorReference = Cursor::fromType(type);
353 // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore.
354 // This will avoid having to re-create the platform cursors over and over.
355 (void)cursorReference.platformCursor();
357 cursor = cursorReference;
361 bool isValidImagePresent;
362 if (!decoder->decode(isValidImagePresent))
365 if (!isValidImagePresent) {
366 cursor = Cursor(Image::nullImage(), IntPoint());
371 if (!decodeImage(decoder, image))
375 if (!decoder->decode(hotSpot))
378 if (!image->rect().contains(hotSpot))
381 cursor = Cursor(image.get(), hotSpot);
386 void ArgumentCoder<WindowFeatures>::encode(ArgumentEncoder* encoder, const WindowFeatures& windowFeatures)
388 encoder->encode(windowFeatures.x);
389 encoder->encode(windowFeatures.y);
390 encoder->encode(windowFeatures.width);
391 encoder->encode(windowFeatures.height);
392 encoder->encode(windowFeatures.xSet);
393 encoder->encode(windowFeatures.ySet);
394 encoder->encode(windowFeatures.widthSet);
395 encoder->encode(windowFeatures.heightSet);
396 encoder->encode(windowFeatures.menuBarVisible);
397 encoder->encode(windowFeatures.statusBarVisible);
398 encoder->encode(windowFeatures.toolBarVisible);
399 encoder->encode(windowFeatures.locationBarVisible);
400 encoder->encode(windowFeatures.scrollbarsVisible);
401 encoder->encode(windowFeatures.resizable);
402 encoder->encode(windowFeatures.fullscreen);
403 encoder->encode(windowFeatures.dialog);
406 bool ArgumentCoder<WindowFeatures>::decode(ArgumentDecoder* decoder, WindowFeatures& windowFeatures)
408 if (!decoder->decode(windowFeatures.x))
410 if (!decoder->decode(windowFeatures.y))
412 if (!decoder->decode(windowFeatures.width))
414 if (!decoder->decode(windowFeatures.height))
416 if (!decoder->decode(windowFeatures.xSet))
418 if (!decoder->decode(windowFeatures.ySet))
420 if (!decoder->decode(windowFeatures.widthSet))
422 if (!decoder->decode(windowFeatures.heightSet))
424 if (!decoder->decode(windowFeatures.menuBarVisible))
426 if (!decoder->decode(windowFeatures.statusBarVisible))
428 if (!decoder->decode(windowFeatures.toolBarVisible))
430 if (!decoder->decode(windowFeatures.locationBarVisible))
432 if (!decoder->decode(windowFeatures.scrollbarsVisible))
434 if (!decoder->decode(windowFeatures.resizable))
436 if (!decoder->decode(windowFeatures.fullscreen))
438 if (!decoder->decode(windowFeatures.dialog))
444 void ArgumentCoder<Color>::encode(ArgumentEncoder* encoder, const Color& color)
446 if (!color.isValid()) {
447 encoder->encodeBool(false);
451 encoder->encodeBool(true);
452 encoder->encode(color.rgb());
455 bool ArgumentCoder<Color>::decode(ArgumentDecoder* decoder, Color& color)
458 if (!decoder->decode(isValid))
467 if (!decoder->decode(rgba))
475 void ArgumentCoder<CompositionUnderline>::encode(ArgumentEncoder* encoder, const CompositionUnderline& underline)
477 encoder->encode(underline.startOffset);
478 encoder->encode(underline.endOffset);
479 encoder->encode(underline.thick);
480 encoder->encode(underline.color);
483 bool ArgumentCoder<CompositionUnderline>::decode(ArgumentDecoder* decoder, CompositionUnderline& underline)
485 if (!decoder->decode(underline.startOffset))
487 if (!decoder->decode(underline.endOffset))
489 if (!decoder->decode(underline.thick))
491 if (!decoder->decode(underline.color))
498 void ArgumentCoder<DatabaseDetails>::encode(ArgumentEncoder* encoder, const DatabaseDetails& details)
500 encoder->encode(details.name());
501 encoder->encode(details.displayName());
502 encoder->encode(details.expectedUsage());
503 encoder->encode(details.currentUsage());
506 bool ArgumentCoder<DatabaseDetails>::decode(ArgumentDecoder* decoder, DatabaseDetails& details)
509 if (!decoder->decode(name))
513 if (!decoder->decode(displayName))
516 uint64_t expectedUsage;
517 if (!decoder->decode(expectedUsage))
520 uint64_t currentUsage;
521 if (!decoder->decode(currentUsage))
524 details = DatabaseDetails(name, displayName, expectedUsage, currentUsage);
529 void ArgumentCoder<FileChooserSettings>::encode(ArgumentEncoder* encoder, const FileChooserSettings& settings)
531 encoder->encode(settings.allowsMultipleFiles);
532 #if ENABLE(DIRECTORY_UPLOAD)
533 encoder->encode(settings.allowsDirectoryUpload);
535 encoder->encode(settings.acceptMIMETypes);
536 encoder->encode(settings.selectedFiles);
537 #if ENABLE(MEDIA_CAPTURE)
538 encoder->encode(settings.capture);
542 bool ArgumentCoder<FileChooserSettings>::decode(ArgumentDecoder* decoder, FileChooserSettings& settings)
544 if (!decoder->decode(settings.allowsMultipleFiles))
546 #if ENABLE(DIRECTORY_UPLOAD)
547 if (!decoder->decode(settings.allowsDirectoryUpload))
550 if (!decoder->decode(settings.acceptMIMETypes))
552 if (!decoder->decode(settings.selectedFiles))
554 #if ENABLE(MEDIA_CAPTURE)
555 if (!decoder->decode(settings.capture))
563 void ArgumentCoder<GrammarDetail>::encode(ArgumentEncoder* encoder, const GrammarDetail& detail)
565 encoder->encode(detail.location);
566 encoder->encode(detail.length);
567 encoder->encode(detail.guesses);
568 encoder->encode(detail.userDescription);
571 bool ArgumentCoder<GrammarDetail>::decode(ArgumentDecoder* decoder, GrammarDetail& detail)
573 if (!decoder->decode(detail.location))
575 if (!decoder->decode(detail.length))
577 if (!decoder->decode(detail.guesses))
579 if (!decoder->decode(detail.userDescription))
586 void ArgumentCoder<TextCheckingResult>::encode(ArgumentEncoder* encoder, const TextCheckingResult& result)
588 encoder->encodeEnum(result.type);
589 encoder->encode(result.location);
590 encoder->encode(result.length);
591 encoder->encode(result.details);
592 encoder->encode(result.replacement);
595 bool ArgumentCoder<TextCheckingResult>::decode(ArgumentDecoder* decoder, TextCheckingResult& result)
597 if (!decoder->decodeEnum(result.type))
599 if (!decoder->decode(result.location))
601 if (!decoder->decode(result.length))
603 if (!decoder->decode(result.details))
605 if (!decoder->decode(result.replacement))
610 void ArgumentCoder<DragSession>::encode(ArgumentEncoder* encoder, const DragSession& result)
612 encoder->encodeEnum(result.operation);
613 encoder->encode(result.mouseIsOverFileInput);
614 encoder->encode(result.numberOfItemsToBeAccepted);
617 bool ArgumentCoder<DragSession>::decode(ArgumentDecoder* decoder, DragSession& result)
619 if (!decoder->decodeEnum(result.operation))
621 if (!decoder->decode(result.mouseIsOverFileInput))
623 if (!decoder->decode(result.numberOfItemsToBeAccepted))
628 void ArgumentCoder<KURL>::encode(ArgumentEncoder* encoder, const KURL& result)
630 encoder->encode(result.string());
633 bool ArgumentCoder<KURL>::decode(ArgumentDecoder* decoder, KURL& result)
636 if (!decoder->decode(urlAsString))
638 result = KURL(WebCore::ParsedURLString, urlAsString);
642 #if USE(UI_SIDE_COMPOSITING)
643 void ArgumentCoder<FloatPoint3D>::encode(ArgumentEncoder* encoder, const FloatPoint3D& floatPoint3D)
645 SimpleArgumentCoder<FloatPoint3D>::encode(encoder, floatPoint3D);
648 bool ArgumentCoder<FloatPoint3D>::decode(ArgumentDecoder* decoder, FloatPoint3D& floatPoint3D)
650 return SimpleArgumentCoder<FloatPoint3D>::decode(decoder, floatPoint3D);
653 void ArgumentCoder<Length>::encode(ArgumentEncoder* encoder, const Length& length)
655 SimpleArgumentCoder<Length>::encode(encoder, length);
658 bool ArgumentCoder<Length>::decode(ArgumentDecoder* decoder, Length& length)
660 return SimpleArgumentCoder<Length>::decode(decoder, length);
663 void ArgumentCoder<TransformationMatrix>::encode(ArgumentEncoder* encoder, const TransformationMatrix& transformationMatrix)
665 SimpleArgumentCoder<TransformationMatrix>::encode(encoder, transformationMatrix);
668 bool ArgumentCoder<TransformationMatrix>::decode(ArgumentDecoder* decoder, TransformationMatrix& transformationMatrix)
670 return SimpleArgumentCoder<TransformationMatrix>::decode(decoder, transformationMatrix);
673 #if ENABLE(CSS_FILTERS)
674 void ArgumentCoder<WebCore::FilterOperations>::encode(ArgumentEncoder* encoder, const WebCore::FilterOperations& filters)
676 encoder->encodeUInt32(filters.size());
677 for (size_t i = 0; i < filters.size(); ++i) {
678 const FilterOperation* filter = filters.at(i);
679 FilterOperation::OperationType type = filter->getOperationType();
680 encoder->encodeEnum(type);
682 case FilterOperation::GRAYSCALE:
683 case FilterOperation::SEPIA:
684 case FilterOperation::SATURATE:
685 case FilterOperation::HUE_ROTATE:
686 encoder->encodeDouble(static_cast<const BasicColorMatrixFilterOperation*>(filter)->amount());
688 case FilterOperation::INVERT:
689 case FilterOperation::BRIGHTNESS:
690 case FilterOperation::CONTRAST:
691 case FilterOperation::OPACITY:
692 encoder->encodeDouble(static_cast<const BasicComponentTransferFilterOperation*>(filter)->amount());
694 case FilterOperation::BLUR:
695 ArgumentCoder<Length>::encode(encoder, static_cast<const BlurFilterOperation*>(filter)->stdDeviation());
697 case FilterOperation::DROP_SHADOW: {
698 const DropShadowFilterOperation* shadow = static_cast<const DropShadowFilterOperation*>(filter);
699 ArgumentCoder<IntPoint>::encode(encoder, shadow->location());
700 encoder->encodeInt32(shadow->stdDeviation());
701 ArgumentCoder<Color>::encode(encoder, shadow->color());
710 bool ArgumentCoder<WebCore::FilterOperations>::decode(ArgumentDecoder* decoder, WebCore::FilterOperations& filters)
713 if (!decoder->decodeUInt32(size))
716 Vector<RefPtr<FilterOperation> >& operations = filters.operations();
718 for (size_t i = 0; i < size; ++i) {
719 FilterOperation::OperationType type;
720 RefPtr<FilterOperation> filter;
721 if (!decoder->decodeEnum(type))
725 case FilterOperation::GRAYSCALE:
726 case FilterOperation::SEPIA:
727 case FilterOperation::SATURATE:
728 case FilterOperation::HUE_ROTATE: {
730 if (!decoder->decodeDouble(value))
732 filter = BasicColorMatrixFilterOperation::create(value, type);
735 case FilterOperation::INVERT:
736 case FilterOperation::BRIGHTNESS:
737 case FilterOperation::CONTRAST:
738 case FilterOperation::OPACITY: {
740 if (!decoder->decodeDouble(value))
742 filter = BasicComponentTransferFilterOperation::create(value, type);
745 case FilterOperation::BLUR: {
747 if (!ArgumentCoder<Length>::decode(decoder, length))
749 filter = BlurFilterOperation::create(length, type);
752 case FilterOperation::DROP_SHADOW: {
754 int32_t stdDeviation;
756 if (!ArgumentCoder<IntPoint>::decode(decoder, location))
758 if (!decoder->decodeInt32(stdDeviation))
760 if (!ArgumentCoder<Color>::decode(decoder, color))
762 filter = DropShadowFilterOperation::create(location, stdDeviation, color, type);
770 operations.append(filter);
779 } // namespace CoreIPC