]> granicus.if.org Git - libevent/commitdiff
provide a function to read lines from buffers; comes in handy for many
authorNiels Provos <provos@gmail.com>
Sat, 23 Apr 2005 02:53:39 +0000 (02:53 +0000)
committerNiels Provos <provos@gmail.com>
Sat, 23 Apr 2005 02:53:39 +0000 (02:53 +0000)
AscII protocols.

svn:r154

buffer.c
event.h

index fb4576af143a488ce6c277188c810b172636ed10..afd2204569f2ce1b76ca024deaf1ad3173083b17 100644 (file)
--- a/buffer.c
+++ b/buffer.c
@@ -176,6 +176,53 @@ evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen)
        return (nread);
 }
 
+/*
+ * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'.
+ * The returned buffer needs to be freed by the called.
+ */
+
+char *
+evbuffer_readline(struct evbuffer *buffer)
+{
+       char *data = EVBUFFER_DATA(buffer);
+       size_t len = EVBUFFER_LENGTH(buffer);
+       char *line;
+       int i;
+
+       for (i = 0; i < len; i++) {
+               if (data[i] == '\r' || data[i] == '\n')
+                       break;
+       }
+       
+       if (i == len)
+               return (NULL);
+
+       if ((line = malloc(i + 1)) == NULL) {
+               fprintf(stderr, "%s: out of memory\n", __func__);
+               evbuffer_drain(buffer, i);
+               return (NULL);
+       }
+
+       memcpy(line, data, i);
+       line[i] = '\0';
+
+       /*
+        * Some protocols terminate a line with '\r\n', so check for
+        * that, too.
+        */
+       if ( i < len - 1 ) {
+               char fch = data[i], sch = data[i+1];
+
+               /* Drain one more character if needed */
+               if ( (sch == '\r' || sch == '\n') && sch != fch )
+                       i += 1;
+       }
+
+       evbuffer_drain(buffer, i + 1);
+
+       return (line);
+}
+
 /* Adds data to an event buffer */
 
 static inline void
diff --git a/event.h b/event.h
index 799a266e2d2d161baed8334b34d5582c3f762644..857dd376e42d4148f9ff3648470366fb9634c3fd 100644 (file)
--- a/event.h
+++ b/event.h
@@ -261,6 +261,7 @@ void evbuffer_free(struct evbuffer *);
 int evbuffer_expand(struct evbuffer *, size_t);
 int evbuffer_add(struct evbuffer *, void *, size_t);
 int evbuffer_remove(struct evbuffer *, void *, size_t);
+char *evbuffer_readline(struct evbuffer *);
 int evbuffer_add_buffer(struct evbuffer *, struct evbuffer *);
 int evbuffer_add_printf(struct evbuffer *, char *fmt, ...);
 void evbuffer_drain(struct evbuffer *, size_t);