olla,

I dont know what the process for submitting patches here,
but this is against version 1.4.9.

This makes it easier to integrate libraries that provide their own
read/write functions (such as openssl).
Example usage would be something like:

-----
static
size_t myrcb(int fd, void *buf, size_t len, int flags, void *rcbarg)
{
        fprintf(stderr, "myrcb invoked\n", fd,len,flags);
        blah;
        bleh;
        return specialized_read(fd, buf, len);
}

//somewhere in setup code ..
..
struct evbuffer rbuf;
..
...
evbuffer_setrcb(&rbuf, myrcb, NULL);
..
...
//somewhere in callback
len = evbuffer_read(&rbuf, fd, BUFSIZ);
---------

Of course you could use bufferevents instead of direct calls
to evbuffer_read/write.

cheers,
jamal
diff --git a/buffer.c b/buffer.c
index e66080f..6032cad 100644
--- a/buffer.c
+++ b/buffer.c
@@ -341,16 +341,28 @@ evbuffer_drain(struct evbuffer *buf, size_t len)
 
 }
 
+#define EVBUFFER_MAX_READ	4096
+size_t
+buffer_read(struct evbuffer *buf, int fd, int howmuch)
+{
+	/* We can append new data at this point */
+	u_char *p = buf->buffer + buf->off;
+
+	if (buf->rcb != NULL)
+		return buf->rcb(fd, p, howmuch, 0, buf->rcbarg);
+#ifndef WIN32
+	return read(fd, p, howmuch);
+#else
+	return recv(fd, p, howmuch, 0);
+#endif
+}
 /*
  * Reads data from a file descriptor into a buffer.
  */
 
-#define EVBUFFER_MAX_READ	4096
-
 int
 evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
 {
-	u_char *p;
 	size_t oldoff = buf->off;
 	int n = EVBUFFER_MAX_READ;
 
@@ -383,14 +395,8 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
 	if (evbuffer_expand(buf, howmuch) == -1)
 		return (-1);
 
-	/* We can append new data at this point */
-	p = buf->buffer + buf->off;
 
-#ifndef WIN32
-	n = read(fd, p, howmuch);
-#else
-	n = recv(fd, p, howmuch, 0);
-#endif
+	n = buffer_read(buf, fd, howmuch);
 	if (n == -1)
 		return (-1);
 	if (n == 0)
@@ -405,16 +411,23 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch)
 	return (n);
 }
 
-int
-evbuffer_write(struct evbuffer *buffer, int fd)
+ssize_t
+buffer_write(struct evbuffer *buf, int fd)
 {
-	int n;
-
+	if (buf->scb != NULL)
+		return buf->scb(fd, buf->buffer, buf->off, 0,buf->scbarg);
 #ifndef WIN32
-	n = write(fd, buffer->buffer, buffer->off);
+	return write(fd, buf->buffer, buf->off);
 #else
-	n = send(fd, buffer->buffer, buffer->off, 0);
+	return send(fd, buf->buffer, buf->off, 0);
 #endif
+}
+
+int
+evbuffer_write(struct evbuffer *buffer, int fd)
+{
+	int n = buffer_write(buffer, fd);
+
 	if (n == -1)
 		return (-1);
 	if (n == 0)
@@ -449,3 +462,18 @@ void evbuffer_setcb(struct evbuffer *buffer,
 	buffer->cb = cb;
 	buffer->cbarg = cbarg;
 }
+
+void evbuffer_setrcb(struct evbuffer *buffer,
+    ssize_t (*cb)(int, void *, size_t, int, void *),
+    void *cbarg)
+{
+	buffer->rcb = cb;
+	buffer->rcbarg = cbarg;
+}
+void evbuffer_setscb(struct evbuffer *buffer,
+    ssize_t (*cb)(int, const void *, size_t, int, void *),
+    void *cbarg)
+{
+	buffer->scb = cb;
+	buffer->scbarg = cbarg;
+}
diff --git a/event.h b/event.h
index b6a8144..e2e01f2 100644
--- a/event.h
+++ b/event.h
@@ -729,6 +729,10 @@ struct evbuffer {
 
 	void (*cb)(struct evbuffer *, size_t, size_t, void *);
 	void *cbarg;
+	ssize_t (*rcb)(int s, void *buf, size_t len, int flags, void *rcbarg);
+	void *rcbarg;
+	ssize_t (*scb)(int s, const void *buf, size_t len, int flags, void *scbarg);
+	void *scbarg;
 };
 
 /* Just for error reporting - use other constants otherwise */
@@ -1118,6 +1122,30 @@ u_char *evbuffer_find(struct evbuffer *, const u_char *, size_t);
  */
 void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_t, void *), void *);
 
+/**
+  Set a callback to invoke for reading from a file descriptor.
+
+  This is useful if you want to use your own read function instead
+  of the standard system call.
+
+  @param buffer the evbuffer to read into
+  @param cb the callback function to invoke for reading
+  @param cbarg an argument to be provided to the callback function
+ */
+void evbuffer_setrcb(struct evbuffer *, ssize_t (*)(int, void *, size_t, int, void *), void *);
+
+/**
+  Set a callback to invoke when the evbuffer is modified.
+
+  This is useful if you want to use your own write function instead
+  of the standard system call.
+
+  @param buffer the evbuffer to be written
+  @param cb the callback function to invoke when writting the evbuffer
+  @param cbarg an argument to be provided to the callback function
+ */
+void evbuffer_setscb(struct evbuffer *, ssize_t (*)(int, const void *, size_t, int, void *), void *);
+
 /*
  * Marshaling tagged data - We assume that all tags are inserted in their
  * numeric order - so that unknown tags will always be higher than the
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users

Reply via email to