diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /dom/file/ipc/IPCBlobUtils.cpp | |
parent | Initial commit. (diff) | |
download | firefox-upstream/124.0.1.tar.xz firefox-upstream/124.0.1.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/file/ipc/IPCBlobUtils.cpp')
-rw-r--r-- | dom/file/ipc/IPCBlobUtils.cpp | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/dom/file/ipc/IPCBlobUtils.cpp b/dom/file/ipc/IPCBlobUtils.cpp new file mode 100644 index 0000000000..78409da529 --- /dev/null +++ b/dom/file/ipc/IPCBlobUtils.cpp @@ -0,0 +1,179 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "IPCBlobUtils.h" +#include "RemoteLazyInputStream.h" +#include "RemoteLazyInputStreamChild.h" +#include "RemoteLazyInputStreamParent.h" +#include "mozilla/dom/IPCBlob.h" +#include "mozilla/ipc/BackgroundParent.h" +#include "mozilla/ipc/PBackgroundParent.h" +#include "mozilla/ipc/PBackgroundChild.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/ipc/IPCStreamUtils.h" +#include "mozilla/ipc/ProtocolUtils.h" +#include "RemoteLazyInputStreamStorage.h" +#include "StreamBlobImpl.h" +#include "prtime.h" + +namespace mozilla::dom::IPCBlobUtils { + +already_AddRefed<BlobImpl> Deserialize(const IPCBlob& aIPCBlob) { + nsCOMPtr<nsIInputStream> inputStream; + + const RemoteLazyStream& stream = aIPCBlob.inputStream(); + switch (stream.type()) { + // Parent to child: when an nsIInputStream is sent from parent to child, the + // child receives a RemoteLazyInputStream actor. + case RemoteLazyStream::TRemoteLazyInputStream: { + inputStream = stream.get_RemoteLazyInputStream(); + break; + } + + // Child to Parent: when a blob is created on the content process send it's + // sent to the parent, we have an IPCStream object. + case RemoteLazyStream::TIPCStream: + MOZ_ASSERT(XRE_IsParentProcess()); + inputStream = DeserializeIPCStream(stream.get_IPCStream()); + break; + + default: + MOZ_CRASH("Unknown type."); + break; + } + + MOZ_ASSERT(inputStream); + + RefPtr<StreamBlobImpl> blobImpl; + + if (aIPCBlob.file().isNothing()) { + blobImpl = StreamBlobImpl::Create(inputStream.forget(), aIPCBlob.type(), + aIPCBlob.size(), aIPCBlob.blobImplType()); + } else { + const IPCFile& file = aIPCBlob.file().ref(); + blobImpl = StreamBlobImpl::Create(inputStream.forget(), file.name(), + aIPCBlob.type(), file.lastModified(), + aIPCBlob.size(), aIPCBlob.blobImplType()); + blobImpl->SetDOMPath(file.DOMPath()); + blobImpl->SetFullPath(file.fullPath()); + blobImpl->SetIsDirectory(file.isDirectory()); + } + + blobImpl->SetFileId(aIPCBlob.fileId()); + + return blobImpl.forget(); +} + +nsresult Serialize(BlobImpl* aBlobImpl, IPCBlob& aIPCBlob) { + MOZ_ASSERT(aBlobImpl); + + nsAutoString value; + aBlobImpl->GetType(value); + aIPCBlob.type() = value; + + aBlobImpl->GetBlobImplType(value); + aIPCBlob.blobImplType() = value; + + ErrorResult rv; + aIPCBlob.size() = aBlobImpl->GetSize(rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + + if (!aBlobImpl->IsFile()) { + aIPCBlob.file() = Nothing(); + } else { + IPCFile file; + + aBlobImpl->GetName(value); + file.name() = value; + + file.lastModified() = aBlobImpl->GetLastModified(rv) * PR_USEC_PER_MSEC; + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + + aBlobImpl->GetDOMPath(value); + file.DOMPath() = value; + + aBlobImpl->GetMozFullPathInternal(value, rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + file.fullPath() = value; + + file.isDirectory() = aBlobImpl->IsDirectory(); + + aIPCBlob.file() = Some(file); + } + + aIPCBlob.fileId() = aBlobImpl->GetFileId(); + + nsCOMPtr<nsIInputStream> inputStream; + aBlobImpl->CreateInputStream(getter_AddRefs(inputStream), rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + + if (XRE_IsParentProcess()) { + RefPtr<RemoteLazyInputStream> stream = + RemoteLazyInputStream::WrapStream(inputStream); + if (NS_WARN_IF(!stream)) { + return NS_ERROR_FAILURE; + } + + aIPCBlob.inputStream() = stream; + return NS_OK; + } + + mozilla::ipc::IPCStream stream; + if (!mozilla::ipc::SerializeIPCStream(inputStream.forget(), stream, + /* aAllowLazy */ true)) { + return NS_ERROR_FAILURE; + } + aIPCBlob.inputStream() = stream; + return NS_OK; +} + +} // namespace mozilla::dom::IPCBlobUtils + +namespace IPC { + +void ParamTraits<mozilla::dom::BlobImpl*>::Write( + IPC::MessageWriter* aWriter, mozilla::dom::BlobImpl* aParam) { + nsresult rv; + mozilla::dom::IPCBlob ipcblob; + if (aParam) { + rv = mozilla::dom::IPCBlobUtils::Serialize(aParam, ipcblob); + } + if (!aParam || NS_WARN_IF(NS_FAILED(rv))) { + WriteParam(aWriter, false); + } else { + WriteParam(aWriter, true); + WriteParam(aWriter, ipcblob); + } +} + +bool ParamTraits<mozilla::dom::BlobImpl*>::Read( + IPC::MessageReader* aReader, RefPtr<mozilla::dom::BlobImpl>* aResult) { + *aResult = nullptr; + + bool notnull = false; + if (!ReadParam(aReader, ¬null)) { + return false; + } + if (notnull) { + mozilla::dom::IPCBlob ipcblob; + if (!ReadParam(aReader, &ipcblob)) { + return false; + } + *aResult = mozilla::dom::IPCBlobUtils::Deserialize(ipcblob); + } + return true; +} + +} // namespace IPC |