XPCWrappedJSIterator.cpp (2719B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "xpcprivate.h" 8 9 #include "mozilla/Try.h" 10 #include "mozilla/dom/IteratorResultBinding.h" 11 #include "mozilla/dom/RootedDictionary.h" 12 #include "mozilla/dom/ScriptSettings.h" 13 14 using namespace mozilla; 15 using namespace mozilla::dom; 16 using namespace xpc; 17 18 NS_IMPL_CYCLE_COLLECTION(XPCWrappedJSIterator, mEnum, mGlobal, mNext) 19 20 NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCWrappedJSIterator) 21 NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCWrappedJSIterator) 22 23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCWrappedJSIterator) 24 NS_INTERFACE_MAP_ENTRY(nsISimpleEnumerator) 25 NS_INTERFACE_MAP_ENTRY(nsISimpleEnumeratorBase) 26 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, XPCWrappedJSIterator) 27 NS_INTERFACE_MAP_END 28 29 XPCWrappedJSIterator::XPCWrappedJSIterator(nsIJSEnumerator* aEnum) 30 : mEnum(aEnum) { 31 nsCOMPtr<nsIXPConnectWrappedJS> wrapped = do_QueryInterface(aEnum); 32 MOZ_ASSERT(wrapped); 33 mGlobal = NativeGlobal(wrapped->GetJSObjectGlobal()); 34 } 35 36 nsresult XPCWrappedJSIterator::HasMoreElements(bool* aRetVal) { 37 if (mHasNext.isNothing()) { 38 AutoJSAPI jsapi; 39 MOZ_ALWAYS_TRUE(jsapi.Init(mGlobal)); 40 41 JSContext* cx = jsapi.cx(); 42 43 JS::RootedValue val(cx); 44 MOZ_TRY(mEnum->Next(cx, &val)); 45 46 RootedDictionary<IteratorResult> result(cx); 47 if (!result.Init(cx, val)) { 48 return NS_ERROR_FAILURE; 49 } 50 51 if (!result.mDone) { 52 if (result.mValue.isObject()) { 53 JS::RootedObject obj(cx, &result.mValue.toObject()); 54 55 nsresult rv; 56 if (!XPCConvert::JSObject2NativeInterface(cx, getter_AddRefs(mNext), 57 obj, &NS_GET_IID(nsISupports), 58 nullptr, &rv)) { 59 return rv; 60 } 61 } else { 62 mNext = XPCVariant::newVariant(cx, result.mValue); 63 } 64 } 65 mHasNext = Some(!result.mDone); 66 } 67 *aRetVal = *mHasNext; 68 return NS_OK; 69 } 70 71 nsresult XPCWrappedJSIterator::GetNext(nsISupports** aRetVal) { 72 bool hasMore; 73 MOZ_TRY(HasMoreElements(&hasMore)); 74 if (!hasMore) { 75 return NS_ERROR_FAILURE; 76 } 77 78 mNext.forget(aRetVal); 79 mHasNext = Nothing(); 80 return NS_OK; 81 } 82 83 nsresult XPCWrappedJSIterator::Iterator(nsIJSEnumerator** aRetVal) { 84 nsCOMPtr<nsIJSEnumerator> jsEnum = mEnum; 85 jsEnum.forget(aRetVal); 86 return NS_OK; 87 } 88 89 nsresult XPCWrappedJSIterator::Entries(const nsID&, nsIJSEnumerator** aRetVal) { 90 return NS_ERROR_NOT_IMPLEMENTED; 91 }