/* * Copyright (C) 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. */ #include "config.h" #include "WebCoreArgumentCoders.h" #include "DataReference.h" #include "ShareableBitmap.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if PLATFORM(COCOA) #include "ArgumentCodersCF.h" #endif #if PLATFORM(IOS) #include #include #include #include #include #endif // PLATFORM(IOS) using namespace WebCore; using namespace WebKit; namespace IPC { void ArgumentCoder::encode(ArgumentEncoder& encoder, const AffineTransform& affineTransform) { SimpleArgumentCoder::encode(encoder, affineTransform); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, AffineTransform& affineTransform) { return SimpleArgumentCoder::decode(decoder, affineTransform); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const TransformationMatrix& transformationMatrix) { SimpleArgumentCoder::encode(encoder, transformationMatrix); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, TransformationMatrix& transformationMatrix) { return SimpleArgumentCoder::decode(decoder, transformationMatrix); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const LinearTimingFunction& timingFunction) { encoder.encodeEnum(timingFunction.type()); } bool ArgumentCoder::decode(ArgumentDecoder&, LinearTimingFunction&) { // Type is decoded by the caller. Nothing else to decode. return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const CubicBezierTimingFunction& timingFunction) { encoder.encodeEnum(timingFunction.type()); encoder << timingFunction.x1(); encoder << timingFunction.y1(); encoder << timingFunction.x2(); encoder << timingFunction.y2(); encoder.encodeEnum(timingFunction.timingFunctionPreset()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, CubicBezierTimingFunction& timingFunction) { // Type is decoded by the caller. double x1; if (!decoder.decode(x1)) return false; double y1; if (!decoder.decode(y1)) return false; double x2; if (!decoder.decode(x2)) return false; double y2; if (!decoder.decode(y2)) return false; CubicBezierTimingFunction::TimingFunctionPreset preset; if (!decoder.decodeEnum(preset)) return false; timingFunction.setValues(x1, y1, x2, y2); timingFunction.setTimingFunctionPreset(preset); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const StepsTimingFunction& timingFunction) { encoder.encodeEnum(timingFunction.type()); encoder << timingFunction.numberOfSteps(); encoder << timingFunction.stepAtStart(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, StepsTimingFunction& timingFunction) { // Type is decoded by the caller. int numSteps; if (!decoder.decode(numSteps)) return false; bool stepAtStart; if (!decoder.decode(stepAtStart)) return false; timingFunction.setNumberOfSteps(numSteps); timingFunction.setStepAtStart(stepAtStart); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FloatPoint& floatPoint) { SimpleArgumentCoder::encode(encoder, floatPoint); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FloatPoint& floatPoint) { return SimpleArgumentCoder::decode(decoder, floatPoint); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FloatPoint3D& floatPoint) { SimpleArgumentCoder::encode(encoder, floatPoint); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FloatPoint3D& floatPoint) { return SimpleArgumentCoder::decode(decoder, floatPoint); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FloatRect& floatRect) { SimpleArgumentCoder::encode(encoder, floatRect); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FloatRect& floatRect) { return SimpleArgumentCoder::decode(decoder, floatRect); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FloatSize& floatSize) { SimpleArgumentCoder::encode(encoder, floatSize); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FloatSize& floatSize) { return SimpleArgumentCoder::decode(decoder, floatSize); } #if PLATFORM(IOS) void ArgumentCoder::encode(ArgumentEncoder& encoder, const FloatQuad& floatQuad) { SimpleArgumentCoder::encode(encoder, floatQuad); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FloatQuad& floatQuad) { return SimpleArgumentCoder::decode(decoder, floatQuad); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const ViewportArguments& viewportArguments) { SimpleArgumentCoder::encode(encoder, viewportArguments); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ViewportArguments& viewportArguments) { return SimpleArgumentCoder::decode(decoder, viewportArguments); } #endif // PLATFORM(IOS) void ArgumentCoder::encode(ArgumentEncoder& encoder, const IntPoint& intPoint) { SimpleArgumentCoder::encode(encoder, intPoint); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IntPoint& intPoint) { return SimpleArgumentCoder::decode(decoder, intPoint); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IntRect& intRect) { SimpleArgumentCoder::encode(encoder, intRect); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IntRect& intRect) { return SimpleArgumentCoder::decode(decoder, intRect); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IntSize& intSize) { SimpleArgumentCoder::encode(encoder, intSize); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IntSize& intSize) { return SimpleArgumentCoder::decode(decoder, intSize); } template<> struct ArgumentCoder { static void encode(ArgumentEncoder&, const Region::Span&); static bool decode(ArgumentDecoder&, Region::Span&); }; void ArgumentCoder::encode(ArgumentEncoder& encoder, const Region::Span& span) { encoder << span.y; encoder << (uint64_t)span.segmentIndex; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Region::Span& span) { if (!decoder.decode(span.y)) return false; uint64_t segmentIndex; if (!decoder.decode(segmentIndex)) return false; span.segmentIndex = segmentIndex; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const Region& region) { encoder.encode(region.shapeSegments()); encoder.encode(region.shapeSpans()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Region& region) { Vector segments; if (!decoder.decode(segments)) return false; Vector spans; if (!decoder.decode(spans)) return false; region.setShapeSegments(segments); region.setShapeSpans(spans); region.updateBoundsFromShape(); if (!region.isValid()) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const Length& length) { SimpleArgumentCoder::encode(encoder, length); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Length& length) { return SimpleArgumentCoder::decode(decoder, length); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const ViewportAttributes& viewportAttributes) { SimpleArgumentCoder::encode(encoder, viewportAttributes); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ViewportAttributes& viewportAttributes) { return SimpleArgumentCoder::decode(decoder, viewportAttributes); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const MimeClassInfo& mimeClassInfo) { encoder << mimeClassInfo.type << mimeClassInfo.desc << mimeClassInfo.extensions; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, 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; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const PluginInfo& pluginInfo) { encoder << pluginInfo.name << pluginInfo.file << pluginInfo.desc << pluginInfo.mimes << pluginInfo.isApplicationPlugin; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, 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; if (!decoder.decode(pluginInfo.isApplicationPlugin)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const HTTPHeaderMap& headerMap) { encoder << static_cast(headerMap.size()); for (auto& keyValuePair : headerMap) { encoder << keyValuePair.key; encoder << keyValuePair.value; } } bool ArgumentCoder::decode(ArgumentDecoder& decoder, HTTPHeaderMap& headerMap) { uint64_t size; if (!decoder.decode(size)) return false; for (size_t i = 0; i < size; ++i) { String name; if (!decoder.decode(name)) return false; String value; if (!decoder.decode(value)) return false; headerMap.set(name, value); } return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const AuthenticationChallenge& challenge) { encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, AuthenticationChallenge& challenge) { ProtectionSpace protectionSpace; if (!decoder.decode(protectionSpace)) return false; Credential proposedCredential; if (!decoder.decode(proposedCredential)) return false; unsigned previousFailureCount; if (!decoder.decode(previousFailureCount)) return false; ResourceResponse failureResponse; if (!decoder.decode(failureResponse)) return false; ResourceError error; if (!decoder.decode(error)) return false; challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const ProtectionSpace& space) { if (space.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, space); return; } encoder << false; encoder << space.host() << space.port() << space.realm(); encoder.encodeEnum(space.authenticationScheme()); encoder.encodeEnum(space.serverType()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ProtectionSpace& space) { bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; if (hasPlatformData) return decodePlatformData(decoder, space); String host; if (!decoder.decode(host)) return false; int port; if (!decoder.decode(port)) return false; String realm; if (!decoder.decode(realm)) return false; ProtectionSpaceAuthenticationScheme authenticationScheme; if (!decoder.decodeEnum(authenticationScheme)) return false; ProtectionSpaceServerType serverType; if (!decoder.decodeEnum(serverType)) return false; space = ProtectionSpace(host, port, serverType, realm, authenticationScheme); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const Credential& credential) { #if CERTIFICATE_CREDENTIALS_SUPPORTED encoder.encodeEnum(credential.type()); if (credential.type() == CredentialTypeClientCertificate) { IPC::encode(encoder, credential.identity()); encoder << !!credential.certificates(); if (credential.certificates()) IPC::encode(encoder, credential.certificates()); encoder.encodeEnum(credential.persistence()); return; } #endif encoder << credential.user() << credential.password(); encoder.encodeEnum(credential.persistence()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Credential& credential) { #if CERTIFICATE_CREDENTIALS_SUPPORTED CredentialType type; if (!decoder.decodeEnum(type)) return false; if (type == CredentialTypeClientCertificate) { RetainPtr identity; if (!IPC::decode(decoder, identity)) return false; bool hasCertificates; if (!decoder.decode(hasCertificates)) return false; RetainPtr certificates; if (hasCertificates) { if (!IPC::decode(decoder, certificates)) return false; } CredentialPersistence persistence; if (!decoder.decodeEnum(persistence)) return false; credential = Credential(identity.get(), certificates.get(), persistence); return true; } #endif String user; if (!decoder.decode(user)) return false; String password; if (!decoder.decode(password)) return false; CredentialPersistence persistence; if (!decoder.decodeEnum(persistence)) return false; credential = Credential(user, password, persistence); return true; } static void encodeImage(ArgumentEncoder& encoder, Image* image) { RefPtr bitmap = ShareableBitmap::createShareable(IntSize(image->size()), ShareableBitmap::SupportsAlpha); bitmap->createGraphicsContext()->drawImage(image, ColorSpaceDeviceRGB, IntPoint()); ShareableBitmap::Handle handle; bitmap->createHandle(handle); encoder << handle; } static bool decodeImage(ArgumentDecoder& decoder, RefPtr& image) { ShareableBitmap::Handle handle; if (!decoder.decode(handle)) return false; RefPtr bitmap = ShareableBitmap::create(handle); if (!bitmap) return false; image = bitmap->createImage(); if (!image) return false; return true; } #if !PLATFORM(IOS) void ArgumentCoder::encode(ArgumentEncoder& encoder, const Cursor& cursor) { encoder.encodeEnum(cursor.type()); if (cursor.type() != Cursor::Custom) return; if (cursor.image()->isNull()) { encoder << false; // There is no valid image being encoded. return; } encoder << true; encodeImage(encoder, cursor.image()); encoder << cursor.hotSpot(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Cursor& cursor) { Cursor::Type type; if (!decoder.decodeEnum(type)) return false; if (type > Cursor::Custom) return false; if (type != Cursor::Custom) { const Cursor& cursorReference = Cursor::fromType(type); // Calling platformCursor here will eagerly create the platform cursor for the cursor singletons inside WebCore. // This will avoid having to re-create the platform cursors over and over. (void)cursorReference.platformCursor(); cursor = cursorReference; return true; } bool isValidImagePresent; if (!decoder.decode(isValidImagePresent)) return false; if (!isValidImagePresent) { cursor = Cursor(Image::nullImage(), IntPoint()); return true; } RefPtr image; if (!decodeImage(decoder, image)) return false; IntPoint hotSpot; if (!decoder.decode(hotSpot)) return false; if (!image->rect().contains(hotSpot)) return false; cursor = Cursor(image.get(), hotSpot); return true; } #endif void ArgumentCoder::encode(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest) { if (kShouldSerializeWebCoreData) { encoder << resourceRequest.url().string(); encoder << resourceRequest.httpMethod(); encoder << resourceRequest.httpHeaderFields(); // FIXME: Do not encode HTTP message body. // 1. It can be large and thus costly to send across. // 2. It is misleading to provide a body with some requests, while others use body streams, which cannot be serialized at all. FormData* httpBody = resourceRequest.httpBody(); encoder << static_cast(httpBody); if (httpBody) encoder << httpBody->flattenToString(); encoder << resourceRequest.firstPartyForCookies().string(); } #if ENABLE(CACHE_PARTITIONING) encoder << resourceRequest.cachePartition(); #endif #if ENABLE(INSPECTOR) encoder << resourceRequest.hiddenFromInspector(); #endif if (resourceRequest.encodingRequiresPlatformData()) { encoder << true; encodePlatformData(encoder, resourceRequest); return; } encoder << false; resourceRequest.encodeWithoutPlatformData(encoder); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ResourceRequest& resourceRequest) { if (kShouldSerializeWebCoreData) { ResourceRequest request; String url; if (!decoder.decode(url)) return false; request.setURL(URL(URL(), url)); String httpMethod; if (!decoder.decode(httpMethod)) return false; request.setHTTPMethod(httpMethod); HTTPHeaderMap headers; if (!decoder.decode(headers)) return false; request.setHTTPHeaderFields(WTF::move(headers)); bool hasHTTPBody; if (!decoder.decode(hasHTTPBody)) return false; if (hasHTTPBody) { String httpBody; if (!decoder.decode(httpBody)) return false; request.setHTTPBody(FormData::create(httpBody.utf8())); } String firstPartyForCookies; if (!decoder.decode(firstPartyForCookies)) return false; request.setFirstPartyForCookies(URL(URL(), firstPartyForCookies)); resourceRequest = request; } #if ENABLE(CACHE_PARTITIONING) String cachePartition; if (!decoder.decode(cachePartition)) return false; resourceRequest.setCachePartition(cachePartition); #endif #if ENABLE(INSPECTOR) bool isHiddenFromInspector; if (!decoder.decode(isHiddenFromInspector)) return false; resourceRequest.setHiddenFromInspector(isHiddenFromInspector); #endif bool hasPlatformData; if (!decoder.decode(hasPlatformData)) return false; if (hasPlatformData) return decodePlatformData(decoder, resourceRequest); return resourceRequest.decodeWithoutPlatformData(decoder); } void ArgumentCoder::encode(ArgumentEncoder& encoder, const ResourceResponse& resourceResponse) { #if PLATFORM(COCOA) bool shouldSerializeWebCoreData = !resourceResponse.platformResponseIsUpToDate(); encoder << shouldSerializeWebCoreData; #else bool shouldSerializeWebCoreData = true; #endif encodePlatformData(encoder, resourceResponse); if (shouldSerializeWebCoreData) { bool responseIsNull = resourceResponse.isNull(); encoder << responseIsNull; if (responseIsNull) return; encoder << resourceResponse.url().string(); encoder << static_cast(resourceResponse.httpStatusCode()); encoder << resourceResponse.httpHeaderFields(); encoder << resourceResponse.mimeType(); encoder << resourceResponse.textEncodingName(); encoder << static_cast(resourceResponse.expectedContentLength()); encoder << resourceResponse.httpStatusText(); encoder << resourceResponse.suggestedFilename(); } #if ENABLE(WEB_TIMING) const ResourceLoadTiming& timing = resourceResponse.resourceLoadTiming(); encoder << timing.domainLookupStart; encoder << timing.domainLookupEnd; encoder << timing.connectStart; encoder << timing.connectEnd; encoder << timing.requestStart; encoder << timing.responseStart; encoder << timing.secureConnectionStart; #endif } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ResourceResponse& resourceResponse) { #if PLATFORM(COCOA) bool hasSerializedWebCoreData; if (!decoder.decode(hasSerializedWebCoreData)) return false; #else bool hasSerializedWebCoreData = true; #endif ResourceResponse response; if (!decodePlatformData(decoder, response)) return false; if (hasSerializedWebCoreData) { bool responseIsNull; if (!decoder.decode(responseIsNull)) return false; if (responseIsNull) { resourceResponse = ResourceResponse(); return true; } String url; if (!decoder.decode(url)) return false; response.setURL(URL(URL(), url)); int32_t httpStatusCode; if (!decoder.decode(httpStatusCode)) return false; response.setHTTPStatusCode(httpStatusCode); HTTPHeaderMap headers; if (!decoder.decode(headers)) return false; for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it) response.setHTTPHeaderField(it->key, it->value); String mimeType; if (!decoder.decode(mimeType)) return false; response.setMimeType(mimeType); String textEncodingName; if (!decoder.decode(textEncodingName)) return false; response.setTextEncodingName(textEncodingName); int64_t contentLength; if (!decoder.decode(contentLength)) return false; response.setExpectedContentLength(contentLength); String httpStatusText; if (!decoder.decode(httpStatusText)) return false; response.setHTTPStatusText(httpStatusText); String suggestedFilename; if (!decoder.decode(suggestedFilename)) return false; response.setSuggestedFilename(suggestedFilename); } #if ENABLE(WEB_TIMING) ResourceLoadTiming& timing = response.resourceLoadTiming(); if (!decoder.decode(timing.domainLookupStart) || !decoder.decode(timing.domainLookupEnd) || !decoder.decode(timing.connectStart) || !decoder.decode(timing.connectEnd) || !decoder.decode(timing.requestStart) || !decoder.decode(timing.responseStart) || !decoder.decode(timing.secureConnectionStart)) return false; #endif resourceResponse = response; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const ResourceError& resourceError) { if (kShouldSerializeWebCoreData) { bool errorIsNull = resourceError.isNull(); encoder << errorIsNull; if (errorIsNull) return; encoder << resourceError.domain(); encoder << resourceError.errorCode(); encoder << resourceError.failingURL(); encoder << resourceError.localizedDescription(); encoder << resourceError.isCancellation(); encoder << resourceError.isTimeout(); } encodePlatformData(encoder, resourceError); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ResourceError& resourceError) { if (kShouldSerializeWebCoreData) { bool errorIsNull; if (!decoder.decode(errorIsNull)) return false; if (errorIsNull) { resourceError = ResourceError(); return true; } String domain; if (!decoder.decode(domain)) return false; int errorCode; if (!decoder.decode(errorCode)) return false; String failingURL; if (!decoder.decode(failingURL)) return false; String localizedDescription; if (!decoder.decode(localizedDescription)) return false; bool isCancellation; if (!decoder.decode(isCancellation)) return false; bool isTimeout; if (!decoder.decode(isTimeout)) return false; resourceError = ResourceError(domain, errorCode, failingURL, localizedDescription); resourceError.setIsCancellation(isCancellation); resourceError.setIsTimeout(isTimeout); } return decodePlatformData(decoder, resourceError); } #if PLATFORM(IOS) void ArgumentCoder::encode(ArgumentEncoder& encoder, const SelectionRect& selectionRect) { encoder << selectionRect.rect(); encoder << static_cast(selectionRect.direction()); encoder << selectionRect.minX(); encoder << selectionRect.maxX(); encoder << selectionRect.maxY(); encoder << selectionRect.lineNumber(); encoder << selectionRect.isLineBreak(); encoder << selectionRect.isFirstOnLine(); encoder << selectionRect.isLastOnLine(); encoder << selectionRect.containsStart(); encoder << selectionRect.containsEnd(); encoder << selectionRect.isHorizontal(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, SelectionRect& selectionRect) { IntRect rect; if (!decoder.decode(rect)) return false; selectionRect.setRect(rect); uint32_t direction; if (!decoder.decode(direction)) return false; selectionRect.setDirection((TextDirection)direction); int intValue; if (!decoder.decode(intValue)) return false; selectionRect.setMinX(intValue); if (!decoder.decode(intValue)) return false; selectionRect.setMaxX(intValue); if (!decoder.decode(intValue)) return false; selectionRect.setMaxY(intValue); if (!decoder.decode(intValue)) return false; selectionRect.setLineNumber(intValue); bool boolValue; if (!decoder.decode(boolValue)) return false; selectionRect.setIsLineBreak(boolValue); if (!decoder.decode(boolValue)) return false; selectionRect.setIsFirstOnLine(boolValue); if (!decoder.decode(boolValue)) return false; selectionRect.setIsLastOnLine(boolValue); if (!decoder.decode(boolValue)) return false; selectionRect.setContainsStart(boolValue); if (!decoder.decode(boolValue)) return false; selectionRect.setContainsEnd(boolValue); if (!decoder.decode(boolValue)) return false; selectionRect.setIsHorizontal(boolValue); return true; } #endif void ArgumentCoder::encode(ArgumentEncoder& encoder, const WindowFeatures& windowFeatures) { encoder << windowFeatures.x; encoder << windowFeatures.y; encoder << windowFeatures.width; encoder << windowFeatures.height; encoder << windowFeatures.xSet; encoder << windowFeatures.ySet; encoder << windowFeatures.widthSet; encoder << windowFeatures.heightSet; encoder << windowFeatures.menuBarVisible; encoder << windowFeatures.statusBarVisible; encoder << windowFeatures.toolBarVisible; encoder << windowFeatures.locationBarVisible; encoder << windowFeatures.scrollbarsVisible; encoder << windowFeatures.resizable; encoder << windowFeatures.fullscreen; encoder << windowFeatures.dialog; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, 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; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const Color& color) { if (!color.isValid()) { encoder << false; return; } encoder << true; encoder << color.rgb(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Color& color) { bool isValid; if (!decoder.decode(isValid)) return false; if (!isValid) { color = Color(); return true; } RGBA32 rgba; if (!decoder.decode(rgba)) return false; color = Color(rgba); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const CompositionUnderline& underline) { encoder << underline.startOffset; encoder << underline.endOffset; encoder << underline.thick; encoder << underline.color; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, CompositionUnderline& underline) { if (!decoder.decode(underline.startOffset)) return false; if (!decoder.decode(underline.endOffset)) return false; if (!decoder.decode(underline.thick)) return false; if (!decoder.decode(underline.color)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const Cookie& cookie) { encoder << cookie.name; encoder << cookie.value; encoder << cookie.domain; encoder << cookie.path; encoder << cookie.expires; encoder << cookie.httpOnly; encoder << cookie.secure; encoder << cookie.session; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Cookie& cookie) { if (!decoder.decode(cookie.name)) return false; if (!decoder.decode(cookie.value)) return false; if (!decoder.decode(cookie.domain)) return false; if (!decoder.decode(cookie.path)) return false; if (!decoder.decode(cookie.expires)) return false; if (!decoder.decode(cookie.httpOnly)) return false; if (!decoder.decode(cookie.secure)) return false; if (!decoder.decode(cookie.session)) return false; return true; } #if ENABLE(SQL_DATABASE) void ArgumentCoder::encode(ArgumentEncoder& encoder, const DatabaseDetails& details) { encoder << details.name(); encoder << details.displayName(); encoder << details.expectedUsage(); encoder << details.currentUsage(); encoder << details.creationTime(); encoder << details.modificationTime(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, DatabaseDetails& details) { String name; if (!decoder.decode(name)) return false; String displayName; if (!decoder.decode(displayName)) return false; uint64_t expectedUsage; if (!decoder.decode(expectedUsage)) return false; uint64_t currentUsage; if (!decoder.decode(currentUsage)) return false; double creationTime; if (!decoder.decode(creationTime)) return false; double modificationTime; if (!decoder.decode(modificationTime)) return false; details = DatabaseDetails(name, displayName, expectedUsage, currentUsage, creationTime, modificationTime); return true; } #endif #if PLATFORM(IOS) void ArgumentCoder::encode(ArgumentEncoder& encoder, const Highlight& highlight) { encoder << static_cast(highlight.type); encoder << highlight.usePageCoordinates; encoder << highlight.contentColor; encoder << highlight.contentOutlineColor; encoder << highlight.paddingColor; encoder << highlight.borderColor; encoder << highlight.marginColor; encoder << highlight.quads; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, Highlight& highlight) { uint32_t type; if (!decoder.decode(type)) return false; highlight.type = (HighlightType)type; if (!decoder.decode(highlight.usePageCoordinates)) return false; if (!decoder.decode(highlight.contentColor)) return false; if (!decoder.decode(highlight.contentOutlineColor)) return false; if (!decoder.decode(highlight.paddingColor)) return false; if (!decoder.decode(highlight.borderColor)) return false; if (!decoder.decode(highlight.marginColor)) return false; if (!decoder.decode(highlight.quads)) return false; return true; } static void encodeSharedBuffer(ArgumentEncoder& encoder, SharedBuffer* buffer) { SharedMemory::Handle handle; encoder << (buffer ? static_cast(buffer->size()): 0); if (buffer) { RefPtr sharedMemoryBuffer = SharedMemory::create(buffer->size()); memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size()); sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly); encoder << handle; } } static bool decodeSharedBuffer(ArgumentDecoder& decoder, RefPtr& buffer) { uint64_t bufferSize = 0; if (!decoder.decode(bufferSize)) return false; if (bufferSize) { SharedMemory::Handle handle; if (!decoder.decode(handle)) return false; RefPtr sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly); buffer = SharedBuffer::create(static_cast(sharedMemoryBuffer->data()), bufferSize); } return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const PasteboardWebContent& content) { encoder << content.canSmartCopyOrDelete; encoder << content.dataInStringFormat; encodeSharedBuffer(encoder, content.dataInWebArchiveFormat.get()); encodeSharedBuffer(encoder, content.dataInRTFDFormat.get()); encodeSharedBuffer(encoder, content.dataInRTFFormat.get()); encoder << content.clientTypes; encoder << static_cast(content.clientData.size()); for (size_t i = 0; i < content.clientData.size(); i++) encodeSharedBuffer(encoder, content.clientData[i].get()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, PasteboardWebContent& content) { if (!decoder.decode(content.canSmartCopyOrDelete)) return false; if (!decoder.decode(content.dataInStringFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInWebArchiveFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInRTFDFormat)) return false; if (!decodeSharedBuffer(decoder, content.dataInRTFFormat)) return false; if (!decoder.decode(content.clientTypes)) return false; uint64_t clientDataSize; if (!decoder.decode(clientDataSize)) return false; if (clientDataSize) content.clientData.resize(clientDataSize); for (size_t i = 0; i < clientDataSize; i++) decodeSharedBuffer(decoder, content.clientData[i]); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const PasteboardImage& pasteboardImage) { encodeImage(encoder, pasteboardImage.image.get()); encoder << pasteboardImage.url.url; encoder << pasteboardImage.url.title; encoder << pasteboardImage.resourceMIMEType; if (pasteboardImage.resourceData) encodeSharedBuffer(encoder, pasteboardImage.resourceData.get()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, PasteboardImage& pasteboardImage) { if (!decodeImage(decoder, pasteboardImage.image)) return false; if (!decoder.decode(pasteboardImage.url.url)) return false; if (!decoder.decode(pasteboardImage.url.title)) return false; if (!decoder.decode(pasteboardImage.resourceMIMEType)) return false; if (!decodeSharedBuffer(decoder, pasteboardImage.resourceData)) return false; return true; } #endif void ArgumentCoder::encode(ArgumentEncoder& encoder, const DictationAlternative& dictationAlternative) { encoder << dictationAlternative.rangeStart; encoder << dictationAlternative.rangeLength; encoder << dictationAlternative.dictationContext; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, DictationAlternative& dictationAlternative) { if (!decoder.decode(dictationAlternative.rangeStart)) return false; if (!decoder.decode(dictationAlternative.rangeLength)) return false; if (!decoder.decode(dictationAlternative.dictationContext)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FileChooserSettings& settings) { encoder << settings.allowsMultipleFiles; encoder << settings.acceptMIMETypes; encoder << settings.selectedFiles; #if ENABLE(MEDIA_CAPTURE) encoder << settings.capture; #endif } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FileChooserSettings& settings) { if (!decoder.decode(settings.allowsMultipleFiles)) return false; if (!decoder.decode(settings.acceptMIMETypes)) return false; if (!decoder.decode(settings.selectedFiles)) return false; #if ENABLE(MEDIA_CAPTURE) if (!decoder.decode(settings.capture)) return false; #endif return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const GrammarDetail& detail) { encoder << detail.location; encoder << detail.length; encoder << detail.guesses; encoder << detail.userDescription; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, GrammarDetail& detail) { if (!decoder.decode(detail.location)) return false; if (!decoder.decode(detail.length)) return false; if (!decoder.decode(detail.guesses)) return false; if (!decoder.decode(detail.userDescription)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const TextCheckingRequestData& request) { encoder << request.sequence(); encoder << request.text(); encoder << request.mask(); encoder.encodeEnum(request.processType()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, TextCheckingRequestData& request) { int sequence; if (!decoder.decode(sequence)) return false; String text; if (!decoder.decode(text)) return false; TextCheckingTypeMask mask; if (!decoder.decode(mask)) return false; TextCheckingProcessType processType; if (!decoder.decodeEnum(processType)) return false; request = TextCheckingRequestData(sequence, text, mask, processType); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const TextCheckingResult& result) { encoder.encodeEnum(result.type); encoder << result.location; encoder << result.length; encoder << result.details; encoder << result.replacement; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, TextCheckingResult& result) { if (!decoder.decodeEnum(result.type)) return false; if (!decoder.decode(result.location)) return false; if (!decoder.decode(result.length)) return false; if (!decoder.decode(result.details)) return false; if (!decoder.decode(result.replacement)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const URL& result) { encoder << result.string(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, URL& result) { String urlAsString; if (!decoder.decode(urlAsString)) return false; result = URL(ParsedURLString, urlAsString); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const UserStyleSheet& userStyleSheet) { encoder << userStyleSheet.source(); encoder << userStyleSheet.url(); encoder << userStyleSheet.whitelist(); encoder << userStyleSheet.blacklist(); encoder.encodeEnum(userStyleSheet.injectedFrames()); encoder.encodeEnum(userStyleSheet.level()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, UserStyleSheet& userStyleSheet) { String source; if (!decoder.decode(source)) return false; URL url; if (!decoder.decode(url)) return false; Vector whitelist; if (!decoder.decode(whitelist)) return false; Vector blacklist; if (!decoder.decode(blacklist)) return false; UserContentInjectedFrames injectedFrames; if (!decoder.decodeEnum(injectedFrames)) return false; UserStyleLevel level; if (!decoder.decodeEnum(level)) return false; userStyleSheet = UserStyleSheet(source, url, whitelist, blacklist, injectedFrames, level); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const UserScript& userScript) { encoder << userScript.source(); encoder << userScript.url(); encoder << userScript.whitelist(); encoder << userScript.blacklist(); encoder.encodeEnum(userScript.injectionTime()); encoder.encodeEnum(userScript.injectedFrames()); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, UserScript& userScript) { String source; if (!decoder.decode(source)) return false; URL url; if (!decoder.decode(url)) return false; Vector whitelist; if (!decoder.decode(whitelist)) return false; Vector blacklist; if (!decoder.decode(blacklist)) return false; UserScriptInjectionTime injectionTime; if (!decoder.decodeEnum(injectionTime)) return false; UserContentInjectedFrames injectedFrames; if (!decoder.decodeEnum(injectedFrames)) return false; userScript = UserScript(source, url, whitelist, blacklist, injectionTime, injectedFrames); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const ScrollableAreaParameters& parameters) { encoder.encodeEnum(parameters.horizontalScrollElasticity); encoder.encodeEnum(parameters.verticalScrollElasticity); encoder.encodeEnum(parameters.horizontalScrollbarMode); encoder.encodeEnum(parameters.verticalScrollbarMode); encoder << parameters.hasEnabledHorizontalScrollbar; encoder << parameters.hasEnabledVerticalScrollbar; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, ScrollableAreaParameters& params) { if (!decoder.decodeEnum(params.horizontalScrollElasticity)) return false; if (!decoder.decodeEnum(params.verticalScrollElasticity)) return false; if (!decoder.decodeEnum(params.horizontalScrollbarMode)) return false; if (!decoder.decodeEnum(params.verticalScrollbarMode)) return false; if (!decoder.decode(params.hasEnabledHorizontalScrollbar)) return false; if (!decoder.decode(params.hasEnabledVerticalScrollbar)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FixedPositionViewportConstraints& viewportConstraints) { encoder << viewportConstraints.alignmentOffset(); encoder << viewportConstraints.anchorEdges(); encoder << viewportConstraints.viewportRectAtLastLayout(); encoder << viewportConstraints.layerPositionAtLastLayout(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FixedPositionViewportConstraints& viewportConstraints) { FloatSize alignmentOffset; if (!decoder.decode(alignmentOffset)) return false; ViewportConstraints::AnchorEdges anchorEdges; if (!decoder.decode(anchorEdges)) return false; FloatRect viewportRectAtLastLayout; if (!decoder.decode(viewportRectAtLastLayout)) return false; FloatPoint layerPositionAtLastLayout; if (!decoder.decode(layerPositionAtLastLayout)) return false; viewportConstraints = FixedPositionViewportConstraints(); viewportConstraints.setAlignmentOffset(alignmentOffset); viewportConstraints.setAnchorEdges(anchorEdges); viewportConstraints.setViewportRectAtLastLayout(viewportRectAtLastLayout); viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const StickyPositionViewportConstraints& viewportConstraints) { encoder << viewportConstraints.alignmentOffset(); encoder << viewportConstraints.anchorEdges(); encoder << viewportConstraints.leftOffset(); encoder << viewportConstraints.rightOffset(); encoder << viewportConstraints.topOffset(); encoder << viewportConstraints.bottomOffset(); encoder << viewportConstraints.constrainingRectAtLastLayout(); encoder << viewportConstraints.containingBlockRect(); encoder << viewportConstraints.stickyBoxRect(); encoder << viewportConstraints.stickyOffsetAtLastLayout(); encoder << viewportConstraints.layerPositionAtLastLayout(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, StickyPositionViewportConstraints& viewportConstraints) { FloatSize alignmentOffset; if (!decoder.decode(alignmentOffset)) return false; ViewportConstraints::AnchorEdges anchorEdges; if (!decoder.decode(anchorEdges)) return false; float leftOffset; if (!decoder.decode(leftOffset)) return false; float rightOffset; if (!decoder.decode(rightOffset)) return false; float topOffset; if (!decoder.decode(topOffset)) return false; float bottomOffset; if (!decoder.decode(bottomOffset)) return false; FloatRect constrainingRectAtLastLayout; if (!decoder.decode(constrainingRectAtLastLayout)) return false; FloatRect containingBlockRect; if (!decoder.decode(containingBlockRect)) return false; FloatRect stickyBoxRect; if (!decoder.decode(stickyBoxRect)) return false; FloatSize stickyOffsetAtLastLayout; if (!decoder.decode(stickyOffsetAtLastLayout)) return false; FloatPoint layerPositionAtLastLayout; if (!decoder.decode(layerPositionAtLastLayout)) return false; viewportConstraints = StickyPositionViewportConstraints(); viewportConstraints.setAlignmentOffset(alignmentOffset); viewportConstraints.setAnchorEdges(anchorEdges); viewportConstraints.setLeftOffset(leftOffset); viewportConstraints.setRightOffset(rightOffset); viewportConstraints.setTopOffset(topOffset); viewportConstraints.setBottomOffset(bottomOffset); viewportConstraints.setConstrainingRectAtLastLayout(constrainingRectAtLastLayout); viewportConstraints.setContainingBlockRect(containingBlockRect); viewportConstraints.setStickyBoxRect(stickyBoxRect); viewportConstraints.setStickyOffsetAtLastLayout(stickyOffsetAtLastLayout); viewportConstraints.setLayerPositionAtLastLayout(layerPositionAtLastLayout); return true; } #if ENABLE(CSS_FILTERS) && !USE(COORDINATED_GRAPHICS) void ArgumentCoder::encode(ArgumentEncoder& encoder, const FilterOperation& filter) { encoder.encodeEnum(filter.type()); switch (filter.type()) { case FilterOperation::NONE: case FilterOperation::REFERENCE: ASSERT_NOT_REACHED(); break; case FilterOperation::GRAYSCALE: case FilterOperation::SEPIA: case FilterOperation::SATURATE: case FilterOperation::HUE_ROTATE: encoder << toBasicColorMatrixFilterOperation(filter).amount(); break; case FilterOperation::INVERT: case FilterOperation::OPACITY: case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: encoder << toBasicComponentTransferFilterOperation(filter).amount(); break; case FilterOperation::BLUR: encoder << toBlurFilterOperation(filter).stdDeviation(); break; case FilterOperation::DROP_SHADOW: { const auto& dropShadowFilter = toDropShadowFilterOperation(filter); encoder << dropShadowFilter.location(); encoder << dropShadowFilter.stdDeviation(); encoder << dropShadowFilter.color(); break; } case FilterOperation::DEFAULT: encoder.encodeEnum(toDefaultFilterOperation(filter).representedType()); break; case FilterOperation::PASSTHROUGH: break; } } bool decodeFilterOperation(ArgumentDecoder& decoder, RefPtr& filter) { FilterOperation::OperationType type; if (!decoder.decodeEnum(type)) return false; switch (type) { case FilterOperation::NONE: case FilterOperation::REFERENCE: ASSERT_NOT_REACHED(); decoder.markInvalid(); return false; case FilterOperation::GRAYSCALE: case FilterOperation::SEPIA: case FilterOperation::SATURATE: case FilterOperation::HUE_ROTATE: { double amount; if (!decoder.decode(amount)) return false; filter = BasicColorMatrixFilterOperation::create(amount, type); break; } case FilterOperation::INVERT: case FilterOperation::OPACITY: case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: { double amount; if (!decoder.decode(amount)) return false; filter = BasicComponentTransferFilterOperation::create(amount, type); break; } case FilterOperation::BLUR: { Length stdDeviation; if (!decoder.decode(stdDeviation)) return false; filter = BlurFilterOperation::create(stdDeviation); break; } case FilterOperation::DROP_SHADOW: { IntPoint location; int stdDeviation; Color color; if (!decoder.decode(location)) return false; if (!decoder.decode(stdDeviation)) return false; if (!decoder.decode(color)) return false; filter = DropShadowFilterOperation::create(location, stdDeviation, color); break; } case FilterOperation::DEFAULT: { FilterOperation::OperationType representedType; if (!decoder.decodeEnum(representedType)) return false; filter = DefaultFilterOperation::create(representedType); break; } case FilterOperation::PASSTHROUGH: filter = PassthroughFilterOperation::create(); break; } return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const FilterOperations& filters) { encoder << static_cast(filters.size()); for (const auto& filter : filters.operations()) encoder << *filter; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, FilterOperations& filters) { uint64_t filterCount; if (!decoder.decode(filterCount)) return false; for (uint64_t i = 0; i < filterCount; ++i) { RefPtr filter; if (!decodeFilterOperation(decoder, filter)) return false; filters.operations().append(WTF::move(filter)); } return true; } #endif // ENABLE(CSS_FILTERS) && !USE(COORDINATED_GRAPHICS) #if ENABLE(INDEXED_DATABASE) void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBDatabaseMetadata& metadata) { encoder << metadata.name << metadata.id << metadata.version << metadata.maxObjectStoreId << metadata.objectStores; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBDatabaseMetadata& metadata) { if (!decoder.decode(metadata.name)) return false; if (!decoder.decode(metadata.id)) return false; if (!decoder.decode(metadata.version)) return false; if (!decoder.decode(metadata.maxObjectStoreId)) return false; if (!decoder.decode(metadata.objectStores)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBIndexMetadata& metadata) { encoder << metadata.name << metadata.id << metadata.keyPath << metadata.unique << metadata.multiEntry; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBIndexMetadata& metadata) { if (!decoder.decode(metadata.name)) return false; if (!decoder.decode(metadata.id)) return false; if (!decoder.decode(metadata.keyPath)) return false; if (!decoder.decode(metadata.unique)) return false; if (!decoder.decode(metadata.multiEntry)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBGetResult& result) { bool nullData = !result.valueBuffer; encoder << nullData; if (!nullData) encoder << DataReference(reinterpret_cast(result.valueBuffer->data()), result.valueBuffer->size()); encoder << result.keyData << result.keyPath; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBGetResult& result) { bool nullData; if (!decoder.decode(nullData)) return false; if (nullData) result.valueBuffer = nullptr; else { DataReference data; if (!decoder.decode(data)) return false; result.valueBuffer = SharedBuffer::create(data.data(), data.size()); } if (!decoder.decode(result.keyData)) return false; if (!decoder.decode(result.keyPath)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBKeyData& keyData) { encoder << keyData.isNull; if (keyData.isNull) return; encoder.encodeEnum(keyData.type); switch (keyData.type) { case IDBKey::InvalidType: break; case IDBKey::ArrayType: encoder << keyData.arrayValue; break; case IDBKey::StringType: encoder << keyData.stringValue; break; case IDBKey::DateType: case IDBKey::NumberType: encoder << keyData.numberValue; break; case IDBKey::MaxType: case IDBKey::MinType: // MaxType and MinType are only used for comparison to other keys. // They should never be sent across the wire. ASSERT_NOT_REACHED(); break; } } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBKeyData& keyData) { if (!decoder.decode(keyData.isNull)) return false; if (keyData.isNull) return true; if (!decoder.decodeEnum(keyData.type)) return false; switch (keyData.type) { case IDBKey::InvalidType: break; case IDBKey::ArrayType: if (!decoder.decode(keyData.arrayValue)) return false; break; case IDBKey::StringType: if (!decoder.decode(keyData.stringValue)) return false; break; case IDBKey::DateType: case IDBKey::NumberType: if (!decoder.decode(keyData.numberValue)) return false; break; case IDBKey::MaxType: case IDBKey::MinType: // MaxType and MinType are only used for comparison to other keys. // They should never be sent across the wire. ASSERT_NOT_REACHED(); decoder.markInvalid(); return false; } return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBKeyPath& keyPath) { encoder.encodeEnum(keyPath.type()); switch (keyPath.type()) { case IDBKeyPath::NullType: break; case IDBKeyPath::StringType: encoder << keyPath.string(); break; case IDBKeyPath::ArrayType: encoder << keyPath.array(); break; default: ASSERT_NOT_REACHED(); } } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBKeyPath& keyPath) { IDBKeyPath::Type type; if (!decoder.decodeEnum(type)) return false; switch (type) { case IDBKeyPath::NullType: keyPath = IDBKeyPath(); return true; case IDBKeyPath::StringType: { String string; if (!decoder.decode(string)) return false; keyPath = IDBKeyPath(string); return true; } case IDBKeyPath::ArrayType: { Vector array; if (!decoder.decode(array)) return false; keyPath = IDBKeyPath(array); return true; } default: return false; } } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBKeyRangeData& keyRange) { encoder << keyRange.isNull; if (keyRange.isNull) return; encoder << keyRange.upperKey << keyRange.lowerKey << keyRange.upperOpen << keyRange.lowerOpen; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBKeyRangeData& keyRange) { if (!decoder.decode(keyRange.isNull)) return false; if (keyRange.isNull) return true; if (!decoder.decode(keyRange.upperKey)) return false; if (!decoder.decode(keyRange.lowerKey)) return false; if (!decoder.decode(keyRange.upperOpen)) return false; if (!decoder.decode(keyRange.lowerOpen)) return false; return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const IDBObjectStoreMetadata& metadata) { encoder << metadata.name << metadata.id << metadata.keyPath << metadata.autoIncrement << metadata.maxIndexId << metadata.indexes; } bool ArgumentCoder::decode(ArgumentDecoder& decoder, IDBObjectStoreMetadata& metadata) { if (!decoder.decode(metadata.name)) return false; if (!decoder.decode(metadata.id)) return false; if (!decoder.decode(metadata.keyPath)) return false; if (!decoder.decode(metadata.autoIncrement)) return false; if (!decoder.decode(metadata.maxIndexId)) return false; if (!decoder.decode(metadata.indexes)) return false; return true; } #endif // ENABLE(INDEXED_DATABASE) void ArgumentCoder::encode(ArgumentEncoder& encoder, const SessionID& sessionID) { encoder << sessionID.sessionID(); } bool ArgumentCoder::decode(ArgumentDecoder& decoder, SessionID& sessionID) { uint64_t session; if (!decoder.decode(session)) return false; sessionID = SessionID(session); return true; } void ArgumentCoder::encode(ArgumentEncoder& encoder, const BlobPart& blobPart) { encoder << static_cast(blobPart.type()); switch (blobPart.type()) { case BlobPart::Data: encoder << blobPart.data(); break; case BlobPart::Blob: encoder << blobPart.url(); break; } } bool ArgumentCoder::decode(ArgumentDecoder& decoder, BlobPart& blobPart) { uint32_t type; if (!decoder.decode(type)) return false; switch (type) { case BlobPart::Data: { Vector data; if (!decoder.decode(data)) return false; blobPart = BlobPart(WTF::move(data)); break; } case BlobPart::Blob: { String url; if (!decoder.decode(url)) return false; blobPart = BlobPart(URL(URL(), url)); break; } default: return false; } return true; } } // namespace IPC