diff --git a/dom/bluetooth/BluetoothAdapter.cpp b/dom/bluetooth/BluetoothAdapter.cpp index 81ef7b7d018..c5a7d12a0f1 100644 --- a/dom/bluetooth/BluetoothAdapter.cpp +++ b/dom/bluetooth/BluetoothAdapter.cpp @@ -20,6 +20,7 @@ #include "nsIDOMBluetoothDeviceAddressEvent.h" #include "nsIDOMBluetoothDeviceEvent.h" #include "nsIDOMDOMRequest.h" +#include "nsTArrayHelpers.h" #include "nsThreadUtils.h" #include "nsXPCOMCIDInternal.h" @@ -102,8 +103,7 @@ public: return false; } - rv = BluetoothDeviceArrayToJSArray(sc->GetNativeContext(), - sc->GetNativeGlobal(), devices, &JsDevices); + rv = nsTArrayToJSArray(sc->GetNativeContext(), devices, &JsDevices); if (JsDevices) { aValue->setObject(*JsDevices); @@ -211,8 +211,7 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue) nsIScriptContext* sc = GetContextForEventHandlers(&rv); if (sc) { rv = - StringArrayToJSArray(sc->GetNativeContext(), - sc->GetNativeGlobal(), mUuids, &mJsUuids); + nsTArrayToJSArray(sc->GetNativeContext(), mUuids, &mJsUuids); if (NS_FAILED(rv)) { NS_WARNING("Cannot set JS UUIDs object!"); return; @@ -227,8 +226,8 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue) nsIScriptContext* sc = GetContextForEventHandlers(&rv); if (sc) { rv = - StringArrayToJSArray(sc->GetNativeContext(), - sc->GetNativeGlobal(), mDeviceAddresses, &mJsDeviceAddresses); + nsTArrayToJSArray(sc->GetNativeContext(), mDeviceAddresses, + &mJsDeviceAddresses); if (NS_FAILED(rv)) { NS_WARNING("Cannot set JS Device Addresses object!"); return; diff --git a/dom/bluetooth/BluetoothDevice.cpp b/dom/bluetooth/BluetoothDevice.cpp index 4c3b68642f9..da6d1196a42 100644 --- a/dom/bluetooth/BluetoothDevice.cpp +++ b/dom/bluetooth/BluetoothDevice.cpp @@ -15,6 +15,7 @@ #include "nsIDOMDOMRequest.h" #include "nsDOMClassInfo.h" #include "nsContentUtils.h" +#include "nsTArrayHelpers.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" USING_BLUETOOTH_NAMESPACE @@ -118,8 +119,7 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue) nsIScriptContext* sc = GetContextForEventHandlers(&rv); if (sc) { rv = - StringArrayToJSArray(sc->GetNativeContext(), - sc->GetNativeGlobal(), mUuids, &mJsUuids); + nsTArrayToJSArray(sc->GetNativeContext(), mUuids, &mJsUuids); if (NS_FAILED(rv)) { NS_WARNING("Cannot set JS UUIDs object!"); return; @@ -134,8 +134,7 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue) nsIScriptContext* sc = GetContextForEventHandlers(&rv); if (sc) { rv = - StringArrayToJSArray(sc->GetNativeContext(), - sc->GetNativeGlobal(), mServices, &mJsServices); + nsTArrayToJSArray(sc->GetNativeContext(), mServices, &mJsServices); if (NS_FAILED(rv)) { NS_WARNING("Cannot set JS Services object!"); return; diff --git a/dom/bluetooth/BluetoothUtils.cpp b/dom/bluetooth/BluetoothUtils.cpp index efd968e04ae..0b3adc949b2 100644 --- a/dom/bluetooth/BluetoothUtils.cpp +++ b/dom/bluetooth/BluetoothUtils.cpp @@ -18,93 +18,6 @@ USING_BLUETOOTH_NAMESPACE -nsresult -mozilla::dom::bluetooth::StringArrayToJSArray(JSContext* aCx, JSObject* aGlobal, - const nsTArray& aSourceArray, - JSObject** aResultArray) -{ - NS_ASSERTION(aCx, "Null context!"); - NS_ASSERTION(aGlobal, "Null global!"); - - JSAutoRequest ar(aCx); - JSAutoCompartment ac(aCx, aGlobal); - - JSObject* arrayObj; - - if (aSourceArray.IsEmpty()) { - arrayObj = JS_NewArrayObject(aCx, 0, nullptr); - } else { - uint32_t valLength = aSourceArray.Length(); - mozilla::ScopedDeleteArray valArray(new jsval[valLength]); - JS::AutoArrayRooter tvr(aCx, 0, valArray); - for (uint32_t index = 0; index < valLength; index++) { - JSString* s = JS_NewUCStringCopyN(aCx, aSourceArray[index].BeginReading(), - aSourceArray[index].Length()); - if(!s) { - NS_WARNING("Memory allocation error!"); - return NS_ERROR_OUT_OF_MEMORY; - } - valArray[index] = STRING_TO_JSVAL(s); - tvr.changeLength(index + 1); - } - arrayObj = JS_NewArrayObject(aCx, valLength, valArray); - } - - if (!arrayObj) { - return NS_ERROR_OUT_OF_MEMORY; - } - - // XXX This is not what Jonas wants. He wants it to be live. - // Followup at bug 717414 - if (!JS_FreezeObject(aCx, arrayObj)) { - return NS_ERROR_FAILURE; - } - - *aResultArray = arrayObj; - return NS_OK; -} - -nsresult -mozilla::dom::bluetooth::BluetoothDeviceArrayToJSArray(JSContext* aCx, JSObject* aGlobal, - const nsTArray >& aSourceArray, - JSObject** aResultArray) -{ - NS_ASSERTION(aCx, "Null context!"); - NS_ASSERTION(aGlobal, "Null global!"); - - JSAutoRequest ar(aCx); - JSAutoCompartment ac(aCx, aGlobal); - - JSObject* arrayObj; - - if (aSourceArray.IsEmpty()) { - arrayObj = JS_NewArrayObject(aCx, 0, nullptr); - } else { - uint32_t valLength = aSourceArray.Length(); - mozilla::ScopedDeleteArray valArray(new jsval[valLength]); - JS::AutoArrayRooter tvr(aCx, 0, valArray); - for (uint32_t index = 0; index < valLength; index++) { - nsISupports* obj = aSourceArray[index]->ToISupports(); - nsresult rv = - nsContentUtils::WrapNative(aCx, aGlobal, obj, &valArray[index]); - NS_ENSURE_SUCCESS(rv, rv); - tvr.changeLength(index + 1); - } - arrayObj = JS_NewArrayObject(aCx, valLength, valArray); - } - - if (!arrayObj) { - return NS_ERROR_OUT_OF_MEMORY; - } - - if (!JS_FreezeObject(aCx, arrayObj)) { - return NS_ERROR_FAILURE; - } - - *aResultArray = arrayObj; - return NS_OK; -} - bool mozilla::dom::bluetooth::SetJsObject(JSContext* aContext, JSObject* aObj, diff --git a/dom/bluetooth/BluetoothUtils.h b/dom/bluetooth/BluetoothUtils.h index e7f18aa60ba..fba06581316 100644 --- a/dom/bluetooth/BluetoothUtils.h +++ b/dom/bluetooth/BluetoothUtils.h @@ -17,16 +17,6 @@ BEGIN_BLUETOOTH_NAMESPACE class BluetoothDevice; class BluetoothNamedValue; -nsresult -StringArrayToJSArray(JSContext* aCx, JSObject* aGlobal, - const nsTArray& aSourceArray, - JSObject** aResultArray); - -nsresult -BluetoothDeviceArrayToJSArray(JSContext* aCx, JSObject* aGlobal, - const nsTArray >& aSourceArray, - JSObject** aResultArray); - bool SetJsObject(JSContext* aContext, JSObject* aObj, diff --git a/js/xpconnect/public/nsTArrayHelpers.h b/js/xpconnect/public/nsTArrayHelpers.h index 7b961083e23..221d9d917b1 100644 --- a/js/xpconnect/public/nsTArrayHelpers.h +++ b/js/xpconnect/public/nsTArrayHelpers.h @@ -46,4 +46,48 @@ nsTArrayToJSArray(JSContext* aCx, const nsTArray& aSourceArray, return NS_OK; } +template <> +inline nsresult +nsTArrayToJSArray(JSContext* aCx, + const nsTArray& aSourceArray, + JSObject** aResultArray) +{ + MOZ_ASSERT(aCx); + JSAutoRequest ar(aCx); + + JSObject* arrayObj = JS_NewArrayObject(aCx, aSourceArray.Length(), nullptr); + if (!arrayObj) { + NS_WARNING("JS_NewArrayObject failed!"); + return NS_ERROR_OUT_OF_MEMORY; + } + + JSObject* global = JS_GetGlobalForScopeChain(aCx); + MOZ_ASSERT(global); + + for (uint32_t index = 0; index < aSourceArray.Length(); index++) { + JSString* s = JS_NewUCStringCopyN(aCx, aSourceArray[index].BeginReading(), + aSourceArray[index].Length()); + + if(!s) { + NS_WARNING("Memory allocation error!"); + return NS_ERROR_OUT_OF_MEMORY; + } + + jsval wrappedVal = STRING_TO_JSVAL(s); + + if (!JS_SetElement(aCx, arrayObj, index, &wrappedVal)) { + NS_WARNING("JS_SetElement failed!"); + return NS_ERROR_FAILURE; + } + } + + if (!JS_FreezeObject(aCx, arrayObj)) { + NS_WARNING("JS_FreezeObject failed!"); + return NS_ERROR_FAILURE; + } + + *aResultArray = arrayObj; + return NS_OK; +} + #endif /* __NSTARRAYHELPERS_H__ */