comparison mcabber/src/hbuf.c @ 1141:5be2408a6534

Add option "max_history_blocks"
author Mikael Berthe <mikael@lilotux.net>
date Tue, 06 Feb 2007 00:21:42 +0100
parents b5bcc223cf51
children e802ec0c02d2
comparison
equal deleted inserted replaced
1140:800bb1e9019c 1141:5be2408a6534
105 } 105 }
106 curr_elt = g_list_next(curr_elt); 106 curr_elt = g_list_next(curr_elt);
107 } 107 }
108 } 108 }
109 109
110 // hbuf_add_line(p_hbuf, text, prefix_flags, width) 110 // hbuf_add_line(p_hbuf, text, prefix_flags, width, maxhbufblocks)
111 // Add a line to the given buffer. If width is not null, then lines are 111 // Add a line to the given buffer. If width is not null, then lines are
112 // wrapped at this length. 112 // wrapped at this length.
113 // maxhbufblocks is the maximum number of hbuf blocks we can allocate. If
114 // null, there is no limit. If non-null, it should be >= 2.
113 // 115 //
114 // Note 1: Splitting according to width won't work if there are tabs; they 116 // Note 1: Splitting according to width won't work if there are tabs; they
115 // should be expanded before. 117 // should be expanded before.
116 // Note 2: width does not include the ending \0. 118 // Note 2: width does not include the ending \0.
117 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp, 119 void hbuf_add_line(GList **p_hbuf, const char *text, time_t timestamp,
118 guint prefix_flags, guint width) 120 guint prefix_flags, guint width, guint maxhbufblocks)
119 { 121 {
120 GList *curr_elt; 122 GList *curr_elt;
121 char *line, *end; 123 char *line;
122 hbuf_block *hbuf_block_elt; 124 hbuf_block *hbuf_block_elt;
123 125
124 if (!text) return; 126 if (!text) return;
125 127
126 hbuf_block_elt = g_new0(hbuf_block, 1); 128 hbuf_block_elt = g_new0(hbuf_block, 1);
147 text = "[ERR:LINE_TOO_LONG]"; 149 text = "[ERR:LINE_TOO_LONG]";
148 hbuf_block_elt->prefix.flags |= HBB_PREFIX_INFO; 150 hbuf_block_elt->prefix.flags |= HBB_PREFIX_INFO;
149 } 151 }
150 if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) { 152 if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) {
151 // Too long for the current allocated bloc, we need another one 153 // Too long for the current allocated bloc, we need another one
152 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE); 154 if (!maxhbufblocks) {
155 // No limit, let's allocate a new block
156 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE);
157 } else {
158 GList *hbuf_head, *hbuf_elt;
159 hbuf_block *hbuf_b_elt;
160 guint n = 0;
161 hbuf_head = g_list_first(*p_hbuf);
162 // We need at least 2 allocated blocks
163 if (maxhbufblocks == 1)
164 maxhbufblocks = 2;
165 // Let's count the number of allocated areas
166 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = g_list_next(hbuf_elt)) {
167 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data);
168 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC)
169 n++;
170 }
171 // If we can't allocate a new area, reuse the previous block(s)
172 if (n < maxhbufblocks) {
173 hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE);
174 } else {
175 // Let's use an old block, and free the extra blocks if needed
176 char *allocated_block = NULL;
177 while (n >= maxhbufblocks) {
178 /* --- */
179 int start_of_block = 1;
180 for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = hbuf_head) {
181 hbuf_b_elt = (hbuf_block*)(hbuf_elt->data);
182 if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) {
183 if (start_of_block-- == 0)
184 break;
185 if (n == maxhbufblocks)
186 allocated_block = hbuf_b_elt->ptr;
187 else
188 g_free(hbuf_b_elt->ptr);
189 }
190 g_free(hbuf_b_elt);
191 hbuf_head = *p_hbuf = g_list_delete_link(hbuf_head, hbuf_elt);
192 }
193 n--;
194 /* --- */
195 }
196 memset(allocated_block, 0, HBB_BLOCKSIZE);
197 hbuf_block_elt->ptr = allocated_block;
198 }
199 }
153 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; 200 hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT;
154 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE; 201 hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE;
155 } 202 }
156 203
157 line = hbuf_block_elt->ptr; 204 line = hbuf_block_elt->ptr;
158 // Ok, now we can copy the text.. 205 // Ok, now we can copy the text..
159 strcpy(line, text); 206 strcpy(line, text);
160 hbuf_block_elt->ptr_end = line + strlen(line) + 1; 207 hbuf_block_elt->ptr_end = line + strlen(line) + 1;
161 end = hbuf_block_elt->ptr_end;
162 208
163 curr_elt = g_list_last(*p_hbuf); 209 curr_elt = g_list_last(*p_hbuf);
164 210
165 // Wrap lines and handle CRs ('\n') 211 // Wrap lines and handle CRs ('\n')
166 do_wrap(p_hbuf, curr_elt, width); 212 do_wrap(p_hbuf, curr_elt, width);