Bug 1025824 - Fix mHwcLayerMap handling r=sushil
[gecko.git] / dom / base / nsStructuredCloneContainer.cpp
blob0aa29f88e76649b78a0db1c8d0067c7c35ede6c4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sw=2 et tw=80:
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "nsStructuredCloneContainer.h"
10 #include "nsCOMPtr.h"
11 #include "nsIScriptContext.h"
12 #include "nsIVariant.h"
13 #include "nsIXPConnect.h"
14 #include "nsServiceManagerUtils.h"
15 #include "nsContentUtils.h"
16 #include "jsapi.h"
17 #include "js/StructuredClone.h"
19 #include "mozilla/Base64.h"
21 using namespace mozilla;
23 NS_IMPL_ADDREF(nsStructuredCloneContainer)
24 NS_IMPL_RELEASE(nsStructuredCloneContainer)
26 NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
27 NS_INTERFACE_MAP_ENTRY(nsIStructuredCloneContainer)
28 NS_INTERFACE_MAP_ENTRY(nsISupports)
29 NS_INTERFACE_MAP_END
31 nsStructuredCloneContainer::nsStructuredCloneContainer()
32 : mData(nullptr), mSize(0), mVersion(0)
36 nsStructuredCloneContainer::~nsStructuredCloneContainer()
38 free(mData);
41 nsresult
42 nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
43 JSContext* aCx)
45 NS_ENSURE_STATE(!mData);
46 NS_ENSURE_ARG_POINTER(aCx);
48 // Make sure that we serialize in the right context.
49 MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
50 JS::Rooted<JS::Value> jsData(aCx, aData);
51 bool success = JS_WrapValue(aCx, &jsData);
52 NS_ENSURE_STATE(success);
54 uint64_t* jsBytes = nullptr;
55 success = JS_WriteStructuredClone(aCx, jsData, &jsBytes, &mSize,
56 nullptr, nullptr,
57 JS::UndefinedHandleValue);
58 NS_ENSURE_STATE(success);
59 NS_ENSURE_STATE(jsBytes);
61 // Copy jsBytes into our own buffer.
62 mData = (uint64_t*) malloc(mSize);
63 if (!mData) {
64 mSize = 0;
65 mVersion = 0;
67 JS_ClearStructuredClone(jsBytes, mSize, nullptr, nullptr);
68 return NS_ERROR_FAILURE;
70 else {
71 mVersion = JS_STRUCTURED_CLONE_VERSION;
74 memcpy(mData, jsBytes, mSize);
76 JS_ClearStructuredClone(jsBytes, mSize, nullptr, nullptr);
77 return NS_OK;
80 nsresult
81 nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
82 uint32_t aFormatVersion,
83 JSContext *aCx)
85 NS_ENSURE_STATE(!mData);
87 NS_ConvertUTF16toUTF8 data(aData);
89 nsAutoCString binaryData;
90 nsresult rv = Base64Decode(data, binaryData);
91 NS_ENSURE_SUCCESS(rv, rv);
93 // Copy the string's data into our own buffer.
94 mData = (uint64_t*) malloc(binaryData.Length());
95 NS_ENSURE_STATE(mData);
96 memcpy(mData, binaryData.get(), binaryData.Length());
98 mSize = binaryData.Length();
99 mVersion = aFormatVersion;
100 return NS_OK;
104 nsresult
105 nsStructuredCloneContainer::DeserializeToVariant(JSContext *aCx,
106 nsIVariant **aData)
108 NS_ENSURE_STATE(mData);
109 NS_ENSURE_ARG_POINTER(aData);
110 *aData = nullptr;
112 // Deserialize to a JS::Value.
113 JS::Rooted<JS::Value> jsStateObj(aCx);
114 bool hasTransferable = false;
115 bool success = JS_ReadStructuredClone(aCx, mData, mSize, mVersion,
116 &jsStateObj, nullptr, nullptr) &&
117 JS_StructuredCloneHasTransferables(mData, mSize,
118 &hasTransferable);
119 // We want to be sure that mData doesn't contain transferable objects
120 MOZ_ASSERT(!hasTransferable);
121 NS_ENSURE_STATE(success && !hasTransferable);
123 // Now wrap the JS::Value as an nsIVariant.
124 nsCOMPtr<nsIVariant> varStateObj;
125 nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
126 NS_ENSURE_STATE(xpconnect);
127 xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
128 NS_ENSURE_STATE(varStateObj);
130 NS_ADDREF(*aData = varStateObj);
131 return NS_OK;
134 nsresult
135 nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
137 NS_ENSURE_STATE(mData);
138 aOut.Truncate();
140 nsAutoCString binaryData(reinterpret_cast<char*>(mData), mSize);
141 nsAutoCString base64Data;
142 nsresult rv = Base64Encode(binaryData, base64Data);
143 NS_ENSURE_SUCCESS(rv, rv);
145 aOut.Assign(NS_ConvertASCIItoUTF16(base64Data));
146 return NS_OK;
149 nsresult
150 nsStructuredCloneContainer::GetSerializedNBytes(uint64_t *aSize)
152 NS_ENSURE_STATE(mData);
153 NS_ENSURE_ARG_POINTER(aSize);
155 // mSize is a size_t, while aSize is a uint64_t. We rely on an implicit cast
156 // here so that we'll get a compile error if a size_t-to-uint64_t cast is
157 // narrowing.
158 *aSize = mSize;
160 return NS_OK;
163 nsresult
164 nsStructuredCloneContainer::GetFormatVersion(uint32_t *aFormatVersion)
166 NS_ENSURE_STATE(mData);
167 NS_ENSURE_ARG_POINTER(aFormatVersion);
168 *aFormatVersion = mVersion;
169 return NS_OK;