Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/ds/nsObserverList.cpp
Line
Count
Source (jump to first uncovered line)
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 "nsObserverList.h"
8
9
#include "nsAutoPtr.h"
10
#include "nsCOMArray.h"
11
#include "xpcpublic.h"
12
13
nsresult
14
nsObserverList::AddObserver(nsIObserver* anObserver, bool ownsWeak)
15
347
{
16
347
  NS_ASSERTION(anObserver, "Null input");
17
347
18
347
  if (!ownsWeak) {
19
172
    ObserverRef* o = mObservers.AppendElement(anObserver);
20
172
    if (!o) {
21
0
      return NS_ERROR_OUT_OF_MEMORY;
22
0
    }
23
172
24
172
    return NS_OK;
25
172
  }
26
175
27
175
  nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(anObserver);
28
175
  if (!weak) {
29
9
    return NS_NOINTERFACE;
30
9
  }
31
166
32
166
  ObserverRef* o = mObservers.AppendElement(weak);
33
166
  if (!o) {
34
0
    return NS_ERROR_OUT_OF_MEMORY;
35
0
  }
36
166
37
166
  return NS_OK;
38
166
}
39
40
nsresult
41
nsObserverList::RemoveObserver(nsIObserver* anObserver)
42
0
{
43
0
  NS_ASSERTION(anObserver, "Null input");
44
0
45
0
  if (mObservers.RemoveElement(static_cast<nsISupports*>(anObserver))) {
46
0
    return NS_OK;
47
0
  }
48
0
49
0
  nsCOMPtr<nsIWeakReference> observerRef = do_GetWeakReference(anObserver);
50
0
  if (!observerRef) {
51
0
    return NS_ERROR_FAILURE;
52
0
  }
53
0
54
0
  if (!mObservers.RemoveElement(observerRef)) {
55
0
    return NS_ERROR_FAILURE;
56
0
  }
57
0
58
0
  return NS_OK;
59
0
}
60
61
void
62
nsObserverList::GetObserverList(nsISimpleEnumerator** anEnumerator)
63
0
{
64
0
  RefPtr<nsObserverEnumerator> e(new nsObserverEnumerator(this));
65
0
  e.forget(anEnumerator);
66
0
}
67
68
void
69
nsObserverList::FillObserverArray(nsCOMArray<nsIObserver>& aArray)
70
0
{
71
0
  aArray.SetCapacity(mObservers.Length());
72
0
73
0
  nsTArray<ObserverRef> observers(mObservers);
74
0
75
0
  for (int32_t i = observers.Length() - 1; i >= 0; --i) {
76
0
    if (observers[i].isWeakRef) {
77
0
      nsCOMPtr<nsIObserver> o(do_QueryReferent(observers[i].asWeak()));
78
0
      if (o) {
79
0
        aArray.AppendObject(o);
80
0
      } else {
81
0
        // the object has gone away, remove the weakref
82
0
        mObservers.RemoveElement(observers[i].asWeak());
83
0
      }
84
0
    } else {
85
0
      aArray.AppendObject(observers[i].asObserver());
86
0
    }
87
0
  }
88
0
}
89
90
void
91
nsObserverList::AppendStrongObservers(nsCOMArray<nsIObserver>& aArray)
92
0
{
93
0
  aArray.SetCapacity(aArray.Length() + mObservers.Length());
94
0
95
0
  for (int32_t i = mObservers.Length() - 1; i >= 0; --i) {
96
0
    if (!mObservers[i].isWeakRef) {
97
0
      aArray.AppendObject(mObservers[i].asObserver());
98
0
    }
99
0
  }
100
0
}
101
102
void
103
nsObserverList::NotifyObservers(nsISupports* aSubject,
104
                                const char* aTopic,
105
                                const char16_t* someData)
106
0
{
107
0
  nsCOMArray<nsIObserver> observers;
108
0
  FillObserverArray(observers);
109
0
110
0
  for (int32_t i = 0; i < observers.Count(); ++i) {
111
0
    observers[i]->Observe(aSubject, aTopic, someData);
112
0
  }
113
0
}
114
115
nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)
116
  : mIndex(0)
117
0
{
118
0
  aObserverList->FillObserverArray(mObservers);
119
0
}
120
121
NS_IMETHODIMP
122
nsObserverEnumerator::HasMoreElements(bool* aResult)
123
0
{
124
0
  *aResult = (mIndex < mObservers.Count());
125
0
  return NS_OK;
126
0
}
127
128
NS_IMETHODIMP
129
nsObserverEnumerator::GetNext(nsISupports** aResult)
130
0
{
131
0
  if (mIndex == mObservers.Count()) {
132
0
    return NS_ERROR_FAILURE;
133
0
  }
134
0
135
0
  NS_ADDREF(*aResult = mObservers[mIndex]);
136
0
  ++mIndex;
137
0
  return NS_OK;
138
0
}