Browse code

corrected content-type propagation through QSA

Vaclav Kubart authored on 10/04/2006 16:59:07
Showing 5 changed files
... ...
@@ -1,3 +1,6 @@
1
+2006-04-10
2
+	* changed QSA - corrected content-type propagation
3
+
1 4
 2006-03-21
2 5
 	* subscription status propagation through QSA
3 6
 
... ...
@@ -73,10 +73,9 @@ typedef enum {
73 73
 typedef struct {
74 74
 	/* replacement for record_id, package, ... it is much more efficient */
75 75
 	subscription_t *subscription; 
76
-	int data_type;
76
+	qsa_content_type_t *content_type;
77 77
 	void *data;
78 78
 	int data_len;
79
-	destroy_function_f destroy_func; /* function used to destroy data */
80 79
 	qsa_subscription_status_t status;
81 80
 } client_notify_info_t;
82 81
 
... ...
@@ -86,9 +85,8 @@ void free_client_notify_info_content(client_notify_info_t *info);
86 85
 /* notifications SHOULD be sent through this method */
87 86
 int notify_subscriber(subscription_t *s, 
88 87
 		notifier_t *n,
89
-		int data_type, 
88
+		qsa_content_type_t *content_type, 
90 89
 		void *data, 
91
-		destroy_function_f data_destroy,
92 90
 		qsa_subscription_status_t status);
93 91
 
94 92
 #ifdef __cplusplus
... ...
@@ -136,6 +136,66 @@ static void destroy_package(notifier_package_t *p)
136 136
 	cds_free(p);
137 137
 }
138 138
 
139
+/* -------- content type functions -------- */
140
+
141
+static qsa_content_type_t *find_content_type(notifier_domain_t *d, const str_t *name)
142
+{
143
+	qsa_content_type_t *p;
144
+
145
+	if (!d) return NULL;
146
+	p = d->first_content_type;
147
+	while (p) {
148
+		if (str_case_equals(name, &p->name) == 0) return p;
149
+		p = p->next;
150
+	}
151
+	return NULL;
152
+}
153
+
154
+static void add_content_type(notifier_domain_t *d, qsa_content_type_t *p)
155
+{
156
+	DOUBLE_LINKED_LIST_ADD(d->first_content_type, d->last_content_type, p);
157
+}
158
+
159
+static qsa_content_type_t *create_content_type(const str_t *name, 
160
+		destroy_function_f destroy_func)
161
+{
162
+	qsa_content_type_t *p = (qsa_content_type_t*)cds_malloc(sizeof(qsa_content_type_t) + str_len(name));
163
+	if (p) {
164
+		p->next = NULL;
165
+		p->prev = NULL;
166
+		p->name.s = p->buf;
167
+		if (str_len(name) > 0) {
168
+			memcpy(p->name.s, name->s, name->len);
169
+			p->name.len = name->len;
170
+		}
171
+		else p->name.len = 0;
172
+		p->destroy_func = destroy_func;
173
+	}
174
+	return p;
175
+}
176
+
177
+/** finds existing package or adds new if not exists */
178
+qsa_content_type_t *register_content_type(notifier_domain_t *d, 
179
+		const str_t *name,
180
+		destroy_function_f destroy_func)
181
+{
182
+	qsa_content_type_t *p = NULL;
183
+	
184
+	if (is_str_empty(name)) return NULL;
185
+	
186
+	p = find_content_type(d, name);
187
+	if (!p) {
188
+		p = create_content_type(name, destroy_func);
189
+		if (p) add_content_type(d, p);
190
+	}
191
+	return p;
192
+}
193
+	
194
+static void destroy_content_type(qsa_content_type_t *p) 
195
+{
196
+	cds_free(p);
197
+}
198
+
139 199
 /* -------- Helper functions -------- */
140 200
 
141 201
 static void free_notifier(notifier_t *info)
... ...
@@ -188,6 +248,8 @@ notifier_domain_t *create_notifier_domain(const str_t *name)
188 248
 	if (d) {
189 249
 		d->first_package = NULL;
190 250
 		d->last_package = NULL;
251
+		d->first_content_type = NULL;
252
+		d->last_content_type = NULL;
191 253
 		if (str_dup(&d->name, name) < 0) {
192 254
 			cds_free(d);
193 255
 			ERROR_LOG("can't allocate memory\n");
... ...
@@ -206,6 +268,7 @@ notifier_domain_t *create_notifier_domain(const str_t *name)
206 268
 void destroy_notifier_domain(notifier_domain_t *domain)
207 269
 {
208 270
 	notifier_package_t *p, *n;
271
+	qsa_content_type_t *c, *nc;
209 272
 
210 273
 	/* this function is always called only if no only one reference
211 274
 	 * to domain exists (see domain maintainer), this should mean, that 
... ...
@@ -223,6 +286,14 @@ void destroy_notifier_domain(notifier_domain_t *domain)
223 286
 	domain->first_package = NULL;
224 287
 	domain->last_package = NULL;
225 288
 	
289
+	c = domain->first_content_type;
290
+	while (c) {
291
+		nc = c->next;
292
+		destroy_content_type(c);
293
+	}
294
+	domain->first_content_type = NULL;
295
+	domain->last_content_type = NULL;
296
+	
226 297
 	unlock_notifier_domain(domain);
227 298
 	
228 299
 	str_free_content(&domain->name);
... ...
@@ -427,9 +498,8 @@ void unsubscribe(notifier_domain_t *domain, subscription_t *s)
427 498
 /* void notify_subscriber(subscription_t *s, mq_message_t *msg) */
428 499
 int notify_subscriber(subscription_t *s, 
429 500
 		notifier_t *n,
430
-		int data_type, 
501
+		qsa_content_type_t *content_type, 
431 502
 		void *data, 
432
-		destroy_function_f data_destroy,
433 503
 		qsa_subscription_status_t status)
434 504
 {
435 505
 	int ok = 1;
... ...
@@ -442,6 +512,11 @@ int notify_subscriber(subscription_t *s,
442 512
 		ok = 0;
443 513
 	}
444 514
 	
515
+	if (!content_type) {
516
+		ERROR_LOG("BUG: content type not given! Possible memory leaks!\n");
517
+		return -1;
518
+	}
519
+	
445 520
 	if (ok) {
446 521
 		msg = create_message_ex(sizeof(client_notify_info_t));
447 522
 		if (!msg) {
... ...
@@ -455,10 +530,9 @@ int notify_subscriber(subscription_t *s,
455 530
 		info = (client_notify_info_t*)msg->data;
456 531
 		
457 532
 		info->subscription = s;
458
-		info->data_type = data_type;
533
+		info->content_type = content_type;
459 534
 		info->data = data;
460 535
 		info->status = status;
461
-		info->destroy_func = data_destroy;
462 536
 		
463 537
 		lock_subscription_data(s);
464 538
 		if (s->dst) {
... ...
@@ -471,7 +545,7 @@ int notify_subscriber(subscription_t *s,
471 545
 	if (!sent) {
472 546
 		/* free unsent messages */
473 547
 		if (msg) free_message(msg);
474
-		else if (data_destroy && data) data_destroy(data);
548
+		else if (data) content_type->destroy_func(data);
475 549
 	}
476 550
 
477 551
 	if (ok) return 0;
... ...
@@ -485,6 +559,9 @@ void free_client_notify_info_content(client_notify_info_t *info)
485 559
 	str_free_content(&info->record_id);
486 560
 	str_free_content(&info->notifier); */
487 561
 	DEBUG_LOG(" ... calling destroy func on data\n");
488
-	if (info->destroy_func) info->destroy_func(info->data);
562
+	if (info->content_type) {
563
+		if (info->data) info->content_type->destroy_func(info->data);
564
+	}
565
+	else ERR("BUG: content-type not given! Possible memory leaks!\n");
489 566
 }
490 567
 
... ...
@@ -66,6 +66,13 @@ typedef int (*server_subscribe_func)(notifier_t *n, subscription_t *subscription
66 66
 
67 67
 typedef void (*server_unsubscribe_func)(notifier_t *n, subscription_t *subscription);
68 68
 
69
+typedef struct _qsa_content_type_t {
70
+	struct _qsa_content_type_t *next, *prev;
71
+	str_t name;
72
+	destroy_function_f destroy_func;
73
+	char buf[1]; /* buffer for name allocation together with the structure */
74
+} qsa_content_type_t;
75
+
69 76
 /** Internal structure storing registered notifiers. */
70 77
 struct _notifier_t {
71 78
 	server_subscribe_func subscribe;
... ...
@@ -89,6 +96,7 @@ struct _notifier_domain_t {
89 96
 	cds_mutex_t data_mutex; /* mutex for locking standalone subscription data, may be changed to mutex pool */
90 97
 	str_t name;
91 98
 	notifier_package_t *first_package, *last_package;
99
+	qsa_content_type_t *first_content_type, *last_content_type;
92 100
 	reference_counter_data_t ref;
93 101
 };
94 102
 
... ...
@@ -102,6 +110,10 @@ notifier_domain_t *create_notifier_domain(const str_t *name);
102 110
  * if there are any notifiers, they are unregistered. */
103 111
 void destroy_notifier_domain(notifier_domain_t *domain);
104 112
 
113
+qsa_content_type_t *register_content_type(notifier_domain_t *d, 
114
+		const str_t *name,
115
+		destroy_function_f destroy_func);
116
+
105 117
 #define lock_notifier_domain(d) cds_mutex_lock(&(d->mutex))
106 118
 #define unlock_notifier_domain(d) cds_mutex_unlock(&(d->mutex))
107 119
 
... ...
@@ -30,11 +30,6 @@
30 30
 #include <cds/ptr_vector.h>
31 31
 #include <time.h>
32 32
 
33
-/* document types processed by presence subscribers
34
- * and generated by presence notifiers */
35
-#define PRESENTITY_INFO_TYPE	1	/* structure presentity_info_t */
36
-#define PRESENTITY_RAW_INFO		2	/* raw document */
37
-
38 33
 typedef struct _presence_note_t {
39 34
 	str_t value;
40 35
 	str_t lang;
... ...
@@ -119,4 +114,9 @@ void free_presence_note(presence_note_t *n);
119 114
 
120 115
 person_t *create_person(const str_t *element, const str_t *id);
121 116
 
117
+/* content type names usable with QSA */
118
+#define CT_PRESENCE_INFO    "structured/presence-info" /* uses presence_info_t */
119
+#define CT_PIDF_XML         "application/pidf+xml" /* carries XML */
120
+#define CT_RAW              "raw" /* uses raw_presence_info_t */
121
+
122 122
 #endif