general clean up
[claws.git] / src / addrquery.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2003 Match Grun
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 2 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, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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  * Create new address query.
49  * \return Initialized address query object.
50  */
51 QueryRequest *reqreq_create( void ) {
52         QueryRequest *req;
53
54         req = g_new0( QueryRequest, 1 );
55         req->queryID = 0;
56         req->searchType = ADDRSEARCH_NONE;
57         req->searchTerm = NULL;
58         req->callBackEnd = NULL;
59         req->callBackEntry = NULL;
60         req->queryList = NULL;
61         return req;
62 }
63
64 /**
65  * Clear the query.
66  * \param req Request query object.
67  */
68 void qryreq_clear( QueryRequest *req ) {
69         GList *node;
70
71         g_return_if_fail( req != NULL );
72         g_free( req->searchTerm );
73         req->queryID = 0;
74         req->searchType = ADDRSEARCH_NONE;
75         req->searchTerm = NULL;
76         req->callBackEnd = NULL;
77         req->callBackEntry = NULL;
78
79         /* Empty the list */
80         node = req->queryList;
81         while( node ) {
82                 node->data = NULL;
83                 node = g_list_next( node );
84         }
85         g_list_free( req->queryList );
86         req->queryList = NULL;
87 }
88
89 /**
90  * Free query.
91  * \param req Request query object.
92  */
93 void qryreq_free( QueryRequest *req ) {
94         g_return_if_fail( req != NULL );
95         qryreq_clear( req );
96         g_free( req );
97 }
98
99 /**
100  * Specify search type.
101  * \param req   Request query object.
102  * \param value Type.
103  */
104 void qryreq_set_search_type( QueryRequest *req, const AddrSearchType value ) {
105         g_return_if_fail( req != NULL );
106         req->searchType = value;
107 }
108
109 /**
110  * Specify search term to be used.
111  * \param req   Request query object.
112  * \param value Search term.
113  */
114 void qryreq_set_search_term( QueryRequest *req, const gchar *value ) {
115         req->searchTerm = mgu_replace_string( req->searchTerm, value );
116         g_return_if_fail( req != NULL );
117         g_strstrip( req->searchTerm );
118 }
119
120 /**
121  * Add address query object to request.
122  * \param req  Request query object.
123  * \param aqo  Address query object that performs the search.
124  */
125 void qryreq_add_query( QueryRequest *req, AddrQueryObject *aqo ) {
126         g_return_if_fail( req != NULL );
127         g_return_if_fail( aqo != NULL );
128         req->queryList = g_list_append( req->queryList, aqo );
129 }
130
131 /**
132  * Display object to specified stream.
133  * \param req    Request query object.
134  * \param stream Output stream.
135  */
136 void qryreq_print( const QueryRequest *req, FILE *stream ) {
137         GList *node;
138         g_return_if_fail( req != NULL );
139
140         fprintf( stream, "QueryRequest:\n" );
141         fprintf( stream, "     queryID: %d\n",   req->queryID );
142         fprintf( stream, "  searchType: %d\n",   req->searchType );
143         fprintf( stream, "  searchTerm: '%s'\n", req->searchTerm );
144         node = req->queryList;
145         while( node ) {
146                 AddrQueryObject *aqo = node->data;
147                 fprintf( stream, "    --- type: %d\n", aqo->queryType );
148                 node = g_list_next( node );
149         }
150 }
151
152 /**
153  * Add query to list.
154  *
155  * \param searchTerm    Search term. A private copy will be made.
156  * \param callBackEnd   Callback function that will be called when query
157  *                      terminates.
158  * \param callBackEntry Callback function that will be called after each
159  *                      address entry has been read.
160  * \return Initialize query request object.                     
161  */
162 QueryRequest *qrymgr_add_request(
163         const gchar *searchTerm, void *callBackEnd, void *callBackEntry )
164 {
165         QueryRequest *req;
166
167         req = g_new0( QueryRequest, 1 );
168         req->searchTerm = g_strdup( searchTerm );
169         req->callBackEnd = callBackEnd;
170         req->callBackEntry = callBackEntry;
171         req->timeStart = time( NULL );
172         req->queryList = NULL;
173
174         /* Insert in head of list */
175         pthread_mutex_lock( & _requestListMutex_ );
176         req->queryID = ++_currentQueryID_;
177         _requestList_ = g_list_prepend( _requestList_, req );
178         pthread_mutex_unlock( & _requestListMutex_ );
179
180         return req;
181 }
182
183 /**
184  * Find query in list.
185  * \param  queryID ID of query to find.
186  * \return Query object, or <i>NULL</i> if not found.
187  */
188 QueryRequest *qrymgr_find_request( const gint queryID ) {
189         QueryRequest *req;
190         QueryRequest *q;
191         GList *node;
192
193         pthread_mutex_lock( & _requestListMutex_ );
194         req = NULL;
195         node = _requestList_;
196         while( node ) {
197                 q = node->data;
198                 if( q->queryID == queryID ) {
199                         req = q;
200                         break;
201                 }
202                 node = g_list_next( node );
203         }
204         pthread_mutex_unlock( & _requestListMutex_ );
205
206         return req;
207 }
208
209 /**
210  * Delete specified query.
211  * \param  queryID ID of query to retire.
212  */
213 void qrymgr_delete_request( const gint queryID ) {
214         QueryRequest *req;
215         GList *node, *nf;
216
217         pthread_mutex_lock( & _requestListMutex_ );
218
219         /* Find node */
220         nf = NULL;
221         node = _requestList_;
222         while( node ) {
223                 req = node->data;
224                 if( req->queryID == queryID ) {
225                         nf = node;
226                         qryreq_free( req );
227                         break;
228                 }
229                 node = g_list_next( node );
230         }
231
232         /* Free link element and associated query */
233         if( nf ) {
234                 _requestList_ = g_list_remove_link( _requestList_, nf );
235                 g_list_free_1( nf );
236         }
237
238         pthread_mutex_unlock( & _requestListMutex_ );
239 }
240
241 /**
242  * Initialize query manager.
243  */
244 void qrymgr_initialize( void ) {
245         _requestList_ = NULL;
246 }
247
248 /**
249  * Free all queries.
250  */
251 static void qrymgr_free_all_request( void ) {
252         QueryRequest *req;
253         GList *node;
254
255         pthread_mutex_lock( & _requestListMutex_ );
256         node = _requestList_;
257         while( node ) {
258                 req = node->data;
259                 qryreq_free( req );
260                 node->data = NULL;
261                 node = g_list_next( node );
262         }
263         g_list_free( _requestList_ );
264         _requestList_ = NULL;
265         pthread_mutex_unlock( & _requestListMutex_ );
266 }
267
268 /**
269  * Teardown query manager.
270  */
271 void qrymgr_teardown( void ) {
272         qrymgr_free_all_request();
273 }
274
275 /**
276  * Display all queries to specified stream.
277  * \param stream Output stream.
278  */
279 void qrymgr_print( FILE *stream ) {
280         QueryRequest *req;
281         GList *node;
282
283         pthread_mutex_lock( & _requestListMutex_ );
284         fprintf( stream, "=== Query Manager ===\n" );
285         node = _requestList_;
286         while( node ) {
287                 req = node->data;
288                 qryreq_print( req, stream );
289                 fprintf( stream, "---\n" );
290                 node = g_list_next( node );
291         }
292         pthread_mutex_unlock( & _requestListMutex_ );
293 }
294
295 /*
296 * End of Source.
297 */
298
299