/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */ #ifndef mozilla_dom_ipc_StructuredCloneData_h #define mozilla_dom_ipc_StructuredCloneData_h #include #include "mozilla/RefPtr.h" #include "mozilla/dom/StructuredCloneHolder.h" #include "nsISupportsImpl.h" namespace IPC { class Message; } class PickleIterator; namespace mozilla { namespace dom { namespace ipc { class SharedJSAllocatedData final { public: explicit SharedJSAllocatedData(JSStructuredCloneData&& aData) : mData(Move(aData)) { } static already_AddRefed CreateFromExternalData(const char* aData, size_t aDataLength) { JSStructuredCloneData buf(JS::StructuredCloneScope::DifferentProcess); buf.AppendBytes(aData, aDataLength); RefPtr sharedData = new SharedJSAllocatedData(Move(buf)); return sharedData.forget(); } static already_AddRefed CreateFromExternalData(const JSStructuredCloneData& aData) { JSStructuredCloneData buf(aData.scope()); buf.Append(aData); RefPtr sharedData = new SharedJSAllocatedData(Move(buf)); return sharedData.forget(); } NS_INLINE_DECL_REFCOUNTING(SharedJSAllocatedData) JSStructuredCloneData& Data() { return mData; } size_t DataLength() const { return mData.Size(); } private: ~SharedJSAllocatedData() { } JSStructuredCloneData mData; }; class StructuredCloneData : public StructuredCloneHolder { public: StructuredCloneData() : StructuredCloneHolder(StructuredCloneHolder::CloningSupported, StructuredCloneHolder::TransferringSupported, StructuredCloneHolder::StructuredCloneScope::DifferentProcess) , mExternalData(StructuredCloneHolder::StructuredCloneScope::DifferentProcess) , mInitialized(false) {} StructuredCloneData(const StructuredCloneData&) = delete; StructuredCloneData(StructuredCloneData&& aOther) = default; ~StructuredCloneData() {} StructuredCloneData& operator=(const StructuredCloneData& aOther) = delete; StructuredCloneData& operator=(StructuredCloneData&& aOther) = default; const nsTArray>& BlobImpls() const { return mBlobImplArray; } nsTArray>& BlobImpls() { return mBlobImplArray; } bool Copy(const StructuredCloneData& aData); void Read(JSContext* aCx, JS::MutableHandle aValue, ErrorResult &aRv); void Write(JSContext* aCx, JS::Handle aValue, ErrorResult &aRv); void Write(JSContext* aCx, JS::Handle aValue, JS::Handle aTransfers, ErrorResult &aRv); bool UseExternalData(const JSStructuredCloneData& aData) { auto iter = aData.Start(); bool success = false; mExternalData = aData.Borrow(iter, aData.Size(), &success); mInitialized = true; return success; } bool CopyExternalData(const char* aData, size_t aDataLength); JSStructuredCloneData& Data() { return mSharedData ? mSharedData->Data() : mExternalData; } const JSStructuredCloneData& Data() const { return mSharedData ? mSharedData->Data() : mExternalData; } void InitScope(JS::StructuredCloneScope aScope) { Data().initScope(aScope); } size_t DataLength() const { return mSharedData ? mSharedData->DataLength() : mExternalData.Size(); } SharedJSAllocatedData* SharedData() const { return mSharedData; } // For IPC serialization void WriteIPCParams(IPC::Message* aMessage) const; bool ReadIPCParams(const IPC::Message* aMessage, PickleIterator* aIter); private: JSStructuredCloneData mExternalData; RefPtr mSharedData; bool mInitialized; }; } // namespace ipc } // namespace dom } // namespace mozilla #endif // mozilla_dom_ipc_StructuredCloneData_h