bug 812562 - click-to-play: reshow notification for blocklisted plugins r=jaws
[gecko.git] / xpcom / ds / nsArray.cpp
blob376826ae3a46aafba7e50e8b64367d2004bcb389
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsArray.h"
7 #include "nsArrayEnumerator.h"
8 #include "nsWeakReference.h"
9 #include "nsThreadUtils.h"
11 // used by IndexOf()
12 struct findIndexOfClosure
14 nsISupports *targetElement;
15 uint32_t startIndex;
16 uint32_t resultIndex;
19 static bool FindElementCallback(void* aElement, void* aClosure);
21 NS_INTERFACE_MAP_BEGIN(nsArray)
22 NS_INTERFACE_MAP_ENTRY(nsIArray)
23 NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
24 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
25 NS_INTERFACE_MAP_END
27 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsArrayCC)
28 NS_INTERFACE_MAP_ENTRY(nsIArray)
29 NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
30 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
31 NS_INTERFACE_MAP_END
33 nsArray::~nsArray()
35 Clear();
39 NS_IMPL_ADDREF(nsArray)
40 NS_IMPL_RELEASE(nsArray)
42 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsArrayCC)
43 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsArrayCC)
45 NS_IMPL_CYCLE_COLLECTION_CLASS(nsArrayCC)
46 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsArrayCC)
47 tmp->Clear();
48 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
49 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsArrayCC)
50 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArray)
51 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
53 NS_IMETHODIMP
54 nsArray::GetLength(uint32_t* aLength)
56 *aLength = mArray.Count();
57 return NS_OK;
60 NS_IMETHODIMP
61 nsArray::QueryElementAt(uint32_t aIndex,
62 const nsIID& aIID,
63 void ** aResult)
65 nsISupports * obj = mArray.SafeObjectAt(aIndex);
66 if (!obj) return NS_ERROR_ILLEGAL_VALUE;
68 // no need to worry about a leak here, because SafeObjectAt()
69 // doesn't addref its result
70 return obj->QueryInterface(aIID, aResult);
73 NS_IMETHODIMP
74 nsArray::IndexOf(uint32_t aStartIndex, nsISupports* aElement,
75 uint32_t* aResult)
77 // optimize for the common case by forwarding to mArray
78 if (aStartIndex == 0) {
79 uint32_t idx = mArray.IndexOf(aElement);
80 if (idx == UINT32_MAX)
81 return NS_ERROR_FAILURE;
83 *aResult = idx;
84 return NS_OK;
87 findIndexOfClosure closure = { aElement, aStartIndex, 0 };
88 bool notFound = mArray.EnumerateForwards(FindElementCallback, &closure);
89 if (notFound)
90 return NS_ERROR_FAILURE;
92 *aResult = closure.resultIndex;
93 return NS_OK;
96 NS_IMETHODIMP
97 nsArray::Enumerate(nsISimpleEnumerator **aResult)
99 return NS_NewArrayEnumerator(aResult, static_cast<nsIArray*>(this));
102 // nsIMutableArray implementation
104 NS_IMETHODIMP
105 nsArray::AppendElement(nsISupports* aElement, bool aWeak)
107 bool result;
108 if (aWeak) {
109 nsCOMPtr<nsIWeakReference> elementRef = do_GetWeakReference(aElement);
110 NS_ASSERTION(elementRef, "AppendElement: Trying to use weak references on an object that doesn't support it");
111 if (!elementRef)
112 return NS_ERROR_FAILURE;
113 result = mArray.AppendObject(elementRef);
116 else {
117 // add the object directly
118 result = mArray.AppendObject(aElement);
120 return result ? NS_OK : NS_ERROR_FAILURE;
123 NS_IMETHODIMP
124 nsArray::RemoveElementAt(uint32_t aIndex)
126 bool result = mArray.RemoveObjectAt(aIndex);
127 return result ? NS_OK : NS_ERROR_FAILURE;
130 NS_IMETHODIMP
131 nsArray::InsertElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
133 nsCOMPtr<nsISupports> elementRef;
134 if (aWeak) {
135 elementRef = do_GetWeakReference(aElement);
136 NS_ASSERTION(elementRef, "InsertElementAt: Trying to use weak references on an object that doesn't support it");
137 if (!elementRef)
138 return NS_ERROR_FAILURE;
139 } else {
140 elementRef = aElement;
142 bool result = mArray.InsertObjectAt(elementRef, aIndex);
143 return result ? NS_OK : NS_ERROR_FAILURE;
146 NS_IMETHODIMP
147 nsArray::ReplaceElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
149 nsCOMPtr<nsISupports> elementRef;
150 if (aWeak) {
151 elementRef = do_GetWeakReference(aElement);
152 NS_ASSERTION(elementRef, "ReplaceElementAt: Trying to use weak references on an object that doesn't support it");
153 if (!elementRef)
154 return NS_ERROR_FAILURE;
155 } else {
156 elementRef = aElement;
158 bool result = mArray.ReplaceObjectAt(elementRef, aIndex);
159 return result ? NS_OK : NS_ERROR_FAILURE;
162 NS_IMETHODIMP
163 nsArray::Clear()
165 mArray.Clear();
166 return NS_OK;
170 // static helper routines
172 bool
173 FindElementCallback(void *aElement, void* aClosure)
175 findIndexOfClosure* closure =
176 static_cast<findIndexOfClosure*>(aClosure);
178 nsISupports* element =
179 static_cast<nsISupports*>(aElement);
181 // don't start searching until we're past the startIndex
182 if (closure->resultIndex >= closure->startIndex &&
183 element == closure->targetElement) {
184 return false; // stop! We found it
186 closure->resultIndex++;
188 return true;
191 nsresult
192 nsArray::XPCOMConstructor(nsISupports *aOuter, const nsIID& aIID, void **aResult)
194 if (aOuter)
195 return NS_ERROR_NO_AGGREGATION;
197 nsCOMPtr<nsIMutableArray> inst = Create();
198 return inst->QueryInterface(aIID, aResult);
201 already_AddRefed<nsIMutableArray>
202 nsArray::Create()
204 nsCOMPtr<nsIMutableArray> inst = NS_IsMainThread() ? new nsArrayCC : new nsArray;
205 return inst.forget();