2008-03-12 [paul] 3.3.1cvs21
[claws.git] / src / addrquery.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2003-2007 Match Grun and the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * 
18  */
19
20 /*
21  * Functions to define an address query (a request).
22  */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <glib.h>
27 #include <pthread.h>
28
29 #include "mgutils.h"
30 #include "addrquery.h"
31
32 /**
33  * Query list for tracking current queries.
34  */
35 static GList *_requestList_ = NULL;
36
37 /**
38  * Mutex to protect list from multiple threads.
39  */
40 static pthread_mutex_t _requestListMutex_ = PTHREAD_MUTEX_INITIALIZER;
41
42 /**
43  * Current query ID. This is incremented for each query request created.
44  */
45 static gint _currentQueryID_ = 0;
46
47 /**
48  * Clear the query.
49  * \param req Request query object.
50  */
51 static void qryreq_clear( QueryRequest *req ) {
52         GList *node;
53
54         g_return_if_fail( req != NULL );
55         g_free( req->searchTerm );
56         req->queryID = 0;
57         req->searchType = ADDRSEARCH_NONE;
58         req->searchTerm = NULL;
59         req->callBackEnd = NULL;
60         req->callBackEntry = NULL;
61
62         /* Empty the list */
63         node = req->queryList;
64         while( node ) {
65                 node->data = NULL;
66                 node = g_list_next( node );
67         }
68         g_list_free( req->queryList );
69         req->queryList = NULL;
70 }
71
72 /**
73  * Free query.
74  * \param req Request query object.
75  */
76 static void qryreq_free( QueryRequest *req ) {
77         g_return_if_fail( req != NULL );
78         qryreq_clear( req );
79         g_free( req );
80 }
81
82 /**
83  * Specify search type.
84  * \param req   Request query object.
85  * \param value Type.
86  */
87 void qryreq_set_search_type( QueryRequest *req, const AddrSearchType value ) {
88         g_return_if_fail( req != NULL );
89         req->searchType = value;
90 }
91
92 /**
93  * Add address query object to request.
94  * \param req  Request query object.
95  * \param aqo  Address query object that performs the search.
96  */
97 void qryreq_add_query( QueryRequest *req, AddrQueryObject *aqo ) {
98         g_return_if_fail( req != NULL );
99         g_return_if_fail( aqo != NULL );
100         req->queryList = g_list_append( req->queryList, aqo );
101 }
102
103 /**
104  * Add query to list.
105  *
106  * \param searchTerm    Search term. A private copy will be made.
107  * \param callBackEnd   Callback function that will be called when query
108  *                      terminates.
109  * \param callBackEntry Callback function that will be called after each
110  *                      address entry has been read.
111  * \return Initialize query request object.                     
112  */
113 QueryRequest *qrymgr_add_request(
114         const gchar *searchTerm, void *callBackEnd, void *callBackEntry )
115 {
116         QueryRequest *req;
117
118         req = g_new0( QueryRequest, 1 );
119         req->searchTerm = g_strdup( searchTerm );
120         req->callBackEnd = callBackEnd;
121         req->callBackEntry = callBackEntry;
122         req->timeStart = time( NULL );
123         req->queryList = NULL;
124
125         /* Insert in head of list */
126         pthread_mutex_lock( & _requestListMutex_ );
127         req->queryID = ++_currentQueryID_;
128         _requestList_ = g_list_prepend( _requestList_, req );
129         pthread_mutex_unlock( & _requestListMutex_ );
130
131         return req;
132 }
133
134 /**
135  * Find query in list.
136  * \param  queryID ID of query to find.
137  * \return Query object, or <i>NULL</i> if not found.
138  */
139 QueryRequest *qrymgr_find_request( const gint queryID ) {
140         QueryRequest *req;
141         QueryRequest *q;
142         GList *node;
143
144         pthread_mutex_lock( & _requestListMutex_ );
145         req = NULL;
146         node = _requestList_;
147         while( node ) {
148                 q = node->data;
149                 if( q->queryID == queryID ) {
150                         req = q;
151                         break;
152                 }
153                 node = g_list_next( node );
154         }
155         pthread_mutex_unlock( & _requestListMutex_ );
156
157         return req;
158 }
159
160 /**
161  * Delete specified query.
162  * \param  queryID ID of query to retire.
163  */
164 void qrymgr_delete_request( const gint queryID ) {
165         QueryRequest *req;
166         GList *node, *nf;
167
168         pthread_mutex_lock( & _requestListMutex_ );
169
170         /* Find node */
171         nf = NULL;
172         node = _requestList_;
173         while( node ) {
174                 req = node->data;
175                 if( req->queryID == queryID ) {
176                         nf = node;
177                         qryreq_free( req );
178                         break;
179                 }
180                 node = g_list_next( node );
181         }
182
183         /* Free link element and associated query */
184         if( nf ) {
185                 _requestList_ = g_list_remove_link( _requestList_, nf );
186                 g_list_free_1( nf );
187         }
188
189         pthread_mutex_unlock( & _requestListMutex_ );
190 }
191
192 /**
193  * Initialize query manager.
194  */
195 void qrymgr_initialize( void ) {
196         _requestList_ = NULL;
197 }
198
199 /**
200  * Free all queries.
201  */
202 static void qrymgr_free_all_request( void ) {
203         QueryRequest *req;
204         GList *node;
205
206         pthread_mutex_lock( & _requestListMutex_ );
207         node = _requestList_;
208         while( node ) {
209                 req = node->data;
210                 qryreq_free( req );
211                 node->data = NULL;
212                 node = g_list_next( node );
213         }
214         g_list_free( _requestList_ );
215         _requestList_ = NULL;
216         pthread_mutex_unlock( & _requestListMutex_ );
217 }
218
219 /**
220  * Teardown query manager.
221  */
222 void qrymgr_teardown( void ) {
223         qrymgr_free_all_request();
224 }
225
226 /*
227 * End of Source.
228 */
229
230