chiark / gitweb /
Add support for variable buffer sizes.
authormdw <mdw>
Sat, 17 Jun 2000 10:38:14 +0000 (10:38 +0000)
committermdw <mdw>
Sat, 17 Jun 2000 10:38:14 +0000 (10:38 +0000)
lbuf.c
lbuf.h
selbuf.c
selbuf.h

diff --git a/lbuf.c b/lbuf.c
index 118250d..9c0ec22 100644 (file)
--- a/lbuf.c
+++ b/lbuf.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: lbuf.c,v 1.3 1999/05/22 13:38:50 mdw Exp $
+ * $Id: lbuf.c,v 1.4 2000/06/17 10:38:14 mdw Exp $
  *
  * Block-to-line buffering
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: lbuf.c,v $
+ * Revision 1.4  2000/06/17 10:38:14  mdw
+ * Add support for variable buffer sizes.
+ *
  * Revision 1.3  1999/05/22 13:38:50  mdw
  * Fix bug which discarded initial portions of incomplete lines.
  *
 
 /*----- Header files ------------------------------------------------------*/
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "alloc.h"
+#include "arena.h"
 #include "lbuf.h"
 
 /*----- Main code ---------------------------------------------------------*/
@@ -94,7 +100,7 @@ void lbuf_flush(lbuf *b, char *p, size_t len)
 
   /* --- Clear @base@ if I'm discarding an overlong line --- */
 
-  if (b->len == sizeof(b->buf))
+  if (b->len == b->sz)
     base = 0;
   else
     base = b->buf;
@@ -151,7 +157,7 @@ void lbuf_flush(lbuf *b, char *p, size_t len)
 
   if (base) {
     size_t len = l - base;
-    if (len == sizeof(b->buf)) {
+    if (len == b->sz) {
       b->buf[len - 1] = 0;
       b->func(base, b->p);
     } else if (base != b->buf)
@@ -173,15 +179,19 @@ void lbuf_flush(lbuf *b, char *p, size_t len)
  * Use:                Empties the buffer of any data currently lurking in it, and
  *             informs the client that this has happened.  It's assumed that
  *             the buffer is enabled: you shouldn't be reading close events
- *             on disabled buffers.
+ *             on disabled buffers.  The buffer, if allocated, is freed.
  */
 
 void lbuf_close(lbuf *b)
 {
-  if (b->len && b->len != sizeof(b->buf)) {
+  if (b->len && b->len != b->sz) {
     b->buf[b->len] = 0;
     b->func(b->buf, b->p);
   }
+  if (b->buf) {
+    x_free(b->a, b->buf);
+    b->buf = 0;
+  }
   if (b->f & LBUF_ENABLE)
     b->func(0, b->p);
 }
@@ -195,7 +205,8 @@ void lbuf_close(lbuf *b)
  *
  * Use:                Returns the free portion of a line buffer.  Data can then be
  *             written to this portion, and split out into lines by calling
- *             @lbuf_flush@.
+ *             @lbuf_flush@.  A buffer is allocated if none currently
+ *             exists.
  */
 
 size_t lbuf_free(lbuf *b, char **p)
@@ -204,18 +215,20 @@ size_t lbuf_free(lbuf *b, char **p)
    *
    * If a line from the file wouldn't fit in the buffer, I truncate it and
    * return what would fit.  The rest of the line ought to be discarded.
-   * This condition is signalled by @len = sizeof(buf)@, and means that the
-   * entire buffer is OK to be trashed.  In other cases, @len@ is the amount
-   * of space currently occupied in the buffer.  This special case is the
-   * reason this routine exists.
+   * This condition is signalled by @len = b->sz@, and means that the entire
+   * buffer is OK to be trashed.  In other cases, @len@ is the amount of
+   * space currently occupied in the buffer.  This special case is the reason
+   * this routine exists.
    */
 
-  if (b->len != 0 && b->len != sizeof(b->buf)) {
+  if (b->len != 0 && b->len != b->sz) {
     *p = b->buf + b->len;
-    return (sizeof(b->buf) - b->len);
+    return (b->sz - b->len);
   } else {
+    if (!b->buf)
+      b->buf = x_alloc(b->a, b->sz);
     *p = b->buf;
-    return (sizeof(b->buf));
+    return (b->sz);
   }
 }
 
@@ -236,7 +249,7 @@ size_t lbuf_free(lbuf *b, char **p)
 void lbuf_snarf(lbuf *b, const void *p, size_t sz)
 {
   const char *pp = p;
-  while (sz) {
+  while (sz && (b->f & LBUF_ENABLE)) {
     size_t bsz;
     char *bp;
 
@@ -250,6 +263,28 @@ void lbuf_snarf(lbuf *b, const void *p, size_t sz)
   }
 }
 
+/* --- @lbuf_setsize@ --- *
+ *
+ * Arguments:  @lbuf *b@ = pointer to buffer block
+ *             @size_t sz@ = requested maximum line size
+ *
+ * Returns:    ---
+ *
+ * Use:                Modifies the size of the buffer associated with the block.
+ *             It is an error to resize a buffer while it contains data.
+ */
+
+void lbuf_setsize(lbuf *b, size_t sz)
+{
+  if (b->buf)
+  assert(((void)"Buffer in use in lbuf_setsize",
+        b->len == 0 || b->len == b->sz));
+  if (b->buf)
+    x_free(b->a, b->buf);
+  b->sz = sz;
+  b->buf = 0;
+}
+
 /* --- @lbuf_init@ --- *
  *
  * Arguments:  @lbuf *b@ = pointer to buffer block
@@ -259,7 +294,9 @@ void lbuf_snarf(lbuf *b, const void *p, size_t sz)
  * Returns:    ---
  *
  * Use:                Initializes a line buffer block.  Any recognized lines are
- *             passed to @func@ for processing.
+ *             passed to @func@ for processing.  No buffer is initially
+ *             allocated; this is done when the buffer is actually required
+ *             for the first time.
  */
 
 void lbuf_init(lbuf *b,
@@ -270,6 +307,26 @@ void lbuf_init(lbuf *b,
   b->p = p;
   b->len = 0;
   b->f = LBUF_ENABLE;
+  b->buf = 0;
+  b->a = arena_global;
+  lbuf_setsize(b, 256);
+}
+
+/* --- @lbuf_destroy@ --- *
+ *
+ * Arguments:  @lbuf *b@ = pointer to buffer block
+ *
+ * Returns:    ---
+ *
+ * Use:                Deallocates a line buffer and frees any resources it owned.
+ */
+
+void lbuf_destroy(lbuf *b)
+{
+  if (b->buf) {
+    x_free(b->a, b->buf);
+    b->buf = 0;
+  }
 }
 
 /*----- That's all, folks -------------------------------------------------*/
diff --git a/lbuf.h b/lbuf.h
index 21968e2..3f25dac 100644 (file)
--- a/lbuf.h
+++ b/lbuf.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: lbuf.h,v 1.3 1999/12/10 23:42:04 mdw Exp $
+ * $Id: lbuf.h,v 1.4 2000/06/17 10:38:14 mdw Exp $
  *
  * Block-to-line buffering
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: lbuf.h,v $
+ * Revision 1.4  2000/06/17 10:38:14  mdw
+ * Add support for variable buffer sizes.
+ *
  * Revision 1.3  1999/12/10 23:42:04  mdw
  * Change header file guard names.
  *
 
 #include <stddef.h>
 
+#ifndef MLIB_ARENA_H
+#  include "arena.h"
+#endif
+
 /*----- Data structures ---------------------------------------------------*/
 
 /* --- The buffer structure --- *
@@ -106,8 +113,10 @@ typedef struct lbuf {
   void (*func)(char */*s*/, void */*p*/); /* Handler function */
   void *p;                             /* Argument for handler */
   size_t len;                          /* Length of data in buffer */
+  size_t sz;                           /* Buffer size */
   unsigned f;                          /* Various useful state flags */
-  char buf[256];                       /* The actual buffer */
+  arena *a;                            /* Memory allocation arena */
+  char *buf;                           /* The actual buffer */
 } lbuf;
 
 enum {
@@ -186,6 +195,18 @@ extern size_t lbuf_free(lbuf */*b*/, char **/*p*/);
 
 extern void lbuf_snarf(lbuf */*b*/, const void */*p*/, size_t /*sz*/);
 
+/* --- @lbuf_setsize@ --- *
+ *
+ * Arguments:  @lbuf *b@ = pointer to buffer block
+ *             @size_t sz@ = requested maximum line size
+ *
+ * Returns:    ---
+ *
+ * Use:                Allocates a buffer of the requested size reading lines.
+ */
+
+extern void lbuf_setsize(lbuf */*b*/, size_t /*sz*/);
+
 /* --- @lbuf_init@ --- *
  *
  * Arguments:  @lbuf *b@ = pointer to buffer block
@@ -202,6 +223,17 @@ extern void lbuf_init(lbuf */*b*/,
                      void (*/*func*/)(char */*s*/, void */*p*/),
                      void */*p*/);
 
+/* --- @lbuf_destroy@ --- *
+ *
+ * Arguments:  @lbuf *b@ = pointer to buffer block
+ *
+ * Returns:    ---
+ *
+ * Use:                Deallocates a line buffer and frees any resources it owned.
+ */
+
+extern void lbuf_destroy(lbuf */*b*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus
index b8b1161..9acc65f 100644 (file)
--- a/selbuf.c
+++ b/selbuf.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: selbuf.c,v 1.3 1999/05/22 13:41:00 mdw Exp $
+ * $Id: selbuf.c,v 1.4 2000/06/17 10:38:14 mdw Exp $
  *
  * Line-buffering select handler
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: selbuf.c,v $
+ * Revision 1.4  2000/06/17 10:38:14  mdw
+ * Add support for variable buffer sizes.
+ *
  * Revision 1.3  1999/05/22 13:41:00  mdw
  * Fix end-of-file detection and error handling.
  *
@@ -131,6 +134,21 @@ static void selbuf_read(int fd, unsigned mode, void *vp)
   }
 }
 
+/* --- @selbuf_setsize@ --- *
+ *
+ * Arguments:  @selbuf *b@ = pointer to buffer block
+ *             @size_t sz@ = size of buffer
+ *
+ * Returns:    ---
+ *
+ * Use:                Sets the size of the buffer used for reading lines.
+ */
+
+void selbuf_setsize(selbuf *b, size_t sz)
+{
+  lbuf_setsize(&b->b, sz);
+}
+
 /* --- @selbuf_init@ --- *
  *
  * Arguments:  @selbuf *b@ = pointer to buffer block
@@ -156,4 +174,19 @@ void selbuf_init(selbuf *b,
   selbuf_enable(b);
 }
 
+/* --- @selbuf_destroy@ --- *
+ *
+ * Arguments:  @selbuf *b@ = pointer to buffer block
+ *
+ * Returns:    ---
+ *
+ * Use:                Deallocates a line buffer and frees any resources it owned.
+ */
+
+void selbuf_destroy(selbuf *b)
+{
+  selbuf_disable(b);
+  lbuf_destroy(&b->b);
+}
+
 /*----- That's all, folks -------------------------------------------------*/
index 571dd8f..65eea4e 100644 (file)
--- a/selbuf.h
+++ b/selbuf.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: selbuf.h,v 1.2 1999/12/10 23:42:04 mdw Exp $
+ * $Id: selbuf.h,v 1.3 2000/06/17 10:38:14 mdw Exp $
  *
  * Line-buffering select handler
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: selbuf.h,v $
+ * Revision 1.3  2000/06/17 10:38:14  mdw
+ * Add support for variable buffer sizes.
+ *
  * Revision 1.2  1999/12/10 23:42:04  mdw
  * Change header file guard names.
  *
@@ -88,6 +91,18 @@ extern void selbuf_enable(selbuf */*b*/);
 
 extern void selbuf_disable(selbuf */*b*/);
 
+/* --- @selbuf_setsize@ --- *
+ *
+ * Arguments:  @selbuf *b@ = pointer to buffer block
+ *             @size_t sz@ = size of buffer
+ *
+ * Returns:    ---
+ *
+ * Use:                Sets the size of the buffer used for reading lines.
+ */
+
+extern void selbuf_setsize(selbuf */*b*/, size_t /*sz*/);
+
 /* --- @selbuf_init@ --- *
  *
  * Arguments:  @selbuf *b@ = pointer to buffer block
@@ -107,6 +122,17 @@ extern void selbuf_init(selbuf */*b*/,
                        void (*/*func*/)(char */*s*/, void */*p*/),
                        void */*p*/);
 
+/* --- @selbuf_destroy@ --- *
+ *
+ * Arguments:  @selbuf *b@ = pointer to buffer block
+ *
+ * Returns:    ---
+ *
+ * Use:                Deallocates a line buffer and frees any resources it owned.
+ */
+
+extern void selbuf_destroy(selbuf */*b*/);
+
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus