59 |
59 |
60 // Let's add non-persistent blocs if necessary |
60 // Let's add non-persistent blocs if necessary |
61 // - If there are '\n' in the string |
61 // - If there are '\n' in the string |
62 // - If length > width (and width != 0) |
62 // - If length > width (and width != 0) |
63 while (curr_elt) { |
63 while (curr_elt) { |
64 hbuf_block *hbuf_b_curr, *hbuf_b_prev; |
64 hbuf_block_t *hbuf_b_curr, *hbuf_b_prev; |
65 char *c, *end; |
65 char *c, *end; |
66 char *br = NULL; // break pointer |
66 char *br = NULL; // break pointer |
67 char *cr = NULL; // CR pointer |
67 char *cr = NULL; // CR pointer |
68 unsigned int cur_w = 0; |
68 unsigned int cur_w = 0; |
69 |
69 |
70 // We want to break where we can find a space char or a CR |
70 // We want to break where we can find a space char or a CR |
71 |
71 |
72 hbuf_b_curr = (hbuf_block*)(curr_elt->data); |
72 hbuf_b_curr = (hbuf_block_t*)(curr_elt->data); |
73 hbuf_b_prev = hbuf_b_curr; |
73 hbuf_b_prev = hbuf_b_curr; |
74 c = hbuf_b_curr->ptr; |
74 c = hbuf_b_curr->ptr; |
75 |
75 |
76 while (*c && (!width || cur_w <= width)) { |
76 while (*c && (!width || cur_w <= width)) { |
77 if (*c == '\n') { |
77 if (*c == '\n') { |
91 else |
91 else |
92 br = next_char(br); |
92 br = next_char(br); |
93 end = hbuf_b_curr->ptr_end; |
93 end = hbuf_b_curr->ptr_end; |
94 hbuf_b_curr->ptr_end = br; |
94 hbuf_b_curr->ptr_end = br; |
95 // Create another block |
95 // Create another block |
96 hbuf_b_curr = g_new0(hbuf_block, 1); |
96 hbuf_b_curr = g_new0(hbuf_block_t, 1); |
97 // The block must be persistent after a CR |
97 // The block must be persistent after a CR |
98 if (cr) { |
98 if (cr) { |
99 hbuf_b_curr->ptr = hbuf_b_prev->ptr_end + 1; // == cr+1 |
99 hbuf_b_curr->ptr = hbuf_b_prev->ptr_end + 1; // == cr+1 |
100 hbuf_b_curr->flags = HBB_FLAG_PERSISTENT; |
100 hbuf_b_curr->flags = HBB_FLAG_PERSISTENT; |
101 } else { |
101 } else { |
125 unsigned mucnicklen, gpointer xep184) |
125 unsigned mucnicklen, gpointer xep184) |
126 { |
126 { |
127 GList *curr_elt; |
127 GList *curr_elt; |
128 char *line; |
128 char *line; |
129 guint hbb_blocksize, textlen; |
129 guint hbb_blocksize, textlen; |
130 hbuf_block *hbuf_block_elt; |
130 hbuf_block_t *hbuf_block_elt; |
131 |
131 |
132 if (!text) return; |
132 if (!text) return; |
133 |
133 |
134 prefix_flags |= (xep184 ? HBB_PREFIX_RECEIPT : 0); |
134 prefix_flags |= (xep184 ? HBB_PREFIX_RECEIPT : 0); |
135 |
135 |
136 textlen = strlen(text); |
136 textlen = strlen(text); |
137 hbb_blocksize = MAX(textlen+1, HBB_BLOCKSIZE); |
137 hbb_blocksize = MAX(textlen+1, HBB_BLOCKSIZE); |
138 |
138 |
139 hbuf_block_elt = g_new0(hbuf_block, 1); |
139 hbuf_block_elt = g_new0(hbuf_block_t, 1); |
140 hbuf_block_elt->prefix.timestamp = timestamp; |
140 hbuf_block_elt->prefix.timestamp = timestamp; |
141 hbuf_block_elt->prefix.flags = prefix_flags; |
141 hbuf_block_elt->prefix.flags = prefix_flags; |
142 hbuf_block_elt->prefix.mucnicklen = mucnicklen; |
142 hbuf_block_elt->prefix.mucnicklen = mucnicklen; |
143 hbuf_block_elt->prefix.xep184 = xep184; |
143 hbuf_block_elt->prefix.xep184 = xep184; |
144 if (!*p_hbuf) { |
144 if (!*p_hbuf) { |
148 return; |
148 return; |
149 } |
149 } |
150 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; |
150 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; |
151 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; |
151 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; |
152 } else { |
152 } else { |
153 hbuf_block *hbuf_b_prev; |
153 hbuf_block_t *hbuf_b_prev; |
154 // Set p_hbuf to the end of the list, to speed up history loading |
154 // Set p_hbuf to the end of the list, to speed up history loading |
155 // (or CPU time will be used by g_list_last() for each line) |
155 // (or CPU time will be used by g_list_last() for each line) |
156 *p_hbuf = g_list_last(*p_hbuf); |
156 *p_hbuf = g_list_last(*p_hbuf); |
157 hbuf_b_prev = (*p_hbuf)->data; |
157 hbuf_b_prev = (*p_hbuf)->data; |
158 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end; |
158 hbuf_block_elt->ptr = hbuf_b_prev->ptr_end; |
170 hbuf_block_elt->ptr = g_new0(char, hbb_blocksize); |
170 hbuf_block_elt->ptr = g_new0(char, hbb_blocksize); |
171 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; |
171 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; |
172 // XXX We should check the return value. |
172 // XXX We should check the return value. |
173 } else { |
173 } else { |
174 GList *hbuf_head, *hbuf_elt; |
174 GList *hbuf_head, *hbuf_elt; |
175 hbuf_block *hbuf_b_elt; |
175 hbuf_block_t *hbuf_b_elt; |
176 guint n = 0; |
176 guint n = 0; |
177 hbuf_head = g_list_first(*p_hbuf); |
177 hbuf_head = g_list_first(*p_hbuf); |
178 // We need at least 2 allocated blocks |
178 // We need at least 2 allocated blocks |
179 if (maxhbufblocks == 1) |
179 if (maxhbufblocks == 1) |
180 maxhbufblocks = 2; |
180 maxhbufblocks = 2; |
181 // Let's count the number of allocated areas |
181 // Let's count the number of allocated areas |
182 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) { |
182 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) { |
183 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data); |
183 hbuf_b_elt = (hbuf_block_t*)(hbuf_elt->data); |
184 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) |
184 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) |
185 n++; |
185 n++; |
186 } |
186 } |
187 // If we can't allocate a new area, reuse the previous block(s) |
187 // If we can't allocate a new area, reuse the previous block(s) |
188 if (n < maxhbufblocks) { |
188 if (n < maxhbufblocks) { |
193 char *allocated_block = NULL; |
193 char *allocated_block = NULL; |
194 char *end_of_allocated_block = NULL; |
194 char *end_of_allocated_block = NULL; |
195 while (n >= maxhbufblocks) { |
195 while (n >= maxhbufblocks) { |
196 int start_of_block = 1; |
196 int start_of_block = 1; |
197 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = hbuf_head) { |
197 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = hbuf_head) { |
198 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data); |
198 hbuf_b_elt = (hbuf_block_t*)(hbuf_elt->data); |
199 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) { |
199 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) { |
200 if (start_of_block-- == 0) |
200 if (start_of_block-- == 0) |
201 break; |
201 break; |
202 if (n == maxhbufblocks) { |
202 if (n == maxhbufblocks) { |
203 allocated_block = hbuf_b_elt->ptr; |
203 allocated_block = hbuf_b_elt->ptr; |
232 |
232 |
233 // hbuf_free() |
233 // hbuf_free() |
234 // Destroys all hbuf list. |
234 // Destroys all hbuf list. |
235 void hbuf_free(GList **p_hbuf) |
235 void hbuf_free(GList **p_hbuf) |
236 { |
236 { |
237 hbuf_block *hbuf_b_elt; |
237 hbuf_block_t *hbuf_b_elt; |
238 GList *hbuf_elt; |
238 GList *hbuf_elt; |
239 GList *first_elt = g_list_first(*p_hbuf); |
239 GList *first_elt = g_list_first(*p_hbuf); |
240 |
240 |
241 for (hbuf_elt = first_elt; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) { |
241 for (hbuf_elt = first_elt; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) { |
242 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data); |
242 hbuf_b_elt = (hbuf_block_t*)(hbuf_elt->data); |
243 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) { |
243 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) { |
244 g_free(hbuf_b_elt->ptr); |
244 g_free(hbuf_b_elt->ptr); |
245 } |
245 } |
246 g_free(hbuf_b_elt); |
246 g_free(hbuf_b_elt); |
247 } |
247 } |
254 // Rebuild all hbuf list, with the new width. |
254 // Rebuild all hbuf list, with the new width. |
255 // If width == 0, lines are not wrapped. |
255 // If width == 0, lines are not wrapped. |
256 void hbuf_rebuild(GList **p_hbuf, unsigned int width) |
256 void hbuf_rebuild(GList **p_hbuf, unsigned int width) |
257 { |
257 { |
258 GList *first_elt, *curr_elt, *next_elt; |
258 GList *first_elt, *curr_elt, *next_elt; |
259 hbuf_block *hbuf_b_curr, *hbuf_b_next; |
259 hbuf_block_t *hbuf_b_curr, *hbuf_b_next; |
260 |
260 |
261 // *p_hbuf needs to be the head of the list |
261 // *p_hbuf needs to be the head of the list |
262 first_elt = *p_hbuf = g_list_first(*p_hbuf); |
262 first_elt = *p_hbuf = g_list_first(*p_hbuf); |
263 |
263 |
264 // #1 Remove non-persistent blocks (ptr_end should be updated!) |
264 // #1 Remove non-persistent blocks (ptr_end should be updated!) |
266 while (curr_elt) { |
266 while (curr_elt) { |
267 next_elt = g_list_next(curr_elt); |
267 next_elt = g_list_next(curr_elt); |
268 // Last element? |
268 // Last element? |
269 if (!next_elt) |
269 if (!next_elt) |
270 break; |
270 break; |
271 hbuf_b_curr = (hbuf_block*)(curr_elt->data); |
271 hbuf_b_curr = (hbuf_block_t*)(curr_elt->data); |
272 hbuf_b_next = (hbuf_block*)(next_elt->data); |
272 hbuf_b_next = (hbuf_block_t*)(next_elt->data); |
273 // Is next line not-persistent? |
273 // Is next line not-persistent? |
274 if (!(hbuf_b_next->flags & HBB_FLAG_PERSISTENT)) { |
274 if (!(hbuf_b_next->flags & HBB_FLAG_PERSISTENT)) { |
275 hbuf_b_curr->ptr_end = hbuf_b_next->ptr_end; |
275 hbuf_b_curr->ptr_end = hbuf_b_next->ptr_end; |
276 g_free(hbuf_b_next); |
276 g_free(hbuf_b_next); |
277 curr_elt = g_list_delete_link(curr_elt, next_elt); |
277 curr_elt = g_list_delete_link(curr_elt, next_elt); |
289 // This function is used for example when resizing a buffer. If the top of the |
289 // This function is used for example when resizing a buffer. If the top of the |
290 // screen is on a non-persistent block, then a screen resize could destroy this |
290 // screen is on a non-persistent block, then a screen resize could destroy this |
291 // line... |
291 // line... |
292 GList *hbuf_previous_persistent(GList *l_line) |
292 GList *hbuf_previous_persistent(GList *l_line) |
293 { |
293 { |
294 hbuf_block *hbuf_b_elt; |
294 hbuf_block_t *hbuf_b_elt; |
295 |
295 |
296 while (l_line) { |
296 while (l_line) { |
297 hbuf_b_elt = (hbuf_block*)l_line->data; |
297 hbuf_b_elt = (hbuf_block_t*)l_line->data; |
298 if (hbuf_b_elt->flags & HBB_FLAG_PERSISTENT && |
298 if (hbuf_b_elt->flags & HBB_FLAG_PERSISTENT && |
299 (hbuf_b_elt->flags & ~HBB_PREFIX_READMARK)) |
299 (hbuf_b_elt->flags & ~HBB_PREFIX_READMARK)) |
300 return l_line; |
300 return l_line; |
301 l_line = g_list_previous(l_line); |
301 l_line = g_list_previous(l_line); |
302 } |
302 } |
310 // Note: The caller should free the array, the hbb_line pointers and the |
310 // Note: The caller should free the array, the hbb_line pointers and the |
311 // text pointers after use. |
311 // text pointers after use. |
312 hbb_line **hbuf_get_lines(GList *hbuf, unsigned int n) |
312 hbb_line **hbuf_get_lines(GList *hbuf, unsigned int n) |
313 { |
313 { |
314 unsigned int i; |
314 unsigned int i; |
315 hbuf_block *blk; |
315 hbuf_block_t *blk; |
316 guint last_persist_prefixflags = 0; |
316 guint last_persist_prefixflags = 0; |
317 GList *last_persist; // last persistent flags |
317 GList *last_persist; // last persistent flags |
318 hbb_line **array, **array_elt; |
318 hbb_line **array, **array_elt; |
319 hbb_line *prev_array_elt = NULL; |
319 hbb_line *prev_array_elt = NULL; |
320 |
320 |
322 // we need to look at the last non-null prefix, which should be the first |
322 // we need to look at the last non-null prefix, which should be the first |
323 // line of the message. We also need to check if there's a readmark flag |
323 // line of the message. We also need to check if there's a readmark flag |
324 // somewhere in the message. |
324 // somewhere in the message. |
325 last_persist = hbuf_previous_persistent(hbuf); |
325 last_persist = hbuf_previous_persistent(hbuf); |
326 while (last_persist) { |
326 while (last_persist) { |
327 blk = (hbuf_block*)last_persist->data; |
327 blk = (hbuf_block_t*)last_persist->data; |
328 if ((blk->flags & HBB_FLAG_PERSISTENT) && blk->prefix.flags) { |
328 if ((blk->flags & HBB_FLAG_PERSISTENT) && blk->prefix.flags) { |
329 // This can be either the beginning of the message, |
329 // This can be either the beginning of the message, |
330 // or a persistent line with a readmark flag (or both). |
330 // or a persistent line with a readmark flag (or both). |
331 if (blk->prefix.flags & ~HBB_PREFIX_READMARK) { // First message line |
331 if (blk->prefix.flags & ~HBB_PREFIX_READMARK) { // First message line |
332 last_persist_prefixflags |= blk->prefix.flags; |
332 last_persist_prefixflags |= blk->prefix.flags; |
343 |
343 |
344 for (i = 0 ; i < n ; i++) { |
344 for (i = 0 ; i < n ; i++) { |
345 if (hbuf) { |
345 if (hbuf) { |
346 int maxlen; |
346 int maxlen; |
347 |
347 |
348 blk = (hbuf_block*)(hbuf->data); |
348 blk = (hbuf_block_t*)(hbuf->data); |
349 maxlen = blk->ptr_end - blk->ptr; |
349 maxlen = blk->ptr_end - blk->ptr; |
350 *array_elt = (hbb_line*)g_new(hbb_line, 1); |
350 *array_elt = (hbb_line*)g_new(hbb_line, 1); |
351 (*array_elt)->timestamp = blk->prefix.timestamp; |
351 (*array_elt)->timestamp = blk->prefix.timestamp; |
352 (*array_elt)->flags = blk->prefix.flags; |
352 (*array_elt)->flags = blk->prefix.flags; |
353 (*array_elt)->mucnicklen = blk->prefix.mucnicklen; |
353 (*array_elt)->mucnicklen = blk->prefix.mucnicklen; |
391 // hbuf_search(hbuf, direction, string) |
391 // hbuf_search(hbuf, direction, string) |
392 // Look backward/forward for a line containing string in the history buffer |
392 // Look backward/forward for a line containing string in the history buffer |
393 // Search starts at hbuf, and goes forward if direction == 1, backward if -1 |
393 // Search starts at hbuf, and goes forward if direction == 1, backward if -1 |
394 GList *hbuf_search(GList *hbuf, int direction, const char *string) |
394 GList *hbuf_search(GList *hbuf, int direction, const char *string) |
395 { |
395 { |
396 hbuf_block *blk; |
396 hbuf_block_t *blk; |
397 |
397 |
398 for (;;) { |
398 for (;;) { |
399 if (direction > 0) |
399 if (direction > 0) |
400 hbuf = g_list_next(hbuf); |
400 hbuf = g_list_next(hbuf); |
401 else |
401 else |
402 hbuf = g_list_previous(hbuf); |
402 hbuf = g_list_previous(hbuf); |
403 |
403 |
404 if (!hbuf) break; |
404 if (!hbuf) break; |
405 |
405 |
406 blk = (hbuf_block*)(hbuf->data); |
406 blk = (hbuf_block_t*)(hbuf->data); |
407 // XXX blk->ptr is (maybe) not really correct, because the match should |
407 // XXX blk->ptr is (maybe) not really correct, because the match should |
408 // not be after ptr_end. We should check that... |
408 // not be after ptr_end. We should check that... |
409 if (strcasestr(blk->ptr, string)) |
409 if (strcasestr(blk->ptr, string)) |
410 break; |
410 break; |
411 } |
411 } |
415 |
415 |
416 // hbuf_jump_date(hbuf, t) |
416 // hbuf_jump_date(hbuf, t) |
417 // Return a pointer to the first line after date t in the history buffer |
417 // Return a pointer to the first line after date t in the history buffer |
418 GList *hbuf_jump_date(GList *hbuf, time_t t) |
418 GList *hbuf_jump_date(GList *hbuf, time_t t) |
419 { |
419 { |
420 hbuf_block *blk; |
420 hbuf_block_t *blk; |
421 |
421 |
422 hbuf = g_list_first(hbuf); |
422 hbuf = g_list_first(hbuf); |
423 |
423 |
424 for ( ; hbuf && g_list_next(hbuf); hbuf = g_list_next(hbuf)) { |
424 for ( ; hbuf && g_list_next(hbuf); hbuf = g_list_next(hbuf)) { |
425 blk = (hbuf_block*)(hbuf->data); |
425 blk = (hbuf_block_t*)(hbuf->data); |
426 if (blk->prefix.timestamp >= t) break; |
426 if (blk->prefix.timestamp >= t) break; |
427 } |
427 } |
428 |
428 |
429 return hbuf; |
429 return hbuf; |
430 } |
430 } |
444 // hbuf_jump_readmark(hbuf) |
444 // hbuf_jump_readmark(hbuf) |
445 // Return a pointer to the line following the readmark |
445 // Return a pointer to the line following the readmark |
446 // or NULL if no mark was found. |
446 // or NULL if no mark was found. |
447 GList *hbuf_jump_readmark(GList *hbuf) |
447 GList *hbuf_jump_readmark(GList *hbuf) |
448 { |
448 { |
449 hbuf_block *blk; |
449 hbuf_block_t *blk; |
450 GList *r = NULL; |
450 GList *r = NULL; |
451 |
451 |
452 hbuf = g_list_last(hbuf); |
452 hbuf = g_list_last(hbuf); |
453 for ( ; hbuf; hbuf = g_list_previous(hbuf)) { |
453 for ( ; hbuf; hbuf = g_list_previous(hbuf)) { |
454 blk = (hbuf_block*)(hbuf->data); |
454 blk = (hbuf_block_t*)(hbuf->data); |
455 if (blk->prefix.flags & HBB_PREFIX_READMARK) |
455 if (blk->prefix.flags & HBB_PREFIX_READMARK) |
456 return r; |
456 return r; |
457 if ((blk->flags & HBB_FLAG_PERSISTENT) && |
457 if ((blk->flags & HBB_FLAG_PERSISTENT) && |
458 (blk->prefix.flags & ~HBB_PREFIX_READMARK)) |
458 (blk->prefix.flags & ~HBB_PREFIX_READMARK)) |
459 r = hbuf; |
459 r = hbuf; |
464 |
464 |
465 // hbuf_dump_to_file(hbuf, filename) |
465 // hbuf_dump_to_file(hbuf, filename) |
466 // Save the buffer to a file. |
466 // Save the buffer to a file. |
467 void hbuf_dump_to_file(GList *hbuf, const char *filename) |
467 void hbuf_dump_to_file(GList *hbuf, const char *filename) |
468 { |
468 { |
469 hbuf_block *blk; |
469 hbuf_block_t *blk; |
470 hbb_line line; |
470 hbb_line line; |
471 guint last_persist_prefixflags = 0; |
471 guint last_persist_prefixflags = 0; |
472 guint prefixwidth; |
472 guint prefixwidth; |
473 char pref[96]; |
473 char pref[96]; |
474 FILE *fp; |
474 FILE *fp; |
488 prefixwidth = MIN(prefixwidth, sizeof pref); |
488 prefixwidth = MIN(prefixwidth, sizeof pref); |
489 |
489 |
490 for (hbuf = g_list_first(hbuf); hbuf; hbuf = g_list_next(hbuf)) { |
490 for (hbuf = g_list_first(hbuf); hbuf; hbuf = g_list_next(hbuf)) { |
491 int maxlen; |
491 int maxlen; |
492 |
492 |
493 blk = (hbuf_block*)(hbuf->data); |
493 blk = (hbuf_block_t*)(hbuf->data); |
494 maxlen = blk->ptr_end - blk->ptr; |
494 maxlen = blk->ptr_end - blk->ptr; |
495 |
495 |
496 memset(&line, 0, sizeof(line)); |
496 memset(&line, 0, sizeof(line)); |
497 line.timestamp = blk->prefix.timestamp; |
497 line.timestamp = blk->prefix.timestamp; |
498 line.flags = blk->prefix.flags; |
498 line.flags = blk->prefix.flags; |
523 // hbuf_remove_receipt(hbuf, xep184) |
523 // hbuf_remove_receipt(hbuf, xep184) |
524 // Remove the Receipt Flag for the message with the given xep184 id |
524 // Remove the Receipt Flag for the message with the given xep184 id |
525 // Returns TRUE if it was found and removed, otherwise FALSE |
525 // Returns TRUE if it was found and removed, otherwise FALSE |
526 gboolean hbuf_remove_receipt(GList *hbuf, gconstpointer xep184) |
526 gboolean hbuf_remove_receipt(GList *hbuf, gconstpointer xep184) |
527 { |
527 { |
528 hbuf_block *blk; |
528 hbuf_block_t *blk; |
529 |
529 |
530 hbuf = g_list_last(hbuf); |
530 hbuf = g_list_last(hbuf); |
531 |
531 |
532 for ( ; hbuf; hbuf = g_list_previous(hbuf)) { |
532 for ( ; hbuf; hbuf = g_list_previous(hbuf)) { |
533 blk = (hbuf_block*)(hbuf->data); |
533 blk = (hbuf_block_t*)(hbuf->data); |
534 if (!g_strcmp0(blk->prefix.xep184, xep184)) { |
534 if (!g_strcmp0(blk->prefix.xep184, xep184)) { |
535 g_free(blk->prefix.xep184); |
535 g_free(blk->prefix.xep184); |
536 blk->prefix.xep184 = NULL; |
536 blk->prefix.xep184 = NULL; |
537 blk->prefix.flags ^= HBB_PREFIX_RECEIPT; |
537 blk->prefix.flags ^= HBB_PREFIX_RECEIPT; |
538 return TRUE; |
538 return TRUE; |
545 // Set/Reset the readmark Flag |
545 // Set/Reset the readmark Flag |
546 // If action is TRUE, set a mark to the latest line, |
546 // If action is TRUE, set a mark to the latest line, |
547 // if action is FALSE, remove a previous readmark flag. |
547 // if action is FALSE, remove a previous readmark flag. |
548 void hbuf_set_readmark(GList *hbuf, gboolean action) |
548 void hbuf_set_readmark(GList *hbuf, gboolean action) |
549 { |
549 { |
550 hbuf_block *blk; |
550 hbuf_block_t *blk; |
551 |
551 |
552 if (!hbuf) return; |
552 if (!hbuf) return; |
553 |
553 |
554 hbuf = hbuf_previous_persistent(g_list_last(hbuf)); |
554 hbuf = hbuf_previous_persistent(g_list_last(hbuf)); |
555 |
555 |
556 if (action) { |
556 if (action) { |
557 // Add a readmark flag |
557 // Add a readmark flag |
558 blk = (hbuf_block*)(hbuf->data); |
558 blk = (hbuf_block_t*)(hbuf->data); |
559 blk->prefix.flags |= HBB_PREFIX_READMARK; |
559 blk->prefix.flags |= HBB_PREFIX_READMARK; |
560 |
560 |
561 // Shift hbuf in order to remove previous flags |
561 // Shift hbuf in order to remove previous flags |
562 // (maybe it can be optimized out, if there's no risk |
562 // (maybe it can be optimized out, if there's no risk |
563 // we have several marks) |
563 // we have several marks) |
564 hbuf = g_list_previous(hbuf); |
564 hbuf = g_list_previous(hbuf); |
565 } |
565 } |
566 |
566 |
567 // Remove old mark |
567 // Remove old mark |
568 for ( ; hbuf; hbuf = g_list_previous(hbuf)) { |
568 for ( ; hbuf; hbuf = g_list_previous(hbuf)) { |
569 blk = (hbuf_block*)(hbuf->data); |
569 blk = (hbuf_block_t*)(hbuf->data); |
570 if (blk->prefix.flags & HBB_PREFIX_READMARK) { |
570 if (blk->prefix.flags & HBB_PREFIX_READMARK) { |
571 blk->prefix.flags &= ~HBB_PREFIX_READMARK; |
571 blk->prefix.flags &= ~HBB_PREFIX_READMARK; |
572 break; |
572 break; |
573 } |
573 } |
574 } |
574 } |
576 |
576 |
577 // hbuf_remove_trailing_readmark(hbuf) |
577 // hbuf_remove_trailing_readmark(hbuf) |
578 // Unset the buffer readmark if it is on the last line |
578 // Unset the buffer readmark if it is on the last line |
579 void hbuf_remove_trailing_readmark(GList *hbuf) |
579 void hbuf_remove_trailing_readmark(GList *hbuf) |
580 { |
580 { |
581 hbuf_block *blk; |
581 hbuf_block_t *blk; |
582 |
582 |
583 if (!hbuf) return; |
583 if (!hbuf) return; |
584 |
584 |
585 hbuf = g_list_last(hbuf); |
585 hbuf = g_list_last(hbuf); |
586 blk = (hbuf_block*)(hbuf->data); |
586 blk = (hbuf_block_t*)(hbuf->data); |
587 blk->prefix.flags &= ~HBB_PREFIX_READMARK; |
587 blk->prefix.flags &= ~HBB_PREFIX_READMARK; |
588 } |
588 } |
589 |
589 |
590 // hbuf_get_blocks_number() |
590 // hbuf_get_blocks_number() |
591 // Returns the number of allocated hbuf_block's. |
591 // Returns the number of allocated hbuf_block_t's. |
592 guint hbuf_get_blocks_number(GList *hbuf) |
592 guint hbuf_get_blocks_number(GList *hbuf) |
593 { |
593 { |
594 hbuf_block *hbuf_b_elt; |
594 hbuf_block_t *hbuf_b_elt; |
595 guint count = 0U; |
595 guint count = 0U; |
596 |
596 |
597 for (hbuf = g_list_first(hbuf); hbuf; hbuf = g_list_next(hbuf)) { |
597 for (hbuf = g_list_first(hbuf); hbuf; hbuf = g_list_next(hbuf)) { |
598 hbuf_b_elt = (hbuf_block*)(hbuf->data); |
598 hbuf_b_elt = (hbuf_block_t*)(hbuf->data); |
599 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) |
599 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) |
600 count++; |
600 count++; |
601 } |
601 } |
602 return count; |
602 return count; |
603 } |
603 } |