• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /**
4  *******************************************************************************
5  * Copyright (C) 2001-2012, International Business Machines Corporation and    *
6  * others. All Rights Reserved.                                                *
7  *******************************************************************************
8  */
9 
10 #include "unicode/utypes.h"
11 
12 #if !UCONFIG_NO_SERVICE
13 
14 #include "servnotf.h"
15 #ifdef NOTIFIER_DEBUG
16 #include <stdio.h>
17 #endif
18 
19 U_NAMESPACE_BEGIN
20 
~EventListener()21 EventListener::~EventListener() {}
22 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
23 
24 static UMutex notifyLock;
25 
ICUNotifier()26 ICUNotifier::ICUNotifier()
27 : listeners(nullptr)
28 {
29 }
30 
~ICUNotifier()31 ICUNotifier::~ICUNotifier() {
32     {
33         Mutex lmx(&notifyLock);
34         delete listeners;
35         listeners = nullptr;
36     }
37 }
38 
39 
40 void
addListener(const EventListener * l,UErrorCode & status)41 ICUNotifier::addListener(const EventListener* l, UErrorCode& status)
42 {
43     if (U_SUCCESS(status)) {
44         if (l == nullptr) {
45             status = U_ILLEGAL_ARGUMENT_ERROR;
46             return;
47         }
48 
49         if (acceptsListener(*l)) {
50             Mutex lmx(&notifyLock);
51             if (listeners == nullptr) {
52                 LocalPointer<UVector> lpListeners(new UVector(5, status), status);
53                 if (U_FAILURE(status)) {
54                     return;
55                 }
56                 listeners = lpListeners.orphan();
57             } else {
58                 for (int i = 0, e = listeners->size(); i < e; ++i) {
59                     const EventListener* el = (const EventListener*)(listeners->elementAt(i));
60                     if (l == el) {
61                         return;
62                     }
63                 }
64             }
65 
66             listeners->addElement((void*)l, status); // cast away const
67         }
68 #ifdef NOTIFIER_DEBUG
69         else {
70             fprintf(stderr, "Listener invalid for this notifier.");
71             exit(1);
72         }
73 #endif
74     }
75 }
76 
77 void
removeListener(const EventListener * l,UErrorCode & status)78 ICUNotifier::removeListener(const EventListener *l, UErrorCode& status)
79 {
80     if (U_SUCCESS(status)) {
81         if (l == nullptr) {
82             status = U_ILLEGAL_ARGUMENT_ERROR;
83             return;
84         }
85 
86         {
87             Mutex lmx(&notifyLock);
88             if (listeners != nullptr) {
89                 // identity equality check
90                 for (int i = 0, e = listeners->size(); i < e; ++i) {
91                     const EventListener* el = (const EventListener*)listeners->elementAt(i);
92                     if (l == el) {
93                         listeners->removeElementAt(i);
94                         if (listeners->size() == 0) {
95                             delete listeners;
96                             listeners = nullptr;
97                         }
98                         return;
99                     }
100                 }
101             }
102         }
103     }
104 }
105 
106 void
notifyChanged()107 ICUNotifier::notifyChanged()
108 {
109     Mutex lmx(&notifyLock);
110     if (listeners != nullptr) {
111         for (int i = 0, e = listeners->size(); i < e; ++i) {
112             EventListener* el = (EventListener*)listeners->elementAt(i);
113             notifyListener(*el);
114         }
115     }
116 }
117 
118 U_NAMESPACE_END
119 
120 /* UCONFIG_NO_SERVICE */
121 #endif
122 
123