1/**
2 *******************************************************************************
3 * Copyright (C) 2001-2012, 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
17U_NAMESPACE_BEGIN
18
19EventListener::~EventListener() {}
20UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
21
22static UMutex notifyLock = U_MUTEX_INITIALIZER;
23
24ICUNotifier::ICUNotifier(void)
25: listeners(NULL)
26{
27}
28
29ICUNotifier::~ICUNotifier(void) {
30    {
31        Mutex lmx(&notifyLock);
32        delete listeners;
33        listeners = NULL;
34    }
35}
36
37
38void
39ICUNotifier::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
71void
72ICUNotifier::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
100void
101ICUNotifier::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
114U_NAMESPACE_END
115
116/* UCONFIG_NO_SERVICE */
117#endif
118
119