sbPropertyArray.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25 */
26 
27 #include "sbPropertyArray.h"
28 
29 #include <nsIClassInfoImpl.h>
30 #include <nsIObjectInputStream.h>
31 #include <nsIObjectOutputStream.h>
32 #include <nsIProgrammingLanguage.h>
33 #include <nsISimpleEnumerator.h>
34 #include <sbIPropertyManager.h>
35 #include <sbIPropertyInfo.h>
36 
37 #include <nsArrayEnumerator.h>
38 #include <nsCOMPtr.h>
39 #include <nsComponentManagerUtils.h>
40 #include <nsMemory.h>
41 #include <nsServiceManagerUtils.h>
42 #include <nsTArray.h>
43 #include "sbPropertiesCID.h"
44 #include "sbSimpleProperty.h"
45 
48 
49 NS_INTERFACE_MAP_BEGIN(sbPropertyArray)
50  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
51  NS_INTERFACE_MAP_ENTRY(sbIPropertyArray)
52  NS_INTERFACE_MAP_ENTRY(sbIMutablePropertyArray)
53  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIArray, nsIMutableArray)
54  NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
55  NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
56  NS_INTERFACE_MAP_ENTRY(nsISerializable)
57 NS_INTERFACE_MAP_END
58 
59 static NS_DEFINE_CID(kPropertyArrayCID, SB_MUTABLEPROPERTYARRAY_CID);
60 
62  nsIMutableArray,
67 sbPropertyArray::sbPropertyArray()
68 : mArrayLock(nsnull),
69  mStrict(PR_TRUE)
70 {
71 }
72 
74 {
75  if(mArrayLock) {
76  nsAutoLock::DestroyLock(mArrayLock);
77  }
78 }
79 
80 nsresult
82 {
83  mArrayLock = nsAutoLock::NewLock("sbPropertyArray::mArrayLock");
84  NS_ENSURE_TRUE(mArrayLock, NS_ERROR_OUT_OF_MEMORY);
85 
86  return NS_OK;
87 }
88 
92 nsresult
93 sbPropertyArray::PropertyIsValid(sbIProperty* aProperty,
94  PRBool* _retval)
95 {
96  NS_ASSERTION(aProperty, "Don't hand me a null!");
97  NS_ASSERTION(_retval, "Don't hand me a null!");
98 
99  nsString id;
100  nsresult rv = aProperty->GetId(id);
101  NS_ENSURE_SUCCESS(rv, rv);
102 
103  nsString value;
104  rv = aProperty->GetValue(value);
105  NS_ENSURE_SUCCESS(rv, rv);
106 
107  return ValueIsValid(id, value, _retval);
108 }
109 
114 nsresult
115 sbPropertyArray::ValueIsValid(const nsAString& aID,
116  const nsAString& aValue,
117  PRBool* _retval)
118 {
119  NS_ASSERTION(!aID.IsEmpty(), "Don't pass an empty property id!");
120  NS_ASSERTION(_retval, "Don't hand me a null!");
121 
122  if (aValue.IsVoid()) {
123  *_retval = PR_TRUE;
124  return NS_OK;
125  }
126 
127  nsresult rv;
128 
129  if (!mPropManager) {
130  mPropManager = do_GetService(SB_PROPERTYMANAGER_CONTRACTID, &rv);
131  NS_ENSURE_SUCCESS(rv, rv);
132  }
133 
134  // This will actually *create* a new sbIPropertyInfo if one has not been
135  // registered already...
136  nsCOMPtr<sbIPropertyInfo> propInfo;
137  rv = mPropManager->GetPropertyInfo(aID, getter_AddRefs(propInfo));
138  NS_ENSURE_SUCCESS(rv, rv);
139 
140  PRBool valid;
141  rv = propInfo->Validate(aValue, &valid);
142  NS_ENSURE_SUCCESS(rv, rv);
143 
144  *_retval = valid;
145  return NS_OK;
146 }
147 
151 NS_IMETHODIMP
152 sbPropertyArray::GetLength(PRUint32* aLength)
153 {
154  NS_ENSURE_ARG_POINTER(aLength);
155 
156  nsAutoLock lock(mArrayLock);
157  *aLength = (PRUint32)mArray.Count();
158  return NS_OK;
159 }
160 
164 NS_IMETHODIMP
165 sbPropertyArray::QueryElementAt(PRUint32 aIndex,
166  const nsIID& aIID,
167  void** _retval)
168 {
169  NS_ENSURE_ARG(aIndex < static_cast<PRUint32>(mArray.Count()));
170  NS_ENSURE_ARG_POINTER(_retval);
171 
172  nsAutoLock lock(mArrayLock);
173  nsCOMPtr<nsISupports> element = mArray.ObjectAt(aIndex);
174  NS_ENSURE_STATE(element);
175 
176  return element->QueryInterface(aIID, _retval);
177 }
178 
182 NS_IMETHODIMP
183 sbPropertyArray::IndexOf(PRUint32 aStartIndex,
184  nsISupports* aElement,
185  PRUint32* _retval)
186 {
187  NS_ENSURE_ARG_POINTER(aElement);
188  NS_ENSURE_ARG_POINTER(_retval);
189 
190  // nsCOMArray doesn't provide any way for us to start searching for an element
191  // at an offset, so warn about the usage. Hopefully no one will use this
192  // method anyway ;)
193 #ifdef DEBUG
194  if (aStartIndex) {
195  NS_WARNING("sbPropertyArray::IndexOf ignores aStartIndex parameter!");
196  }
197 #endif
198 
199  nsresult rv;
200  nsCOMPtr<sbIProperty> property = do_QueryInterface(aElement, &rv);
201  NS_ENSURE_SUCCESS(rv, rv);
202 
203  nsAutoLock lock(mArrayLock);
204  PRInt32 index = mArray.IndexOf(property);
205  NS_ENSURE_TRUE(index >= 0, NS_ERROR_NOT_AVAILABLE);
206 
207  *_retval = (PRUint32)index;
208  return NS_OK;
209 }
210 
214 NS_IMETHODIMP
215 sbPropertyArray::Enumerate(nsISimpleEnumerator** _retval)
216 {
217  NS_ENSURE_ARG_POINTER(_retval);
218 
219  nsresult rv;
220  nsCOMPtr<nsIMutableArray> array =
221  do_CreateInstance("@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
222  NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
223 
224  nsAutoLock lock(mArrayLock);
225  PRUint32 length = mArray.Count();
226  for (PRUint32 i = 0; i < length; i++) {
227  rv = array->AppendElement(mArray.ObjectAt(i), PR_FALSE);
228  NS_ENSURE_SUCCESS(rv, rv);
229  }
230 
231  return NS_NewArrayEnumerator(_retval, array);
232 }
233 
237 NS_IMETHODIMP
238 sbPropertyArray::AppendElement(nsISupports* aElement,
239  PRBool aWeak)
240 {
241  NS_ENSURE_ARG_POINTER(aElement);
242 
243  // No support for weak references here
244  NS_ENSURE_FALSE(aWeak, NS_ERROR_FAILURE);
245 
246  nsresult rv;
247  nsCOMPtr<sbIProperty> property = do_QueryInterface(aElement, &rv);
248  NS_ENSURE_SUCCESS(rv, rv);
249 
250  nsAutoLock lock(mArrayLock);
251 
252  if (mStrict) {
253  PRBool valid;
254  rv = PropertyIsValid(property, &valid);
255  NS_ENSURE_SUCCESS(rv, rv);
256 
257  NS_ENSURE_TRUE(valid, NS_ERROR_ILLEGAL_VALUE);
258  }
259 
260  PRBool success = mArray.AppendObject(property);
261  NS_ENSURE_STATE(success);
262 
263  return NS_OK;
264 }
265 
269 NS_IMETHODIMP
270 sbPropertyArray::RemoveElementAt(PRUint32 aIndex)
271 {
272  NS_ENSURE_ARG(aIndex < static_cast<PRUint32>(mArray.Count()));
273 
274  nsAutoLock lock(mArrayLock);
275  PRBool success = mArray.RemoveObjectAt(aIndex);
276  NS_ENSURE_STATE(success);
277  return NS_OK;
278 }
279 
283 NS_IMETHODIMP
284 sbPropertyArray::InsertElementAt(nsISupports* aElement,
285  PRUint32 aIndex,
286  PRBool aWeak)
287 {
288  NS_ENSURE_ARG_POINTER(aElement);
289  NS_ENSURE_ARG_MAX((PRInt32)aIndex, mArray.Count());
290 
291  // No support for weak references here
292  NS_ENSURE_FALSE(aWeak, NS_ERROR_FAILURE);
293 
294  nsresult rv;
295  nsCOMPtr<sbIProperty> property = do_QueryInterface(aElement, &rv);
296  NS_ENSURE_SUCCESS(rv, rv);
297 
298  nsAutoLock lock(mArrayLock);
299 
300  if (mStrict) {
301  PRBool valid;
302  rv = PropertyIsValid(property, &valid);
303  NS_ENSURE_SUCCESS(rv, rv);
304 
305  NS_ENSURE_TRUE(valid, NS_ERROR_ILLEGAL_VALUE);
306  }
307 
308  PRBool success = mArray.InsertObjectAt(property, aIndex);
309  NS_ENSURE_STATE(success);
310 
311  return NS_OK;
312 }
313 
317 NS_IMETHODIMP
318 sbPropertyArray::ReplaceElementAt(nsISupports* aElement,
319  PRUint32 aIndex,
320  PRBool aWeak)
321 {
322  NS_ENSURE_ARG_POINTER(aElement);
323  NS_ENSURE_ARG(aIndex < static_cast<PRUint32>(mArray.Count()));
324 
325  // No support for weak references here
326  NS_ENSURE_FALSE(aWeak, NS_ERROR_NOT_IMPLEMENTED);
327 
328  nsresult rv;
329  nsCOMPtr<sbIProperty> property = do_QueryInterface(aElement, &rv);
330  NS_ENSURE_SUCCESS(rv, rv);
331 
332  nsAutoLock lock(mArrayLock);
333 
334  if (mStrict) {
335  PRBool valid;
336  rv = PropertyIsValid(property, &valid);
337  NS_ENSURE_SUCCESS(rv, rv);
338 
339  NS_ENSURE_TRUE(valid, NS_ERROR_ILLEGAL_VALUE);
340  }
341 
342  PRBool success = mArray.ReplaceObjectAt(property, aIndex);
343  NS_ENSURE_STATE(success);
344 
345  return NS_OK;
346 }
347 
351 NS_IMETHODIMP
352 sbPropertyArray::Clear()
353 {
354  nsAutoLock lock(mArrayLock);
355  mArray.Clear();
356  return NS_OK;
357 }
358 
362 NS_IMETHODIMP
363 sbPropertyArray::AppendProperty(const nsAString& aID,
364  const nsAString& aValue)
365 {
366  NS_ENSURE_TRUE(!aID.IsEmpty(), NS_ERROR_INVALID_ARG);
367 
368  nsAutoLock lock(mArrayLock);
369 
370  if (mStrict) {
371  PRBool valid;
372  nsresult rv = ValueIsValid(aID, aValue, &valid);
373  NS_ENSURE_SUCCESS(rv, rv);
374 
375  NS_ENSURE_TRUE(valid, NS_ERROR_ILLEGAL_VALUE);
376  }
377 
378  nsCOMPtr<sbIProperty> property = new sbSimpleProperty(aID, aValue);
379  NS_ENSURE_TRUE(property, NS_ERROR_OUT_OF_MEMORY);
380 
381  PRBool success = mArray.AppendObject(property);
382  NS_ENSURE_STATE(success);
383 
384  return NS_OK;
385 }
386 
390 NS_IMETHODIMP
391 sbPropertyArray::AppendProperties(sbIPropertyArray* aPropertyArray,
392  PRBool aSkipDuplicates)
393 {
394  NS_ENSURE_ARG_POINTER(aPropertyArray);
395 
396  PRUint32 propertyCount;
397  nsresult rv;
398 
399  nsAutoLock lock(mArrayLock);
400 
401  // If skipping duplicates, create the list of IDs of properties already in
402  // array.
403  nsTArray<nsString> currentPropertyIDList;
404  if (aSkipDuplicates) {
405  propertyCount = mArray.Count();
406  NS_ENSURE_TRUE(currentPropertyIDList.SetCapacity(propertyCount),
407  NS_ERROR_OUT_OF_MEMORY);
408  for (PRUint32 i = 0; i < propertyCount; i++) {
409  nsCOMPtr<sbIProperty> property = mArray[i];
410 
411  nsAutoString id;
412  rv = property->GetId(id);
413  NS_ENSURE_SUCCESS(rv, rv);
414  NS_ENSURE_TRUE(currentPropertyIDList.AppendElement(id),
415  NS_ERROR_OUT_OF_MEMORY);
416  }
417  }
418 
419  // Add properties to array.
420  rv = aPropertyArray->GetLength(&propertyCount);
421  NS_ENSURE_SUCCESS(rv, rv);
422  for (PRUint32 i = 0; i < propertyCount; i++) {
423  // Get the next property to add.
424  nsCOMPtr<sbIProperty> property;
425  rv = aPropertyArray->GetPropertyAt(i, getter_AddRefs(property));
426  NS_ENSURE_SUCCESS(rv, rv);
427 
428  // Get the property info.
429  nsAutoString id;
430  nsAutoString value;
431  rv = property->GetId(id);
432  NS_ENSURE_SUCCESS(rv, rv);
433  rv = property->GetValue(value);
434  NS_ENSURE_SUCCESS(rv, rv);
435 
436  // Validate property if strict.
437  if (mStrict) {
438  PRBool valid;
439  rv = ValueIsValid(id, value, &valid);
440  NS_ENSURE_SUCCESS(rv, rv);
441  NS_ENSURE_TRUE(valid, NS_ERROR_ILLEGAL_VALUE);
442  }
443 
444  // If skipping duplicates and property is a duplicate, skip it.
445  if (aSkipDuplicates && currentPropertyIDList.Contains(id)) {
446  continue;
447  }
448 
449  // Add the property to the array and its ID to the list of present property
450  // IDs.
451  PRBool success = mArray.AppendObject(property);
452  NS_ENSURE_STATE(success);
453  NS_ENSURE_TRUE(currentPropertyIDList.AppendElement(id),
454  NS_ERROR_OUT_OF_MEMORY);
455  }
456 
457  return NS_OK;
458 }
459 
463 NS_IMETHODIMP
464 sbPropertyArray::SetStrict(PRBool aStrict)
465 {
466  nsAutoLock lock(mArrayLock);
467 
468  if ((aStrict != mStrict) && mArray.Count()) {
469  NS_WARNING("Can't change strict setting of a non-empty sbPropertyArray!");
470  return NS_ERROR_FAILURE;
471  }
472 
473  if (mStrict == aStrict) {
474  return NS_OK;
475  }
476 
477  // Free the property manager if it will no longer be needed.
478  if (!aStrict && mPropManager) {
479  mPropManager = nsnull;
480  }
481 
482  mStrict = aStrict;
483  return NS_OK;
484 }
485 
489 NS_IMETHODIMP
490 sbPropertyArray::GetStrict(PRBool* aStrict)
491 {
492  NS_ENSURE_ARG_POINTER(aStrict);
493 
494  nsAutoLock lock(mArrayLock);
495 
496  *aStrict = mStrict;
497  return NS_OK;
498 }
499 
503 NS_IMETHODIMP
504 sbPropertyArray::GetPropertyAt(PRUint32 aIndex,
505  sbIProperty** _retval)
506 {
507  NS_ENSURE_ARG(aIndex < static_cast<PRUint32>(mArray.Count()));
508  NS_ENSURE_ARG_POINTER(_retval);
509 
510  nsAutoLock lock(mArrayLock);
511  nsCOMPtr<sbIProperty> property = mArray.ObjectAt(aIndex);
512  NS_ENSURE_STATE(property);
513 
514  NS_ADDREF(*_retval = property);
515  return NS_OK;
516 }
517 
521 NS_IMETHODIMP
522 sbPropertyArray::GetPropertyValue(const nsAString& aID,
523  nsAString& _retval)
524 {
525  nsresult rv;
526 
527  nsAutoLock lock(mArrayLock);
528  PRUint32 length = mArray.Count();
529  for (PRUint32 i = 0; i < length; i++) {
530  nsCOMPtr<sbIProperty> property = mArray.ObjectAt(i);
531  NS_ENSURE_STATE(property);
532 
533  nsAutoString propertyID;
534  rv = property->GetId(propertyID);
535  NS_ENSURE_SUCCESS(rv, rv);
536 
537  if (propertyID.Equals(aID)) {
538  rv = property->GetValue(_retval);
539  NS_ENSURE_SUCCESS(rv, rv);
540  return NS_OK;
541  }
542  }
543 
544  return NS_ERROR_NOT_AVAILABLE;
545 }
546 
550 NS_IMETHODIMP
551 sbPropertyArray::ToString(nsAString& _retval)
552 {
553  nsresult rv;
554 
555  nsAutoLock lock(mArrayLock);
556 
557  nsAutoString buff;
558  buff.AssignLiteral("[");
559 
560  PRUint32 length = mArray.Count();
561  for (PRUint32 i = 0; i < length; i++) {
562  nsCOMPtr<sbIProperty> property = mArray.ObjectAt(i);
563  NS_ENSURE_STATE(property);
564 
565  nsAutoString propertyID;
566  rv = property->GetId(propertyID);
567  NS_ENSURE_SUCCESS(rv, rv);
568 
569  nsAutoString value;
570  rv = property->GetValue(value);
571  NS_ENSURE_SUCCESS(rv, rv);
572 
573  buff.AppendLiteral("'");
574  buff.Append(propertyID);
575  buff.AppendLiteral("' => ");
576 
577  buff.AppendLiteral("'");
578  buff.Append(value);
579  buff.AppendLiteral("'");
580 
581  if (i + 1 < length) {
582  buff.AppendLiteral(", ");
583  }
584  }
585 
586  buff.AppendLiteral("]");
587  _retval = buff;
588 
589  return NS_OK;
590 }
591 
595 NS_IMETHODIMP
596 sbPropertyArray::GetValidated(PRBool* aValidated)
597 {
598  return GetStrict(aValidated);
599 }
600 
601 // nsISerializable
602 NS_IMETHODIMP
603 sbPropertyArray::Read(nsIObjectInputStream* aStream)
604 {
605  NS_ENSURE_ARG_POINTER(aStream);
606 
607  nsresult rv;
608 
609  nsAutoLock lock(mArrayLock);
610 
611  rv = aStream->ReadBoolean(&mStrict);
612  NS_ENSURE_SUCCESS(rv, rv);
613 
614  PRUint32 length;
615  rv = aStream->Read32(&length);
616  NS_ENSURE_SUCCESS(rv, rv);
617 
618  mArray.Clear();
619  for (PRUint32 i = 0; i < length; i++) {
620 
621  nsString id;
622  rv = aStream->ReadString(id);
623  NS_ENSURE_SUCCESS(rv, rv);
624 
625  nsString value;
626  rv = aStream->ReadString(value);
627  NS_ENSURE_SUCCESS(rv, rv);
628 
629  nsCOMPtr<sbIProperty> property = new sbSimpleProperty(id, value);
630  NS_ENSURE_TRUE(property, NS_ERROR_OUT_OF_MEMORY);
631 
632  PRBool success = mArray.AppendObject(property);
633  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
634  }
635 
636  return NS_OK;
637 }
638 
639 NS_IMETHODIMP
640 sbPropertyArray::Write(nsIObjectOutputStream* aStream)
641 {
642  NS_ENSURE_ARG_POINTER(aStream);
643 
644  nsresult rv;
645 
646  nsAutoLock lock(mArrayLock);
647 
648  rv = aStream->WriteBoolean(mStrict);
649  NS_ENSURE_SUCCESS(rv, rv);
650 
651  PRUint32 length = mArray.Count();
652  rv = aStream->Write32(length);
653  NS_ENSURE_SUCCESS(rv, rv);
654 
655  for (PRUint32 i = 0; i < length; i++) {
656  nsCOMPtr<sbIProperty> property = mArray.ObjectAt(i);
657  NS_ENSURE_STATE(property);
658 
659  nsString id;
660  rv = property->GetId(id);
661  NS_ENSURE_SUCCESS(rv, rv);
662 
663  nsString value;
664  rv = property->GetValue(value);
665  NS_ENSURE_SUCCESS(rv, rv);
666 
667  rv = aStream->WriteWStringZ(id.BeginReading());
668  NS_ENSURE_SUCCESS(rv, rv);
669 
670  rv = aStream->WriteWStringZ(value.BeginReading());
671  NS_ENSURE_SUCCESS(rv, rv);
672  }
673 
674  return NS_OK;
675 }
676 
677 // nsIClassInfo
678 NS_IMETHODIMP
679 sbPropertyArray::GetInterfaces(PRUint32* count, nsIID*** array)
680 {
681  return NS_CI_INTERFACE_GETTER_NAME(sbPropertyArray)(count, array);
682 }
683 
684 NS_IMETHODIMP
685 sbPropertyArray::GetHelperForLanguage(PRUint32 language,
686  nsISupports** _retval)
687 {
688  *_retval = nsnull;
689  return NS_OK;
690 }
691 
692 NS_IMETHODIMP
693 sbPropertyArray::GetContractID(char** aContractID)
694 {
695  *aContractID = nsnull;
696  return NS_OK;
697 }
698 
699 NS_IMETHODIMP
700 sbPropertyArray::GetClassDescription(char** aClassDescription)
701 {
702  *aClassDescription = nsnull;
703  return NS_OK;
704 }
705 
706 NS_IMETHODIMP
707 sbPropertyArray::GetClassID(nsCID** aClassID)
708 {
709  *aClassID = nsnull;
710  return NS_OK;
711 }
712 
713 NS_IMETHODIMP
714 sbPropertyArray::GetImplementationLanguage(PRUint32* aImplementationLanguage)
715 {
716  *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
717  return NS_OK;
718 }
719 
720 NS_IMETHODIMP
721 sbPropertyArray::GetFlags(PRUint32 *aFlags)
722 {
723  *aFlags = 0;
724  return NS_OK;
725 }
726 
727 NS_IMETHODIMP
728 sbPropertyArray::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
729 {
730  NS_ENSURE_ARG_POINTER(aClassIDNoAlloc);
731  *aClassIDNoAlloc = kPropertyArrayCID;
732  return NS_OK;
733 }
734 
return NS_OK
menuItem id
Definition: FeedWriter.js:971
onPageChanged aValue
Definition: FeedWriter.js:1395
inArray array
#define SB_MUTABLEPROPERTYARRAY_CID
var language
Definition: Info.js:44
static nsresult ToString(const nsDiscriminatedUnion &data, nsACString &outString)
Definition: sbVariant.cpp:861
NS_IMPL_THREADSAFE_RELEASE(sbRequestItem)
NS_IMPL_THREADSAFE_ADDREF(sbRequestItem)
#define SB_PROPERTYMANAGER_CONTRACTID
An interface to carry around arrays of nsIProperty instances Note that implementations of the interfa...
var count
Definition: test_bug7406.js:32
nsISerializable
countRef value
Definition: FeedWriter.js:1423
NS_IMPL_CI_INTERFACE_GETTER6(sbPropertyArray, nsIArray, nsIMutableArray, nsISerializable, sbIPropertyArray, sbIMutablePropertyArray, nsIClassInfo) sbPropertyArray
static NS_INTERFACE_MAP_END NS_DEFINE_CID(kPropertyArrayCID,{0xc7e88d66, 0x5a02, 0x4ab2,{0xba, 0x0b, 0x37, 0x5e, 0x80, 0x2b, 0x05, 0xea}})
An interface to carry around arrays of nsIProperty instances. Users of this interface should only QI ...
_getSelectedPageStyle s i