Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/lib-storage/mail-sort.c @ 924:4f697dde0fca HEAD
THREAD=REFERENCES implementation. Doesn't crash, but I'm not sure how
correct replies it produces :)
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 08 Jan 2003 22:49:51 +0200 |
parents | fd8888f6f037 |
children | ceb3ea5e1a2a |
comparison
equal
deleted
inserted
replaced
923:b71883ef0247 | 924:4f697dde0fca |
---|---|
12 | 12 |
13 struct mail_sort_context { | 13 struct mail_sort_context { |
14 enum mail_sort_type output[MAX_SORT_PROGRAM_SIZE]; | 14 enum mail_sort_type output[MAX_SORT_PROGRAM_SIZE]; |
15 enum mail_sort_type common_mask; | 15 enum mail_sort_type common_mask; |
16 | 16 |
17 struct mail_sort_funcs funcs; | 17 const struct mail_sort_callbacks *callbacks; |
18 void *func_context; | 18 void *func_context; |
19 | 19 |
20 buffer_t *sort_buffer; | 20 buffer_t *sort_buffer; |
21 pool_t temp_pool; | 21 pool_t temp_pool; |
22 | 22 |
74 return mask; | 74 return mask; |
75 } | 75 } |
76 | 76 |
77 struct mail_sort_context * | 77 struct mail_sort_context * |
78 mail_sort_init(const enum mail_sort_type *input, enum mail_sort_type *output, | 78 mail_sort_init(const enum mail_sort_type *input, enum mail_sort_type *output, |
79 struct mail_sort_funcs funcs, void *context) | 79 const struct mail_sort_callbacks *callbacks, void *context) |
80 { | 80 { |
81 struct mail_sort_context *ctx; | 81 struct mail_sort_context *ctx; |
82 enum mail_sort_type norm_input[MAX_SORT_PROGRAM_SIZE]; | 82 enum mail_sort_type norm_input[MAX_SORT_PROGRAM_SIZE]; |
83 enum mail_sort_type norm_output[MAX_SORT_PROGRAM_SIZE]; | 83 enum mail_sort_type norm_output[MAX_SORT_PROGRAM_SIZE]; |
84 buffer_t *buf; | 84 buffer_t *buf; |
108 ctx->sort_buffer = buffer_create_dynamic(system_pool, | 108 ctx->sort_buffer = buffer_create_dynamic(system_pool, |
109 128 * sizeof(unsigned int), | 109 128 * sizeof(unsigned int), |
110 (size_t)-1); | 110 (size_t)-1); |
111 | 111 |
112 ctx->temp_pool = pool_alloconly_create("Sort", 8192); | 112 ctx->temp_pool = pool_alloconly_create("Sort", 8192); |
113 ctx->funcs = funcs; | 113 ctx->callbacks = callbacks; |
114 ctx->func_context = context; | 114 ctx->func_context = context; |
115 return ctx; | 115 return ctx; |
116 } | 116 } |
117 | 117 |
118 void mail_sort_deinit(struct mail_sort_context *ctx) | 118 void mail_sort_deinit(struct mail_sort_context *ctx) |
149 return s2 == NULL ? 0 : -1; | 149 return s2 == NULL ? 0 : -1; |
150 if (s2 == NULL) | 150 if (s2 == NULL) |
151 return 1; | 151 return 1; |
152 | 152 |
153 p_clear(pool); | 153 p_clear(pool); |
154 ret = strcmp(imap_get_base_subject_cased(pool, s1), | 154 ret = strcmp(imap_get_base_subject_cased(pool, s1, NULL), |
155 imap_get_base_subject_cased(pool, s2)); | 155 imap_get_base_subject_cased(pool, s2, NULL)); |
156 return ret; | 156 return ret; |
157 } | 157 } |
158 | 158 |
159 static void mail_sort_check_flush(struct mail_sort_context *ctx, | 159 static void mail_sort_check_flush(struct mail_sort_context *ctx, |
160 unsigned int id) | 160 unsigned int id) |
163 time_t t; | 163 time_t t; |
164 uoff_t size; | 164 uoff_t size; |
165 int changed = FALSE; | 165 int changed = FALSE; |
166 | 166 |
167 if (ctx->common_mask & MAIL_SORT_ARRIVAL) { | 167 if (ctx->common_mask & MAIL_SORT_ARRIVAL) { |
168 t = ctx->funcs.input_time(MAIL_SORT_ARRIVAL, id, | 168 t = ctx->callbacks->input_time(MAIL_SORT_ARRIVAL, id, |
169 ctx->func_context); | 169 ctx->func_context); |
170 if (t != ctx->last_arrival) { | 170 if (t != ctx->last_arrival) { |
171 ctx->last_arrival = t; | 171 ctx->last_arrival = t; |
172 changed = TRUE; | 172 changed = TRUE; |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 if (ctx->common_mask & MAIL_SORT_CC) { | 176 if (ctx->common_mask & MAIL_SORT_CC) { |
177 str = ctx->funcs.input_str(MAIL_SORT_CC, id, | 177 str = ctx->callbacks->input_str(MAIL_SORT_CC, id, |
178 ctx->func_context); | 178 ctx->func_context); |
179 if (addr_strcmp(str, ctx->last_cc) != 0) { | 179 if (addr_strcmp(str, ctx->last_cc) != 0) { |
180 i_free(ctx->last_cc); | 180 i_free(ctx->last_cc); |
181 ctx->last_cc = i_strdup(str); | 181 ctx->last_cc = i_strdup(str); |
182 changed = TRUE; | 182 changed = TRUE; |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 if (ctx->common_mask & MAIL_SORT_DATE) { | 186 if (ctx->common_mask & MAIL_SORT_DATE) { |
187 t = ctx->funcs.input_time(MAIL_SORT_DATE, id, | 187 t = ctx->callbacks->input_time(MAIL_SORT_DATE, id, |
188 ctx->func_context); | 188 ctx->func_context); |
189 if (t != ctx->last_date) { | 189 if (t != ctx->last_date) { |
190 ctx->last_date = t; | 190 ctx->last_date = t; |
191 changed = TRUE; | 191 changed = TRUE; |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 if (ctx->common_mask & MAIL_SORT_FROM) { | 195 if (ctx->common_mask & MAIL_SORT_FROM) { |
196 str = ctx->funcs.input_str(MAIL_SORT_FROM, id, | 196 str = ctx->callbacks->input_str(MAIL_SORT_FROM, id, |
197 ctx->func_context); | 197 ctx->func_context); |
198 if (addr_strcmp(str, ctx->last_from) != 0) { | 198 if (addr_strcmp(str, ctx->last_from) != 0) { |
199 i_free(ctx->last_from); | 199 i_free(ctx->last_from); |
200 ctx->last_from = i_strdup(str); | 200 ctx->last_from = i_strdup(str); |
201 changed = TRUE; | 201 changed = TRUE; |
202 } | 202 } |
203 } | 203 } |
204 | 204 |
205 if (ctx->common_mask & MAIL_SORT_SIZE) { | 205 if (ctx->common_mask & MAIL_SORT_SIZE) { |
206 size = ctx->funcs.input_time(MAIL_SORT_SIZE, id, | 206 size = ctx->callbacks->input_time(MAIL_SORT_SIZE, id, |
207 ctx->func_context); | 207 ctx->func_context); |
208 if (size != ctx->last_size) { | 208 if (size != ctx->last_size) { |
209 ctx->last_size = size; | 209 ctx->last_size = size; |
210 changed = TRUE; | 210 changed = TRUE; |
211 } | 211 } |
212 } | 212 } |
213 | 213 |
214 if (ctx->common_mask & MAIL_SORT_SUBJECT) { | 214 if (ctx->common_mask & MAIL_SORT_SUBJECT) { |
215 str = ctx->funcs.input_str(MAIL_SORT_SUBJECT, id, | 215 str = ctx->callbacks->input_str(MAIL_SORT_SUBJECT, id, |
216 ctx->func_context); | 216 ctx->func_context); |
217 if (subject_cmp(ctx->temp_pool, str, ctx->last_subject) != 0) { | 217 if (subject_cmp(ctx->temp_pool, str, ctx->last_subject) != 0) { |
218 i_free(ctx->last_subject); | 218 i_free(ctx->last_subject); |
219 ctx->last_subject = i_strdup(str); | 219 ctx->last_subject = i_strdup(str); |
220 changed = TRUE; | 220 changed = TRUE; |
221 } | 221 } |
222 } | 222 } |
223 | 223 |
224 if (ctx->common_mask & MAIL_SORT_TO) { | 224 if (ctx->common_mask & MAIL_SORT_TO) { |
225 str = ctx->funcs.input_str(MAIL_SORT_TO, id, | 225 str = ctx->callbacks->input_str(MAIL_SORT_TO, id, |
226 ctx->func_context); | 226 ctx->func_context); |
227 if (addr_strcmp(str, ctx->last_to) != 0) { | 227 if (addr_strcmp(str, ctx->last_to) != 0) { |
228 i_free(ctx->last_to); | 228 i_free(ctx->last_to); |
229 ctx->last_to = i_strdup(str); | 229 ctx->last_to = i_strdup(str); |
230 changed = TRUE; | 230 changed = TRUE; |
231 } | 231 } |
247 | 247 |
248 static int mail_sort_qsort_func(const void *p1, const void *p2) | 248 static int mail_sort_qsort_func(const void *p1, const void *p2) |
249 { | 249 { |
250 const unsigned int *i1 = p1; | 250 const unsigned int *i1 = p1; |
251 const unsigned int *i2 = p2; | 251 const unsigned int *i2 = p2; |
252 enum mail_sort_type *output = mail_sort_qsort_context->output; | 252 enum mail_sort_type *output; |
253 struct mail_sort_funcs *funcs = &mail_sort_qsort_context->funcs; | 253 const struct mail_sort_callbacks *cb; |
254 void *ctx = mail_sort_qsort_context->func_context; | 254 void *ctx; |
255 int ret, reverse = FALSE; | 255 int ret, reverse = FALSE; |
256 | |
257 output = mail_sort_qsort_context->output; | |
258 cb = mail_sort_qsort_context->callbacks; | |
259 ctx = mail_sort_qsort_context->func_context; | |
256 | 260 |
257 t_push(); | 261 t_push(); |
258 | 262 |
259 ret = 0; | 263 ret = 0; |
260 for (; *output != MAIL_SORT_END && ret == 0; output++) { | 264 for (; *output != MAIL_SORT_END && ret == 0; output++) { |
266 switch (*output) { | 270 switch (*output) { |
267 case MAIL_SORT_ARRIVAL: | 271 case MAIL_SORT_ARRIVAL: |
268 case MAIL_SORT_DATE: { | 272 case MAIL_SORT_DATE: { |
269 time_t r1, r2; | 273 time_t r1, r2; |
270 | 274 |
271 r1 = funcs->input_time(*output, *i1, ctx); | 275 r1 = cb->input_time(*output, *i1, ctx); |
272 r2 = funcs->input_time(*output, *i2, ctx); | 276 r2 = cb->input_time(*output, *i2, ctx); |
273 ret = r1 < r2 ? -1 : r1 > r2 ? 1 : 0; | 277 ret = r1 < r2 ? -1 : r1 > r2 ? 1 : 0; |
274 break; | 278 break; |
275 } | 279 } |
276 case MAIL_SORT_SIZE: { | 280 case MAIL_SORT_SIZE: { |
277 uoff_t r1, r2; | 281 uoff_t r1, r2; |
278 | 282 |
279 r1 = funcs->input_uofft(*output, *i1, ctx); | 283 r1 = cb->input_uofft(*output, *i1, ctx); |
280 r2 = funcs->input_uofft(*output, *i2, ctx); | 284 r2 = cb->input_uofft(*output, *i2, ctx); |
281 ret = r1 < r2 ? -1 : r1 > r2 ? 1 : 0; | 285 ret = r1 < r2 ? -1 : r1 > r2 ? 1 : 0; |
282 break; | 286 break; |
283 } | 287 } |
284 case MAIL_SORT_CC: | 288 case MAIL_SORT_CC: |
285 case MAIL_SORT_FROM: | 289 case MAIL_SORT_FROM: |
286 case MAIL_SORT_TO: { | 290 case MAIL_SORT_TO: { |
287 const char *a1, *a2; | 291 const char *a1, *a2; |
288 | 292 |
289 a1 = funcs->input_mailbox(*output, *i1, ctx); | 293 a1 = cb->input_mailbox(*output, *i1, ctx); |
290 a2 = funcs->input_mailbox(*output, *i2, ctx); | 294 a2 = cb->input_mailbox(*output, *i2, ctx); |
291 ret = addr_strcmp(a1, a2); | 295 ret = addr_strcmp(a1, a2); |
292 break; | 296 break; |
293 } | 297 } |
294 case MAIL_SORT_SUBJECT: | 298 case MAIL_SORT_SUBJECT: |
295 ret = subject_cmp(mail_sort_qsort_context->temp_pool, | 299 ret = subject_cmp(mail_sort_qsort_context->temp_pool, |
296 funcs->input_str(*output, *i1, ctx), | 300 cb->input_str(*output, *i1, ctx), |
297 funcs->input_str(*output, *i2, ctx)); | 301 cb->input_str(*output, *i2, ctx)); |
298 break; | 302 break; |
299 default: | 303 default: |
300 i_unreached(); | 304 i_unreached(); |
301 } | 305 } |
302 | 306 |
308 } | 312 } |
309 | 313 |
310 reverse = FALSE; | 314 reverse = FALSE; |
311 } | 315 } |
312 | 316 |
313 funcs->input_reset(ctx); | 317 cb->input_reset(ctx); |
314 | 318 |
315 t_pop(); | 319 t_pop(); |
316 | 320 |
317 return ret != 0 ? ret : (*i1 < *i2 ? -1 : 1); | 321 return ret != 0 ? ret : (*i1 < *i2 ? -1 : 1); |
318 } | 322 } |
326 | 330 |
327 arr = buffer_get_modifyable_data(ctx->sort_buffer, NULL); | 331 arr = buffer_get_modifyable_data(ctx->sort_buffer, NULL); |
328 count = buffer_get_used_size(ctx->sort_buffer) / sizeof(unsigned int); | 332 count = buffer_get_used_size(ctx->sort_buffer) / sizeof(unsigned int); |
329 qsort(arr, count, sizeof(unsigned int), mail_sort_qsort_func); | 333 qsort(arr, count, sizeof(unsigned int), mail_sort_qsort_func); |
330 | 334 |
331 ctx->funcs.output(arr, count, ctx->func_context); | 335 ctx->callbacks->output(arr, count, ctx->func_context); |
332 buffer_set_used_size(ctx->sort_buffer, 0); | 336 buffer_set_used_size(ctx->sort_buffer, 0); |
333 } | 337 } |