Bumping manifests a=b2g-bump
[gecko.git] / xpcom / ds / nsArray.cpp
blob2a94aab48ff93f7f2fe143a0585b3409f04fff98
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 "nsIWeakReference.h"
9 #include "nsIWeakReferenceUtils.h"
10 #include "nsThreadUtils.h"
12 // used by IndexOf()
13 struct findIndexOfClosure
15 nsISupports* targetElement;
16 uint32_t startIndex;
17 uint32_t resultIndex;
20 static bool FindElementCallback(void* aElement, void* aClosure);
22 NS_INTERFACE_MAP_BEGIN(nsArray)
23 NS_INTERFACE_MAP_ENTRY(nsIArray)
24 NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
25 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
26 NS_INTERFACE_MAP_END
28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsArrayCC)
29 NS_INTERFACE_MAP_ENTRY(nsIArray)
30 NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
31 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
32 NS_INTERFACE_MAP_END
34 nsArrayBase::~nsArrayBase()
36 Clear();
40 NS_IMPL_ADDREF(nsArray)
41 NS_IMPL_RELEASE(nsArray)
43 NS_IMPL_CYCLE_COLLECTION_CLASS(nsArrayCC)
45 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsArrayCC)
46 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsArrayCC)
48 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsArrayCC)
49 tmp->Clear();
50 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
51 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsArrayCC)
52 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArray)
53 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
55 NS_IMETHODIMP
56 nsArrayBase::GetLength(uint32_t* aLength)
58 *aLength = mArray.Count();
59 return NS_OK;
62 NS_IMETHODIMP
63 nsArrayBase::QueryElementAt(uint32_t aIndex,
64 const nsIID& aIID,
65 void** aResult)
67 nsISupports* obj = mArray.SafeObjectAt(aIndex);
68 if (!obj) {
69 return NS_ERROR_ILLEGAL_VALUE;
72 // no need to worry about a leak here, because SafeObjectAt()
73 // doesn't addref its result
74 return obj->QueryInterface(aIID, aResult);
77 NS_IMETHODIMP
78 nsArrayBase::IndexOf(uint32_t aStartIndex, nsISupports* aElement,
79 uint32_t* aResult)
81 // optimize for the common case by forwarding to mArray
82 if (aStartIndex == 0) {
83 uint32_t idx = mArray.IndexOf(aElement);
84 if (idx == UINT32_MAX) {
85 return NS_ERROR_FAILURE;
88 *aResult = idx;
89 return NS_OK;
92 findIndexOfClosure closure = { aElement, aStartIndex, 0 };
93 bool notFound = mArray.EnumerateForwards(FindElementCallback, &closure);
94 if (notFound) {
95 return NS_ERROR_FAILURE;
98 *aResult = closure.resultIndex;
99 return NS_OK;
102 NS_IMETHODIMP
103 nsArrayBase::Enumerate(nsISimpleEnumerator** aResult)
105 return NS_NewArrayEnumerator(aResult, static_cast<nsIArray*>(this));
108 // nsIMutableArray implementation
110 NS_IMETHODIMP
111 nsArrayBase::AppendElement(nsISupports* aElement, bool aWeak)
113 bool result;
114 if (aWeak) {
115 nsCOMPtr<nsIWeakReference> elementRef = do_GetWeakReference(aElement);
116 NS_ASSERTION(elementRef,
117 "AppendElement: Trying to use weak references on an object that doesn't support it");
118 if (!elementRef) {
119 return NS_ERROR_FAILURE;
121 result = mArray.AppendObject(elementRef);
124 else {
125 // add the object directly
126 result = mArray.AppendObject(aElement);
128 return result ? NS_OK : NS_ERROR_FAILURE;
131 NS_IMETHODIMP
132 nsArrayBase::RemoveElementAt(uint32_t aIndex)
134 bool result = mArray.RemoveObjectAt(aIndex);
135 return result ? NS_OK : NS_ERROR_FAILURE;
138 NS_IMETHODIMP
139 nsArrayBase::InsertElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
141 nsCOMPtr<nsISupports> elementRef;
142 if (aWeak) {
143 elementRef = do_GetWeakReference(aElement);
144 NS_ASSERTION(elementRef,
145 "InsertElementAt: Trying to use weak references on an object that doesn't support it");
146 if (!elementRef) {
147 return NS_ERROR_FAILURE;
149 } else {
150 elementRef = aElement;
152 bool result = mArray.InsertObjectAt(elementRef, aIndex);
153 return result ? NS_OK : NS_ERROR_FAILURE;
156 NS_IMETHODIMP
157 nsArrayBase::ReplaceElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
159 nsCOMPtr<nsISupports> elementRef;
160 if (aWeak) {
161 elementRef = do_GetWeakReference(aElement);
162 NS_ASSERTION(elementRef,
163 "ReplaceElementAt: Trying to use weak references on an object that doesn't support it");
164 if (!elementRef) {
165 return NS_ERROR_FAILURE;
167 } else {
168 elementRef = aElement;
170 bool result = mArray.ReplaceObjectAt(elementRef, aIndex);
171 return result ? NS_OK : NS_ERROR_FAILURE;
174 NS_IMETHODIMP
175 nsArrayBase::Clear()
177 mArray.Clear();
178 return NS_OK;
182 // static helper routines
184 bool
185 FindElementCallback(void* aElement, void* aClosure)
187 findIndexOfClosure* closure = static_cast<findIndexOfClosure*>(aClosure);
188 nsISupports* element = static_cast<nsISupports*>(aElement);
190 // don't start searching until we're past the startIndex
191 if (closure->resultIndex >= closure->startIndex &&
192 element == closure->targetElement) {
193 return false; // stop! We found it
195 closure->resultIndex++;
197 return true;
200 nsresult
201 nsArrayBase::XPCOMConstructor(nsISupports* aOuter, const nsIID& aIID,
202 void** aResult)
204 if (aOuter) {
205 return NS_ERROR_NO_AGGREGATION;
208 nsCOMPtr<nsIMutableArray> inst = Create();
209 return inst->QueryInterface(aIID, aResult);
212 already_AddRefed<nsIMutableArray>
213 nsArrayBase::Create()
215 nsCOMPtr<nsIMutableArray> inst;
216 if (NS_IsMainThread()) {
217 inst = new nsArrayCC;
218 } else {
219 inst = new nsArray;
221 return inst.forget();