summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
5a18a12)
handler functions. Allow run-time configuration of line delimiters.
- * $Id: lbuf.c,v 1.5 2001/02/03 16:23:33 mdw Exp $
+ * $Id: lbuf.c,v 1.6 2002/01/13 13:32:52 mdw Exp $
*
* Block-to-line buffering
*
*
* Block-to-line buffering
*
/*----- Revision history --------------------------------------------------*
*
* $Log: lbuf.c,v $
/*----- Revision history --------------------------------------------------*
*
* $Log: lbuf.c,v $
+ * Revision 1.6 2002/01/13 13:32:52 mdw
+ * Pass line length to line handler function. Provide a @typedef@ for
+ * handler functions. Allow run-time configuration of line delimiters.
+ *
* Revision 1.5 2001/02/03 16:23:33 mdw
* Bug fix: handle a disable during a close-induced flush without dumping
* core.
* Revision 1.5 2001/02/03 16:23:33 mdw
* Bug fix: handle a disable during a close-induced flush without dumping
* core.
int cr; /* Carriage return state */
if (b->f & LBUF_CLOSE) {
int cr; /* Carriage return state */
if (b->f & LBUF_CLOSE) {
/* --- Quickly discard uninteresting characters --- */
/* --- Quickly discard uninteresting characters --- */
- if (*q != '\r' && *q != '\n') {
- cr = 0;
- continue;
- }
- if (*q == '\r') {
- cr = 1;
- continue;
+ switch (b->delim) {
+ case LBUF_CRLF:
+ case LBUF_STRICTCRLF:
+ if (*q != '\r' && *q != '\n') {
+ cr = 0;
+ continue;
+ }
+ if (*q == '\r') {
+ cr = 1;
+ continue;
+ }
+ if (!cr && b->delim == LBUF_STRICTCRLF)
+ continue;
+ break;
+ default:
+ if (*q != b->delim)
+ continue;
- /* --- Two choices here --- *
- *
- * I can either be strict about CRLF line ends, or I can be shoddy
- * and allow bare LFs. I'll do the latter, although I oughtn't,
- * because it makes testing interactively and with Unix text files
- * easier.
- */
-
-#ifdef STRICT_CRLF
- if (!cr)
- continue;
-#endif
-
- /* --- I have a positive ID on a linefeed --- *
+ /* --- I have a positive ID on a delimiter --- *
*
* If I'm interested in this string, report it to my owner.
*/
if (base) {
*
* If I'm interested in this string, report it to my owner.
*/
if (base) {
- q[-1] = 0; /* Exercise: why is this safe? */
- else
- *q = 0;
- b->func(base, b->p);
+ len--; /* Exercise: why is this safe? */
+ base[len] = 0;
+ b->func(base, len, b->p);
if (!(b->f & LBUF_ENABLE)) {
base = q + 1;
break;
if (!(b->f & LBUF_ENABLE)) {
base = q + 1;
break;
/* --- Sift through the aftermath --- */
if (base) {
/* --- Sift through the aftermath --- */
if (base) {
if (len == b->sz) {
b->buf[len - 1] = 0;
if (len == b->sz) {
b->buf[len - 1] = 0;
+ b->func(base, len - 1, b->p);
} else if (base != b->buf)
memmove(b->buf, base, len);
b->len = len;
} else if (base != b->buf)
memmove(b->buf, base, len);
b->len = len;
{
if (b->len && b->len != b->sz) {
b->buf[b->len] = 0;
{
if (b->len && b->len != b->sz) {
b->buf[b->len] = 0;
+ b->func(b->buf, b->len, b->p);
}
if (b->buf) {
x_free(b->a, b->buf);
}
if (b->buf) {
x_free(b->a, b->buf);
}
b->f |= LBUF_CLOSE;
if (b->f & LBUF_ENABLE)
}
b->f |= LBUF_CLOSE;
if (b->f & LBUF_ENABLE)
}
/* --- @lbuf_free@ --- *
}
/* --- @lbuf_free@ --- *
/* --- @lbuf_init@ --- *
*
* Arguments: @lbuf *b@ = pointer to buffer block
/* --- @lbuf_init@ --- *
*
* Arguments: @lbuf *b@ = pointer to buffer block
- * @void (*func)(char *s, void *p)@ = handler function
+ * @lbuf_func *func@ = handler function
* @void *p@ = argument pointer for @func@
*
* Returns: ---
* @void *p@ = argument pointer for @func@
*
* Returns: ---
-void lbuf_init(lbuf *b,
- void (*func)(char */*s*/, void */*p*/),
- void *p)
+void lbuf_init(lbuf *b, lbuf_func *func, void *p)
{
b->func = func;
b->p = p;
b->len = 0;
b->f = LBUF_ENABLE;
{
b->func = func;
b->p = p;
b->len = 0;
b->f = LBUF_ENABLE;
b->buf = 0;
b->a = arena_global;
lbuf_setsize(b, 256);
b->buf = 0;
b->a = arena_global;
lbuf_setsize(b, 256);
- * $Id: lbuf.h,v 1.6 2001/02/03 16:23:33 mdw Exp $
+ * $Id: lbuf.h,v 1.7 2002/01/13 13:32:52 mdw Exp $
*
* Block-to-line buffering
*
*
* Block-to-line buffering
*
/*----- Revision history --------------------------------------------------*
*
* $Log: lbuf.h,v $
/*----- Revision history --------------------------------------------------*
*
* $Log: lbuf.h,v $
+ * Revision 1.7 2002/01/13 13:32:52 mdw
+ * Pass line length to line handler function. Provide a @typedef@ for
+ * handler functions. Allow run-time configuration of line delimiters.
+ *
* Revision 1.6 2001/02/03 16:23:33 mdw
* Bug fix: handle a disable during a close-induced flush without dumping
* core.
* Revision 1.6 2001/02/03 16:23:33 mdw
* Bug fix: handle a disable during a close-induced flush without dumping
* core.
+struct lbuf;
+
+typedef void lbuf_func(char */*s*/, size_t /*len*/, void */*p*/);
+
- void (*func)(char */*s*/, void */*p*/); /* Handler function */
+ lbuf_func *func; /* Handler function */
void *p; /* Argument for handler */
size_t len; /* Length of data in buffer */
size_t sz; /* Buffer size */
void *p; /* Argument for handler */
size_t len; /* Length of data in buffer */
size_t sz; /* Buffer size */
+ unsigned delim; /* Delimiter to look for */
unsigned f; /* Various useful state flags */
arena *a; /* Memory allocation arena */
char *buf; /* The actual buffer */
unsigned f; /* Various useful state flags */
arena *a; /* Memory allocation arena */
char *buf; /* The actual buffer */
#define LBUF_ENABLE 2u /* Buffer is currently enabled */
#define LBUF_CLOSE 4u /* Buffer is now closed */
#define LBUF_ENABLE 2u /* Buffer is currently enabled */
#define LBUF_CLOSE 4u /* Buffer is now closed */
+enum {
+ LBUF_CRLF = 256,
+ LBUF_STRICTCRLF = 257
+};
+
/*----- Functions provided ------------------------------------------------*/
/* --- @lbuf_flush@ --- *
/*----- Functions provided ------------------------------------------------*/
/* --- @lbuf_flush@ --- *
/* --- @lbuf_init@ --- *
*
* Arguments: @lbuf *b@ = pointer to buffer block
/* --- @lbuf_init@ --- *
*
* Arguments: @lbuf *b@ = pointer to buffer block
- * @void (*func)(char *s, void *p)@ = handler function
+ * @lbuf_func *func@ = handler function
* @void *p@ = argument pointer for @func@
*
* Returns: ---
* @void *p@ = argument pointer for @func@
*
* Returns: ---
* passed to @func@ for processing.
*/
* passed to @func@ for processing.
*/
-extern void lbuf_init(lbuf */*b*/,
- void (*/*func*/)(char */*s*/, void */*p*/),
- void */*p*/);
+extern void lbuf_init(lbuf */*b*/, lbuf_func */*func*/, void */*p*/);
/* --- @lbuf_destroy@ --- *
*
/* --- @lbuf_destroy@ --- *
*
.BI "size_t lbuf_free(lbuf *" b ", char **" p );
.BI "void lbuf_snarf(lbuf *" b ", const void *" p ", size_t " sz );
.BI "void lbuf_setsize(lbuf *" b ", size_t " sz );
.BI "size_t lbuf_free(lbuf *" b ", char **" p );
.BI "void lbuf_snarf(lbuf *" b ", const void *" p ", size_t " sz );
.BI "void lbuf_setsize(lbuf *" b ", size_t " sz );
-.BI "void lbuf_init(lbuf *" b ,
-.BI " void (*" func ")(char *" s ", void *" p ),
-.BI " void *" p );
+.BI "void lbuf_init(lbuf *" b ", lbuf_func *" func ", void *" p );
.BI "void lbuf_destroy(lbuf *" b );
.fi
.SH "DESCRIPTION"
.BI "void lbuf_destroy(lbuf *" b );
.fi
.SH "DESCRIPTION"
buffer will allocate memory to store incoming data automatically: this
structure just contains bookkeeping information.
.TP
buffer will allocate memory to store incoming data automatically: this
structure just contains bookkeeping information.
.TP
-.BI "void (*" func ")(char *" s ", void *" p )
The
.I line-handler
function to which the line buffer should pass completed lines of text.
The
.I line-handler
function to which the line buffer should pass completed lines of text.
+See
+.B "Line-handler functions"
+below for a description of this function.
.TP
.BI "void *" p
A pointer argument to be passed to the function when a completed line of
.TP
.BI "void *" p
A pointer argument to be passed to the function when a completed line of
.BR lbuf_free / lbuf_flush
interface.
.SS "Line breaking"
.BR lbuf_free / lbuf_flush
interface.
.SS "Line breaking"
-The line buffer considers a line to end with either a simple linefeed
-character (the normal Unix convention) or a carriage-return/linefeed
-pair (the Internet convention).
+By default, the line buffer considers a line to end with either a simple
+linefeed character (the normal Unix convention) or a
+carriage-return/linefeed pair (the Internet convention). This can be
+changed by modifying the
+.B delim
+member of the
+.B lbuf
+structure: the default value is
+.BR LBUF_CRLF .
+If set to
+.BR LBUF_STRICTCRLF ,
+only a carriage-return/linefeed pair will terminate a line. Any other
+value is a single character which is considered to be the line terminator.
.PP
The line buffer has a fixed amount of memory available to it. This is
deliberate, to prevent a trivial attack whereby a remote user sends a
.PP
The line buffer has a fixed amount of memory available to it. This is
deliberate, to prevent a trivial attack whereby a remote user sends a
line completely.
.SS "Line-handler functions"
Completed lines, as already said, are passed to the caller's
line completely.
.SS "Line-handler functions"
Completed lines, as already said, are passed to the caller's
-line-handler function. The function is given two arguments:
-the address
+line-handler function. This function has the signature
+.IP
+.B "void"
+.IB func "(char *" s ", size_t " len ", void *" p );
+.PP
+It is given three arguments: the address
-of the line which has just been read, and the pointer
+of the line which has just been read; the length
+.I len
+of the line (not including the null terminator), and the pointer
.I p
which was set up in the call to
.BR lbuf_init .
.I p
which was set up in the call to
.BR lbuf_init .
.PP
The line pointer argument
.I s
.PP
The line pointer argument
.I s
-may be null to signify end-of-file. See the next section.
+may be null to signify end-of-file; in this case, the length
+.I len
+will be zero. See the next section.
.SS "Flushing the remaining data"
When the client program knows that there's no more data arriving (for
example, an end-of-file condition exists on its data source) it should
.SS "Flushing the remaining data"
When the client program knows that there's no more data arriving (for
example, an end-of-file condition exists on its data source) it should