Yes, thanks for looking at it, Eric. It is correct after I flatten it: output: _ASCII_String0_!__ASCII_String4_!ASCII_String1_!_ASCII_String2_!_ASCII_String3_! but not when reading the bucket with apr_bucket_read(Index, &TestBuffer, &Length, APR_BLOCK_READ): Marker: 1 CurrBucket: _ASCII_String1_! Length: 1 Bucket1 is not just "_". It looks like apr_bucket_read returns the memory location of the original string and does no manipulation like null termination when splitting. So I guess that I cannot simply call printf, and that I must either use putchar with a loop or snprintf, strncpy, memcpy, etc. One of the reasons for this exercise is to understand the difference between transient and immortal buckets. I don't get memory errors when running valgrind and mis-matching the transient, immortal, and even pool buckets with the memory they were used to create them. I don't want to embark on using this library without a good understanding of what is going on. I have a better idea now, but still many questions remain. I looked at http://www.apachetutor.org/dev/brigades, but that doesn't explain much. The tests in the source code archive helped a bit. Is there any good reading about this on the interwebs? ;) Simon On 01/02/2018 12:51 AM, Eric Covener wrote: >> I see such code as the example you gave in various places. However, this >> bit of code (attached) shows me that I cannot simply printf the data. >> Again, I am probably doing something wrong. >> > > The output looks right to me but maybe I am misunderstanding the > intent of the example. > > output: _ASCII_String0_!__ASCII_String4_!ASCII_String1_!_ASCII_String2_!_ASCII_String3_! > ^ extra underscore is b1 > ^ b4 inserted heree > ^ > b1_1 and the missing underscore from the split and > > > You start with b0,b1,b2,b3 and iterate over the brigade. > > While looking at b1, you split it at index 1 into two buckets. b1 is > now just "_" and b1_1 is the rest. > > b0, b1, b1_1, b2, b3 > > You then insert b4 after b1: > > b0, b1, b1_1, b2, b3 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx > For additional commands, e-mail: users-help@xxxxxxxxxxxxxxxx >
#include <stdlib.h> #include <linux/limits.h> #include <apr-1.0/apr_buckets.h> int main(int ArgCount, char * Arg[]) { apr_initialize(); atexit(apr_terminate); apr_pool_t * Pool; apr_pool_create(&Pool, NULL); apr_bucket_alloc_t * BucketAlloc = apr_bucket_alloc_create(Pool); apr_bucket_brigade * Brigade = apr_brigade_create(Pool, BucketAlloc); char * String0 = calloc(strlen("_ASCII_String0_!") + 1, 1); strcpy(String0, "_ASCII_String0_!"); printf("Address of String0 = %p\n", (void *)(String0)); apr_bucket * Bucket0 = apr_bucket_immortal_create(String0, strlen(String0), BucketAlloc); APR_BRIGADE_INSERT_TAIL(Brigade, Bucket0); char * String1 = calloc(strlen("_ASCII_String1_!") + 1, 1); strcpy(String1, "_ASCII_String1_!"); printf("Address of String1 = %p\n", (void *)(String1)); apr_bucket * Bucket1 = apr_bucket_immortal_create(String1, strlen(String1), BucketAlloc); APR_BRIGADE_INSERT_TAIL(Brigade, Bucket1); char * String2 = "_ASCII_String2_!"; printf("Address of String2 = %p\n", (void *)(String2)); apr_bucket * Bucket2 = apr_bucket_transient_create(String2, strlen(String2), BucketAlloc); APR_BRIGADE_INSERT_TAIL(Brigade, Bucket2); char * String3 = "_ASCII_String3_!"; printf("Address of String3 = %p\n", (void *)(String3)); apr_bucket * Bucket3 = apr_bucket_transient_create(String3, strlen(String3), BucketAlloc); APR_BRIGADE_INSERT_TAIL(Brigade, Bucket3); char * String4 = apr_pcalloc(Pool, strlen("_ASCII_String4_!") + 1); strcpy(String4, "_ASCII_String4_!"); printf("Address of String4 = %p\n", (void *)(String4)); apr_bucket * Bucket4 = apr_bucket_pool_create(String4, strlen(String4), Pool, BucketAlloc); apr_bucket * Index; const char * TestBuffer = NULL; int Marker = 0; int PutIndex = 0; size_t Length = 0; for (Index = APR_BRIGADE_FIRST(Brigade); Index != APR_BRIGADE_SENTINEL(Brigade); Index = APR_BUCKET_NEXT(Index)) { printf("Marker: %d\n", Marker); if (Marker == 1) { apr_bucket_split(Index, 1); printf("Address of String1 + 1 = %p\n", (void *)(String1 + 1)); APR_BUCKET_INSERT_AFTER(Index, Bucket4); } TestBuffer = NULL; Length = 0; if (apr_bucket_read(Index, &TestBuffer, &Length, APR_BLOCK_READ) == APR_SUCCESS) { printf("CurrBucket: "); PutIndex = 0; while (PutIndex < Length) putchar(*(TestBuffer + PutIndex++)); printf("\n"); printf("Address of TestBuffer = %p\n", (void *)(TestBuffer)); printf("Length: %zu\n", Length); } Marker++; } char * Output0 = NULL; apr_size_t Output0Length = 0; apr_brigade_pflatten(Brigade, &Output0, &Output0Length, Pool); printf("Output0: %s\n", Output0); printf("Output0 Length: %zu\n", Output0Length); printf("Address of Output0 = %p\n", (void *)(Output0)); apr_off_t BrigadeLength; apr_brigade_length(Brigade, 1, &BrigadeLength); printf("BrigadeLength Length: %zu\n", BrigadeLength); char * Output1 = calloc(BrigadeLength + 1, 1); apr_size_t Output1Length = BrigadeLength; apr_brigade_flatten(Brigade, Output1, &Output1Length); printf("Output1: %s\n", Output1); printf("Output1 Length: %zu\n", Output1Length); printf("Address of Output1 = %p\n", (void *)(Output1)); free(String0); free(String1); free(Output1); apr_pool_destroy(Pool); }
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx For additional commands, e-mail: users-help@xxxxxxxxxxxxxxxx