summaryrefslogtreecommitdiffstats
path: root/src/plugins/push-notification/push-notification-events.c
blob: a71e8a62e551f2774139c245b65911b977e3b7ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "array.h"

#include "push-notification-drivers.h"
#include "push-notification-events.h"

ARRAY_TYPE(push_notification_event) push_notification_events;

ARRAY_TYPE(push_notification_event) *push_notification_get_events(void)
{
	return &push_notification_events;
}

static bool
push_notification_event_find(const char *name, unsigned int *idx_r)
{
	unsigned int count, i;
	const struct push_notification_event *const *events;

	events = array_get(&push_notification_events, &count);
	for (i = 0; i < count; i++) {
		if (strcasecmp(events[i]->name, name) == 0) {
			*idx_r = i;
			return TRUE;
		}
	}

	return FALSE;
}

static const struct push_notification_event *
push_notification_event_find_class(const char *driver)
{
	unsigned int idx;

	if (!push_notification_event_find(driver, &idx))
		return NULL;

	return array_idx_elem(&push_notification_events, idx);
}

void push_notification_event_init(struct push_notification_driver_txn *dtxn,
				  const char *event_name, void *config)
{
	const struct push_notification_event *event;
	struct push_notification_event_config *ec;

	if (!array_is_created(&dtxn->ptxn->events))
		p_array_init(&dtxn->ptxn->events, dtxn->ptxn->pool, 4);

	event = push_notification_event_find_class(event_name);
	if (event != NULL) {
		if ((config == NULL) && (event->init.default_config != NULL)) {
			config = event->init.default_config();
		}

		ec = p_new(dtxn->ptxn->pool,
			   struct push_notification_event_config, 1);
		ec->config = config;
		ec->event = event;

		array_push_back(&dtxn->ptxn->events, &ec);
	}
}

void push_notification_event_register(
	const struct push_notification_event *event)
{
	unsigned int idx;

	if (!array_is_created(&push_notification_events))
		i_array_init(&push_notification_events, 16);

	if (push_notification_event_find(event->name, &idx)) {
		i_panic("push_notification_event_register(%s): duplicate event",
			event->name);
	}

	array_push_back(&push_notification_events, &event);
}

void push_notification_event_unregister(
	const struct push_notification_event *event)
{
	unsigned int idx;

	if (!push_notification_event_find(event->name, &idx)) {
		i_panic("push_notification_event_register(%s): unknown event",
			event->name);
	}

	if (array_is_created(&push_notification_events)) {
		array_delete(&push_notification_events, idx, 1);

		if (array_is_empty(&push_notification_events))
			array_free(&push_notification_events);
	}
}