/* -*- 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 "StructuredCloneData.h" #include "nsIDOMDOMException.h" #include "nsIMutable.h" #include "nsIXPConnect.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BlobBinding.h" #include "mozilla/dom/File.h" #include "mozilla/dom/ToJSValue.h" #include "nsContentUtils.h" #include "nsJSEnvironment.h" #include "MainThreadUtils.h" #include "StructuredCloneTags.h" #include "jsapi.h" namespace mozilla { namespace dom { namespace ipc { bool StructuredCloneData::Copy(const StructuredCloneData& aData) { if (!aData.mData) { return true; } uint64_t* data = static_cast(js_malloc(aData.mDataLength)); if (!data) { return false; } memcpy(data, aData.mData, aData.mDataLength); mData = data; mDataLength = aData.mDataLength; mDataOwned = eJSAllocated; MOZ_ASSERT(BlobImpls().IsEmpty()); BlobImpls().AppendElements(aData.BlobImpls()); MOZ_ASSERT(GetImages().IsEmpty()); return true; } void StructuredCloneData::Read(JSContext* aCx, JS::MutableHandle aValue, ErrorResult &aRv) { MOZ_ASSERT(mData); nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx)); MOZ_ASSERT(global); ReadFromBuffer(global, aCx, mData, mDataLength, aValue, aRv); } void StructuredCloneData::Write(JSContext* aCx, JS::Handle aValue, ErrorResult &aRv) { MOZ_ASSERT(!mData); StructuredCloneHolder::Write(aCx, aValue, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } mBuffer->steal(&mData, &mDataLength); mBuffer = nullptr; mDataOwned = eJSAllocated; } void StructuredCloneData::WriteIPCParams(Message* aMsg) const { WriteParam(aMsg, mDataLength); if (mDataLength) { // Structured clone data must be 64-bit aligned. aMsg->WriteBytes(mData, mDataLength, sizeof(uint64_t)); } } bool StructuredCloneData::ReadIPCParams(const IPC::Message* aMsg, void** aIter) { MOZ_ASSERT(!mData); if (!ReadParam(aMsg, aIter, &mDataLength)) { return false; } if (!mDataLength) { return true; } const char** buffer = const_cast(reinterpret_cast(&mData)); // Structured clone data must be 64-bit aligned. if (!aMsg->ReadBytes(aIter, buffer, mDataLength, sizeof(uint64_t))) { return false; } uint64_t* data = static_cast(js_malloc(mDataLength)); if (!data) { return false; } memcpy(data, mData, mDataLength); mData = data; mDataOwned = eJSAllocated; return true; } bool StructuredCloneData::CopyExternalData(const void* aData, size_t aDataLength) { MOZ_ASSERT(!mData); uint64_t* data = static_cast(js_malloc(aDataLength)); if (!data) { return false; } memcpy(data, aData, aDataLength); mData = data; mDataLength = aDataLength; mDataOwned = eJSAllocated; return true; } } // namespace ipc } // namespace dom } // namespace mozilla