mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-04 16:15:25 +00:00
506dfe6ea3
In JS StructuredClone BufferList<SystemAllocPolicy> is typedef'd to JSStructuredCloneData and use everywhere in gecko that stores structured clone data. This patch changed some raw pointers to UniquePtr<JSStructuredCloneData> and some to stack allocated JSStructuredCloneData for better life time management. Some parameters or methods are deleted because of changing to the new data structure. MessagePortMessage now has the exactly same structure with ClonedMessageData. Maybe in the future they can be consolidated. MozReview-Commit-ID: 1IY9p5eKLgv
180 lines
4.1 KiB
C++
180 lines
4.1 KiB
C++
/* -*- 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 "nsStructuredCloneContainer.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIGlobalObject.h"
|
|
#include "nsIVariant.h"
|
|
#include "nsIXPConnect.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
#include "nsContentUtils.h"
|
|
#include "jsapi.h"
|
|
#include "xpcpublic.h"
|
|
|
|
#include "mozilla/Base64.h"
|
|
#include "mozilla/dom/ScriptSettings.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
NS_IMPL_ADDREF(nsStructuredCloneContainer)
|
|
NS_IMPL_RELEASE(nsStructuredCloneContainer)
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
|
|
NS_INTERFACE_MAP_ENTRY(nsIStructuredCloneContainer)
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
nsStructuredCloneContainer::nsStructuredCloneContainer()
|
|
: mVersion(0)
|
|
{
|
|
}
|
|
|
|
nsStructuredCloneContainer::~nsStructuredCloneContainer()
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
|
|
JSContext* aCx)
|
|
{
|
|
if (DataLength()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
ErrorResult rv;
|
|
Write(aCx, aData, rv);
|
|
if (NS_WARN_IF(rv.Failed())) {
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
mVersion = JS_STRUCTURED_CLONE_VERSION;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
|
|
uint32_t aFormatVersion)
|
|
{
|
|
if (DataLength()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_ConvertUTF16toUTF8 data(aData);
|
|
|
|
nsAutoCString binaryData;
|
|
nsresult rv = Base64Decode(data, binaryData);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!CopyExternalData(binaryData.get(), binaryData.Length())) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
mVersion = aFormatVersion;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsStructuredCloneContainer::DeserializeToJsval(JSContext* aCx,
|
|
JS::MutableHandle<JS::Value> aValue)
|
|
{
|
|
aValue.setNull();
|
|
JS::Rooted<JS::Value> jsStateObj(aCx);
|
|
|
|
ErrorResult rv;
|
|
Read(aCx, &jsStateObj, rv);
|
|
if (NS_WARN_IF(rv.Failed())) {
|
|
return rv.StealNSResult();
|
|
}
|
|
|
|
aValue.set(jsStateObj);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsStructuredCloneContainer::DeserializeToVariant(JSContext* aCx,
|
|
nsIVariant** aData)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aData);
|
|
*aData = nullptr;
|
|
|
|
if (!DataLength()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Deserialize to a JS::Value.
|
|
JS::Rooted<JS::Value> jsStateObj(aCx);
|
|
nsresult rv = DeserializeToJsval(aCx, &jsStateObj);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
// Now wrap the JS::Value as an nsIVariant.
|
|
nsCOMPtr<nsIVariant> varStateObj;
|
|
nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
|
|
NS_ENSURE_STATE(xpconnect);
|
|
xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
|
|
NS_ENSURE_STATE(varStateObj);
|
|
|
|
varStateObj.forget(aData);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
|
|
{
|
|
aOut.Truncate();
|
|
|
|
if (!DataLength()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (HasClonedDOMObjects()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
auto iter = Data().Iter();
|
|
size_t size = Data().Size();
|
|
nsAutoCString binaryData;
|
|
binaryData.SetLength(size);
|
|
Data().ReadBytes(iter, binaryData.BeginWriting(), size);
|
|
nsAutoCString base64Data;
|
|
nsresult rv = Base64Encode(binaryData, base64Data);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
CopyASCIItoUTF16(base64Data, aOut);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsStructuredCloneContainer::GetSerializedNBytes(uint64_t* aSize)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aSize);
|
|
|
|
if (!DataLength()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
*aSize = DataLength();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsStructuredCloneContainer::GetFormatVersion(uint32_t* aFormatVersion)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aFormatVersion);
|
|
|
|
if (!DataLength()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
*aFormatVersion = mVersion;
|
|
return NS_OK;
|
|
}
|