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 }