jerenkrantz 02/01/20 03:20:27
Modified: . CHANGES
buckets apr_brigade.c
include apr_buckets.h
Log:
Add apr_brigade_getline, apr_brigade_pgetline, and apr_brigade_split_line.
These functions allow APR-util to have centralized logic for dealing with:
1) Returning a flattened char* representation of an entire brigade with
a user-provided char*
2) Returning a minimally-sized char* representation (pool-allocated) of a
brigade
3) Splitting a brigade based on LF presence
Reviewed by: Greg Stein (concept)
Revision Changes Path
1.53 +4 -0 apr-util/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr-util/CHANGES,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- CHANGES 19 Jan 2002 05:03:57 -0000 1.52
+++ CHANGES 20 Jan 2002 11:20:27 -0000 1.53
@@ -1,4 +1,8 @@
Changes with APR-util b1
+
+ *) Add ability to natively fetch and split brigades based on LF lines.
+ [Justin Erenkrantz]
+
*) add --with-berkeley-db=DIR & --with-gdbm configure flags
[Ian Holsman/Justin Erenkrantz]
1.27 +95 -0 apr-util/buckets/apr_brigade.c
Index: apr_brigade.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- apr_brigade.c 12 Nov 2001 03:22:25 -0000 1.26
+++ apr_brigade.c 20 Jan 2002 11:20:27 -0000 1.27
@@ -221,6 +221,101 @@
return APR_SUCCESS;
}
+APU_DECLARE(apr_status_t) apr_brigade_getline(apr_bucket_brigade *bb,
+ char *c, apr_size_t *len)
+{
+ apr_size_t actual = 0;
+ apr_bucket *b;
+
+ APR_BRIGADE_FOREACH(b, bb) {
+ const char *str;
+ apr_size_t str_len;
+ apr_status_t status;
+
+ status = apr_bucket_read(b, &str, &str_len, APR_BLOCK_READ);
+ if (status != APR_SUCCESS) {
+ return status;
+ }
+
+ /* If we would overflow. */
+ if (*len < actual + str_len) {
+ str_len = *len - actual;
+ }
+
+ memcpy(c, str, str_len);
+
+ c += str_len;
+ actual += str_len;
+
+ if (*len < actual) {
+ break;
+ }
+ }
+
+ *len = actual;
+ return APR_SUCCESS;
+}
+
+APU_DECLARE(char *) apr_brigade_pgetline(apr_bucket_brigade *bb,
+ apr_pool_t *pool)
+{
+ apr_off_t tmp;
+ apr_size_t actual;
+ char *c;
+
+ apr_brigade_length(bb, 1, &tmp);
+ actual = tmp;
+
+ c = apr_palloc(pool, actual + 1);
+
+ apr_brigade_getline(bb, c, &actual);
+ c[actual] = '\0';
+
+ return APR_SUCCESS;
+}
+
+APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
+ apr_bucket_brigade *bbIn,
+ apr_read_type_e block,
+ apr_size_t maxbytes)
+{
+ apr_size_t readbytes = 0;
+
+ while (!APR_BRIGADE_EMPTY(bbIn)) {
+ const char *pos;
+ const char *str;
+ apr_size_t len;
+ apr_status_t rv;
+ apr_bucket *e;
+
+ e = APR_BRIGADE_FIRST(bbIn);
+ rv = apr_bucket_read(e, &str, &len, block);
+
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ pos = memchr(str, APR_ASCII_LF, len);
+ /* We found a match. */
+ if (pos != NULL) {
+ apr_bucket_split(e, pos - str + 1);
+ APR_BUCKET_REMOVE(e);
+ APR_BRIGADE_INSERT_TAIL(bbOut, e);
+ return APR_SUCCESS;
+ }
+ APR_BUCKET_REMOVE(e);
+ APR_BRIGADE_INSERT_TAIL(bbOut, e);
+ readbytes += len;
+ /* We didn't find an APR_ASCII_LF within the maximum line length. */
+ if (readbytes >= maxbytes) {
+ break;
+ }
+ }
+
+ return APR_SUCCESS;
+}
+
+
APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b,
struct iovec *vec, int *nvec)
{
1.122 +33 -0 apr-util/include/apr_buckets.h
Index: apr_buckets.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -r1.121 -r1.122
--- apr_buckets.h 12 Nov 2001 03:22:25 -0000 1.121
+++ apr_buckets.h 20 Jan 2002 11:20:27 -0000 1.122
@@ -689,6 +689,39 @@
apr_off_t *length);
/**
+ * Take a bucket brigade and store the data in a flat char*
+ * @param bb The bucket brigade to create the char* from
+ * @param c The char* to write into
+ * @param len The maximum length of the char array. On return, it is the
+ * actual length of the char array.
+ */
+APU_DECLARE(apr_status_t) apr_brigade_getline(apr_bucket_brigade *bb,
+ char *c,
+ apr_size_t *len);
+
+/**
+ * Returns a pool-allocated string representing a flat bucket brigade
+ * @param bb The bucket brigade to create the iovec from
+ * @param p The pool to allocate the string from.
+ * Note: This string is NULL-terminated.
+ */
+APU_DECLARE(char *) apr_brigade_pgetline(apr_bucket_brigade *bb,
+ apr_pool_t *pool);
+
+/**
+ * Split a brigade to represent one LF line.
+ * @param bbOut The bucket brigade that will have the LF line appended to.
+ * @param bbIn The input bucket brigade to search for a LF-line.
+ * @param block The blocking mode to be used to split the line.
+ * @param maxbytes The maximum bytes to read. If this many bytes are seen
+ * without a LF, the brigade will contain a partial line.
+ */
+APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
+ apr_bucket_brigade *bbIn,
+ apr_read_type_e block,
+ apr_size_t maxbytes);
+
+/**
* create an iovec of the elements in a bucket_brigade... return number
* of elements used. This is useful for writing to a file or to the
* network efficiently.