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