sbArray.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is XPCOM Array implementation.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corp.
19  * Portions created by the Initial Developer are Copyright (C) 2002
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  * Alec Flett <alecf@netscape.com>
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * ***** END LICENSE BLOCK ***** */
38 
39 #include "nsAutoLock.h"
40 #include "sbArray.h"
41 #include "nsArrayEnumerator.h"
42 #include "nsWeakReference.h"
43 
44 // used by IndexOf()
46 {
48  PRUint32 startIndex;
49  PRUint32 resultIndex;
50 };
51 
52 PR_STATIC_CALLBACK(PRBool) FindElementCallback(void* aElement, void* aClosure);
53 
54 NS_INTERFACE_MAP_BEGIN(sbArray)
55  NS_INTERFACE_MAP_ENTRY(nsIArray)
56  NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
57  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
58 NS_INTERFACE_MAP_END
59 
61 {
62  mLock = nsAutoLock::NewLock("nsThreadsafeArray::mLock");
63  NS_ASSERTION(mLock, "Failed to create lock");
64 }
66  : mArray(aBaseArray)
67 {
68  mLock = nsAutoLock::NewLock("nsThreadsafeArray::mLock");
69  NS_ASSERTION(mLock, "Failed to create lock");
70 }
71 
72 sbArray::~sbArray()
73 {
74  Clear();
75  if (mLock) {
76  nsAutoLock::DestroyLock(mLock);
77  }
78 }
79 
82 
83 NS_IMETHODIMP
84 sbArray::GetLength(PRUint32* aLength)
85 {
86  nsAutoLock lock(mLock);
87  *aLength = mArray.Count();
88  return NS_OK;
89 }
90 
91 NS_IMETHODIMP
92 sbArray::QueryElementAt(PRUint32 aIndex,
93  const nsIID& aIID,
94  void ** aResult)
95 {
96  nsAutoLock lock(mLock);
97  nsISupports * obj = mArray.SafeObjectAt(aIndex);
98  if (!obj) return NS_ERROR_ILLEGAL_VALUE;
99 
100  // no need to worry about a leak here, because SafeObjectAt()
101  // doesn't addref its result
102  return obj->QueryInterface(aIID, aResult);
103 }
104 
105 NS_IMETHODIMP
106 sbArray::IndexOf(PRUint32 aStartIndex, nsISupports* aElement,
107  PRUint32* aResult)
108 {
109  nsAutoLock lock(mLock);
110 
111  // optimize for the common case by forwarding to mArray
112  if (aStartIndex == 0) {
113  *aResult = mArray.IndexOf(aElement);
114  if (*aResult == PR_UINT32_MAX)
115  return NS_ERROR_FAILURE;
116  return NS_OK;
117  }
118 
119  findIndexOfClosure closure = { aElement, aStartIndex, 0 };
120  PRBool notFound = mArray.EnumerateForwards(FindElementCallback, &closure);
121  if (notFound)
122  return NS_ERROR_FAILURE;
123 
124  *aResult = closure.resultIndex;
125  return NS_OK;
126 }
127 
128 NS_IMETHODIMP
129 sbArray::Enumerate(nsISimpleEnumerator **aResult)
130 {
131  return NS_NewArrayEnumerator(aResult, static_cast<nsIArray*>(this));
132 }
133 
134 // nsIMutableArray implementation
135 
136 NS_IMETHODIMP
137 sbArray::AppendElement(nsISupports* aElement, PRBool aWeak)
138 {
139  PRBool result;
140  if (aWeak) {
141  nsCOMPtr<nsISupports> elementRef =
142  getter_AddRefs(static_cast<nsISupports*>
143  (NS_GetWeakReference(aElement)));
144  NS_ASSERTION(elementRef, "AppendElement: Trying to use weak references on an object that doesn't support it");
145  if (!elementRef)
146  return NS_ERROR_FAILURE;
147  { /* scope */
148  nsAutoLock lock(mLock);
149  result = mArray.AppendObject(elementRef);
150  }
151  }
152 
153  else {
154  // add the object directly
155  nsAutoLock lock(mLock);
156  result = mArray.AppendObject(aElement);
157  }
158  return result ? NS_OK : NS_ERROR_FAILURE;
159 }
160 
161 NS_IMETHODIMP
162 sbArray::RemoveElementAt(PRUint32 aIndex)
163 {
164  nsAutoLock lock(mLock);
165  PRBool result = mArray.RemoveObjectAt(aIndex);
166  return result ? NS_OK : NS_ERROR_FAILURE;
167 }
168 
169 NS_IMETHODIMP
170 sbArray::InsertElementAt(nsISupports* aElement, PRUint32 aIndex, PRBool aWeak)
171 {
172  nsCOMPtr<nsISupports> elementRef;
173  if (aWeak) {
174  elementRef =
175  getter_AddRefs(static_cast<nsISupports*>
176  (NS_GetWeakReference(aElement)));
177  NS_ASSERTION(elementRef, "InsertElementAt: Trying to use weak references on an object that doesn't support it");
178  if (!elementRef)
179  return NS_ERROR_FAILURE;
180  } else {
181  elementRef = aElement;
182  }
183  { /* scope */
184  nsAutoLock lock(mLock);
185  PRBool result = mArray.InsertObjectAt(elementRef, aIndex);
186  return result ? NS_OK : NS_ERROR_FAILURE;
187  }
188 }
189 
190 NS_IMETHODIMP
191 sbArray::ReplaceElementAt(nsISupports* aElement, PRUint32 aIndex, PRBool aWeak)
192 {
193  nsCOMPtr<nsISupports> elementRef;
194  if (aWeak) {
195  elementRef =
196  getter_AddRefs(static_cast<nsISupports*>
197  (NS_GetWeakReference(aElement)));
198  NS_ASSERTION(elementRef, "ReplaceElementAt: Trying to use weak references on an object that doesn't support it");
199  if (!elementRef)
200  return NS_ERROR_FAILURE;
201  } else {
202  elementRef = aElement;
203  }
204  { /* scope */
205  nsAutoLock lock(mLock);
206  PRBool result = mArray.ReplaceObjectAt(elementRef, aIndex);
207  return result ? NS_OK : NS_ERROR_FAILURE;
208  }
209 }
210 
211 NS_IMETHODIMP
212 sbArray::Clear()
213 {
214  nsAutoLock lock(mLock);
215  mArray.Clear();
216  return NS_OK;
217 }
218 
219 //
220 // static helper routines
221 //
222 PRBool
223 FindElementCallback(void *aElement, void* aClosure)
224 {
225  findIndexOfClosure* closure =
226  static_cast<findIndexOfClosure*>(aClosure);
227 
229  static_cast<nsISupports*>(aElement);
230 
231  // don't start searching until we're past the startIndex
232  if (closure->resultIndex >= closure->startIndex &&
233  element == closure->targetElement) {
234  return PR_FALSE; // stop! We found it
235  }
236  closure->resultIndex++;
237 
238  return PR_TRUE;
239 }
return NS_OK
sbArray()
Definition: sbArray.cpp:60
PR_STATIC_CALLBACK(PRBool) FindElementCallback(void *aElement
PRBool InsertObjectAt(nsISupports *aObject, PRInt32 aIndex)
Definition: sbCOMArray.cpp:85
PRBool RemoveObjectAt(PRInt32 aIndex)
Definition: sbCOMArray.cpp:134
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
PRBool FindElementCallback(void *aElement, void *aClosure)
Definition: sbArray.cpp:223
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
PRInt32 IndexOf(nsISupports *aObject) const
Definition: sbCOMArray.h:58
PRBool ReplaceObjectAt(nsISupports *aObject, PRInt32 aIndex)
Definition: sbCOMArray.cpp:106
PRBool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void *aData)
Definition: sbCOMArray.h:64
void * aClosure
Definition: sbArray.cpp:52
nsISupports * targetElement
Definition: sbArray.cpp:47
PRUint32 resultIndex
Definition: sbArray.cpp:49
PRBool AppendObject(nsISupports *aObject)
Definition: sbCOMArray.h:83
const PR_UINT32_MAX
Definition: httpd.js:55
PRUint32 startIndex
Definition: sbArray.cpp:48
nsISupports * SafeObjectAt(PRInt32 aIndex) const
Definition: sbCOMArray.h:103
function notFound(ch)