]> git.meshlink.io Git - catta/blob - avahi-core/rrlist.c
308ecd1be5501e56ae5e3a66c8a7d6f501a7d011
[catta] / avahi-core / rrlist.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <assert.h>
28
29 #include <avahi-common/llist.h>
30 #include <avahi-common/malloc.h>
31
32 #include "rrlist.h"
33 #include "log.h"
34
35 typedef struct AvahiRecordListItem AvahiRecordListItem;
36
37 struct AvahiRecordListItem {
38     int read;
39     AvahiRecord *record;
40     int unicast_response;
41     int flush_cache;
42     int auxiliary;
43     AVAHI_LLIST_FIELDS(AvahiRecordListItem, items);
44 };
45
46 struct AvahiRecordList {
47     AVAHI_LLIST_HEAD(AvahiRecordListItem, read);
48     AVAHI_LLIST_HEAD(AvahiRecordListItem, unread);
49
50     int all_flush_cache;
51 };
52
53 AvahiRecordList *avahi_record_list_new(void) {
54     AvahiRecordList *l;
55
56     if (!(l = avahi_new(AvahiRecordList, 1))) {
57         avahi_log_error("avahi_new() failed.");
58         return NULL;
59     }
60
61     AVAHI_LLIST_HEAD_INIT(AvahiRecordListItem, l->read);
62     AVAHI_LLIST_HEAD_INIT(AvahiRecordListItem, l->unread);
63
64     l->all_flush_cache = 1;
65     return l;
66 }
67
68 void avahi_record_list_free(AvahiRecordList *l) {
69     assert(l);
70
71     avahi_record_list_flush(l);
72     avahi_free(l);
73 }
74
75 static void item_free(AvahiRecordList *l, AvahiRecordListItem *i) {
76     assert(l);
77     assert(i);
78
79     if (i->read)
80         AVAHI_LLIST_REMOVE(AvahiRecordListItem, items, l->read, i);
81     else
82         AVAHI_LLIST_REMOVE(AvahiRecordListItem, items, l->unread, i);
83
84     avahi_record_unref(i->record);
85     avahi_free(i);
86 }
87
88 void avahi_record_list_flush(AvahiRecordList *l) {
89     assert(l);
90
91     while (l->read)
92         item_free(l, l->read);
93     while (l->unread)
94         item_free(l, l->unread);
95
96     l->all_flush_cache = 1;
97 }
98
99 AvahiRecord* avahi_record_list_next(AvahiRecordList *l, int *ret_flush_cache, int *ret_unicast_response, int *ret_auxiliary) {
100     AvahiRecord *r;
101     AvahiRecordListItem *i;
102
103     if (!(i = l->unread))
104         return NULL;
105
106     assert(!i->read);
107
108     r = avahi_record_ref(i->record);
109     if (ret_unicast_response)
110         *ret_unicast_response = i->unicast_response;
111     if (ret_flush_cache)
112         *ret_flush_cache = i->flush_cache;
113     if (ret_auxiliary)
114         *ret_auxiliary = i->auxiliary;
115
116     AVAHI_LLIST_REMOVE(AvahiRecordListItem, items, l->unread, i);
117     AVAHI_LLIST_PREPEND(AvahiRecordListItem, items, l->read, i);
118
119     i->read = 1;
120
121     return r;
122 }
123
124 static AvahiRecordListItem *get(AvahiRecordList *l, AvahiRecord *r) {
125     AvahiRecordListItem *i;
126
127     assert(l);
128     assert(r);
129
130     for (i = l->read; i; i = i->items_next)
131         if (avahi_record_equal_no_ttl(i->record, r))
132             return i;
133
134     for (i = l->unread; i; i = i->items_next)
135         if (avahi_record_equal_no_ttl(i->record, r))
136             return i;
137
138     return NULL;
139 }
140
141 void avahi_record_list_push(AvahiRecordList *l, AvahiRecord *r, int flush_cache, int unicast_response, int auxiliary) {
142     AvahiRecordListItem *i;
143
144     assert(l);
145     assert(r);
146
147     if (get(l, r))
148         return;
149
150     if (!(i = avahi_new(AvahiRecordListItem, 1))) {
151         avahi_log_error("avahi_new() failed.");
152         return;
153     }
154
155     i->unicast_response = unicast_response;
156     i->flush_cache = flush_cache;
157     i->auxiliary = auxiliary;
158     i->record = avahi_record_ref(r);
159     i->read = 0;
160
161     l->all_flush_cache = l->all_flush_cache && flush_cache;
162
163     AVAHI_LLIST_PREPEND(AvahiRecordListItem, items, l->unread, i);
164 }
165
166 void avahi_record_list_drop(AvahiRecordList *l, AvahiRecord *r) {
167     AvahiRecordListItem *i;
168
169     assert(l);
170     assert(r);
171
172     if (!(i = get(l, r)))
173         return;
174
175     item_free(l, i);
176 }
177
178 int avahi_record_list_is_empty(AvahiRecordList *l) {
179     assert(l);
180
181     return !l->unread && !l->read;
182 }
183
184 int avahi_record_list_all_flush_cache(AvahiRecordList *l) {
185     assert(l);
186
187     /* Return TRUE if all entries in this list have flush_cache set */
188
189     return l->all_flush_cache;
190 }