2007-08-09 [wwp] 2.10.0cvs108
[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 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 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  * Specify search term to be used.
94  * \param req   Request query object.
95  * \param value Search term.
96  */
97 void qryreq_set_search_term( QueryRequest *req, const gchar *value ) {
98         req->searchTerm = mgu_replace_string( req->searchTerm, value );
99         g_return_if_fail( req != NULL );
100         g_strstrip( req->searchTerm );
101 }
102
103 /**
104  * Add address query object to request.
105  * \param req  Request query object.
106  * \param aqo  Address query object that performs the search.
107  */
108 void qryreq_add_query( QueryRequest *req, AddrQueryObject *aqo ) {
109         g_return_if_fail( req != NULL );
110         g_return_if_fail( aqo != NULL );
111         req->queryList = g_list_append( req->queryList, aqo );
112 }
113
114 /**
115  * Display object to specified stream.
116  * \param req    Request query object.
117  * \param stream Output stream.
118  */
119 void qryreq_print( const QueryRequest *req, FILE *stream ) {
120         GList *node;
121         g_return_if_fail( req != NULL );
122
123         fprintf( stream, "QueryRequest:\n" );
124         fprintf( stream, "     queryID: %d\n",   req->queryID );
125         fprintf( stream, "  searchType: %d\n",   req->searchType );
126         fprintf( stream, "  searchTerm: '%s'\n", req->searchTerm );
127         node = req->queryList;
128         while( node ) {
129                 AddrQueryObject *aqo = node->data;
130                 fprintf( stream, "    --- type: %d\n", aqo->queryType );
131                 node = g_list_next( node );
132         }
133 }
134
135 /**
136  * Add query to list.
137  *
138  * \param searchTerm    Search term. A private copy will be made.
139  * \param callBackEnd   Callback function that will be called when query
140  *                      terminates.
141  * \param callBackEntry Callback function that will be called after each
142  *                      address entry has been read.
143  * \return Initialize query request object.                     
144  */
145 QueryRequest *qrymgr_add_request(
146         const gchar *searchTerm, void *callBackEnd, void *callBackEntry )
147 {
148         QueryRequest *req;
149
150         req = g_new0( QueryRequest, 1 );
151         req->searchTerm = g_strdup( searchTerm );
152         req->callBackEnd = callBackEnd;
153         req->callBackEntry = callBackEntry;
154         req->timeStart = time( NULL );
155         req->queryList = NULL;
156
157         /* Insert in head of list */
158         pthread_mutex_lock( & _requestListMutex_ );
159         req->queryID = ++_currentQueryID_;
160         _requestList_ = g_list_prepend( _requestList_, req );
161         pthread_mutex_unlock( & _requestListMutex_ );
162
163         return req;
164 }
165
166 /**
167  * Find query in list.
168  * \param  queryID ID of query to find.
169  * \return Query object, or <i>NULL</i> if not found.
170  */
171 QueryRequest *qrymgr_find_request( const gint queryID ) {
172         QueryRequest *req;
173         QueryRequest *q;
174         GList *node;
175
176         pthread_mutex_lock( & _requestListMutex_ );
177         req = NULL;
178         node = _requestList_;
179         while( node ) {
180                 q = node->data;
181                 if( q->queryID == queryID ) {
182                         req = q;
183                         break;
184                 }
185                 node = g_list_next( node );
186         }
187         pthread_mutex_unlock( & _requestListMutex_ );
188
189         return req;
190 }
191
192 /**
193  * Delete specified query.
194  * \param  queryID ID of query to retire.
195  */
196 void qrymgr_delete_request( const gint queryID ) {
197         QueryRequest *req;
198         GList *node, *nf;
199
200         pthread_mutex_lock( & _requestListMutex_ );
201
202         /* Find node */
203         nf = NULL;
204         node = _requestList_;
205         while( node ) {
206                 req = node->data;
207                 if( req->queryID == queryID ) {
208                         nf = node;
209                         qryreq_free( req );
210                         break;
211                 }
212                 node = g_list_next( node );
213         }
214
215         /* Free link element and associated query */
216         if( nf ) {
217                 _requestList_ = g_list_remove_link( _requestList_, nf );
218                 g_list_free_1( nf );
219         }
220
221         pthread_mutex_unlock( & _requestListMutex_ );
222 }
223
224 /**
225  * Initialize query manager.
226  */
227 void qrymgr_initialize( void ) {
228         _requestList_ = NULL;
229 }
230
231 /**
232  * Free all queries.
233  */
234 static void qrymgr_free_all_request( void ) {
235         QueryRequest *req;
236         GList *node;
237
238         pthread_mutex_lock( & _requestListMutex_ );
239         node = _requestList_;
240         while( node ) {
241                 req = node->data;
242                 qryreq_free( req );
243                 node->data = NULL;
244                 node = g_list_next( node );
245         }
246         g_list_free( _requestList_ );
247         _requestList_ = NULL;
248         pthread_mutex_unlock( & _requestListMutex_ );
249 }
250
251 /**
252  * Teardown query manager.
253  */
254 void qrymgr_teardown( void ) {
255         qrymgr_free_all_request();
256 }
257
258 /**
259  * Display all queries to specified stream.
260  * \param stream Output stream.
261  */
262 void qrymgr_print( FILE *stream ) {
263         QueryRequest *req;
264         GList *node;
265
266         pthread_mutex_lock( & _requestListMutex_ );
267         fprintf( stream, "=== Query Manager ===\n" );
268         node = _requestList_;
269         while( node ) {
270                 req = node->data;
271                 qryreq_print( req, stream );
272                 fprintf( stream, "---\n" );
273                 node = g_list_next( node );
274         }
275         pthread_mutex_unlock( & _requestListMutex_ );
276 }
277
278 /*
279 * End of Source.
280 */
281
282