Imported Upstream version 58.1
[platform/upstream/icu.git] / source / common / servnotf.cpp
1 // Copyright (C) 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
21 EventListener::~EventListener() {}
22 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
23
24 static UMutex notifyLock = U_MUTEX_INITIALIZER;
25
26 ICUNotifier::ICUNotifier(void) 
27 : listeners(NULL) 
28 {
29 }
30
31 ICUNotifier::~ICUNotifier(void) {
32     {
33         Mutex lmx(&notifyLock);
34         delete listeners;
35         listeners = NULL;
36     }
37 }
38
39
40 void 
41 ICUNotifier::addListener(const EventListener* l, UErrorCode& status) 
42 {
43     if (U_SUCCESS(status)) {
44         if (l == NULL) {
45             status = U_ILLEGAL_ARGUMENT_ERROR;
46             return;
47         }
48
49         if (acceptsListener(*l)) {
50             Mutex lmx(&notifyLock);
51             if (listeners == NULL) {
52                 listeners = new UVector(5, status);
53             } else {
54                 for (int i = 0, e = listeners->size(); i < e; ++i) {
55                     const EventListener* el = (const EventListener*)(listeners->elementAt(i));
56                     if (l == el) {
57                         return;
58                     }
59                 }
60             }
61
62             listeners->addElement((void*)l, status); // cast away const
63         }
64 #ifdef NOTIFIER_DEBUG
65         else {
66             fprintf(stderr, "Listener invalid for this notifier.");
67             exit(1);
68         }
69 #endif
70     }
71 }
72
73 void 
74 ICUNotifier::removeListener(const EventListener *l, UErrorCode& status) 
75 {
76     if (U_SUCCESS(status)) {
77         if (l == NULL) {
78             status = U_ILLEGAL_ARGUMENT_ERROR;
79             return;
80         }
81
82         {
83             Mutex lmx(&notifyLock);
84             if (listeners != NULL) {
85                 // identity equality check
86                 for (int i = 0, e = listeners->size(); i < e; ++i) {
87                     const EventListener* el = (const EventListener*)listeners->elementAt(i);
88                     if (l == el) {
89                         listeners->removeElementAt(i);
90                         if (listeners->size() == 0) {
91                             delete listeners;
92                             listeners = NULL;
93                         }
94                         return;
95                     }
96                 }
97             }
98         }
99     }
100 }
101
102 void 
103 ICUNotifier::notifyChanged(void) 
104 {
105     if (listeners != NULL) {
106         Mutex lmx(&notifyLock);
107         if (listeners != NULL) {
108             for (int i = 0, e = listeners->size(); i < e; ++i) {
109                 EventListener* el = (EventListener*)listeners->elementAt(i);
110                 notifyListener(*el);
111             }
112         }
113     }
114 }
115
116 U_NAMESPACE_END
117
118 /* UCONFIG_NO_SERVICE */
119 #endif
120