* This call returns a fastbuf that concatenates all the given fastbufs.
* The last parameter of @fbmulti_create must be NULL.
*
- * By default, if @bclose() is called on fbmulti, all the underlying buffers
- * get closed recursively.
+ * If @bclose() is called on fbmulti, all the underlying buffers get closed
+ * recursively.
*
* You may init a fbmulti by @fbmulti_create(bufsize) with no underlying buffers
- * and then append the underlying buffers one by one. If allow_close is set to 0,
- * the fastbuf doesn't get closed at @bclose() and you have to do the cleanup on
- * yourself.
+ * and then append the underlying buffers one by one.
*
* If used in some formatter, you'll probably have a large and deep structure
* of nested fastbufs. Just before reading from the fbmulti, you may call
* @fbmulti_flatten() to flatten the structure. After @fbmulti_flatten(), the
* fbmulti is seeked to the beginning, flushed and ready to read the whole buffer.
*
- * For performance reasons, use @fbmulti_flatten() only once, just before reading.
- *
* If you want to remove a fastbuf from the chain, just call @fbmulti_remove
* where the second parameter is a pointer to the removed fastbuf. If you pass
* NULL, all the underlying fastbufs are removed.
***/
struct fastbuf *fbmulti_create(uns bufsize, ...) SENTINEL_CHECK;
-void fbmulti_append(struct fastbuf *f, struct fastbuf *fa, int allow_close);
-void fbmulti_flatten(struct fastbuf *f);
+void fbmulti_append(struct fastbuf *f, struct fastbuf *fa);
void fbmulti_remove(struct fastbuf *f, struct fastbuf *fb);
struct subbuf {
cnode n;
ucw_off_t begin, end, offset;
- int allow_close;
struct fastbuf *fb;
};
fbmulti_close(struct fastbuf *f)
{
CLIST_FOR_EACH(struct subbuf *, n, *(FB_MULTI(f)->subbufs))
- if (n->allow_close)
- bclose(n->fb);
+ bclose(n->fb);
mp_delete(FB_MULTI(f)->mp);
}
va_list args;
va_start(args, bufsize);
while (fb_in = va_arg(args, struct fastbuf *))
- fbmulti_append(fb_out, fb_in, 1);
+ fbmulti_append(fb_out, fb_in);
va_end(args);
}
void
-fbmulti_append(struct fastbuf *f, struct fastbuf *fb, int allow_close)
+fbmulti_append(struct fastbuf *f, struct fastbuf *fb)
{
struct subbuf *sb = mp_alloc(FB_MULTI(f)->mp, sizeof(struct subbuf));
sb->fb = fb;
- sb->allow_close = allow_close;
clist_add_tail(FB_MULTI(f)->subbufs, &(sb->n));
fbmulti_update_capability(f);
}
f->pos = 0;
}
-static void fbmulti_flatten_internal(struct fastbuf *f, clist *c, int allow_close)
-{
- CLIST_FOR_EACH(struct subbuf *, n, *c)
- {
- if (strcmp(n->fb->name, FB_MULTI_NAME))
- fbmulti_append(f, n->fb, n->allow_close && allow_close);
-
- else
- {
- fbmulti_flatten_internal(f, FB_MULTI(n->fb)->subbufs, allow_close && n->allow_close);
- if (allow_close && n->allow_close)
- {
- FB_MULTI(n->fb)->subbufs = mp_alloc(FB_MULTI(n->fb)->mp, sizeof(clist));
- clist_init(FB_MULTI(n->fb)->subbufs);
- bclose(n->fb);
- }
- }
- }
-}
-
-void
-fbmulti_flatten(struct fastbuf *f)
-{
- if (strcmp(f->name, FB_MULTI_NAME))
- {
- DBG("fbmulti: given fastbuf isn't fbmulti");
- return;
- }
-
- clist *c = FB_MULTI(f)->subbufs;
- FB_MULTI(f)->subbufs = mp_alloc(FB_MULTI(f)->mp, sizeof(clist));
- clist_init(FB_MULTI(f)->subbufs);
-
- fbmulti_flatten_internal(f, c, 1);
- FB_MULTI(f)->cur = clist_head(FB_MULTI(f)->subbufs);
- f->bptr = f->bstop = f->buffer;
- f->pos = 0;
-}
-
#ifdef TEST
int main(int argc, char **argv)
bclose(f);
break;
}
- case 'f':
case 'n':
{
char *data[] = { "Nested", "Data", "As", "In", "Real", "Usage", };
&nl,
NULL);
- if (*argv[1] == 'f')
- fbmulti_flatten(f);
-
char buffer[20];
while (bgets(f, buffer, 20))
puts(buffer);