Simple in-memory buckets
When we created transient buckets above, we were inserting a chunk of
memory in the output stream. But we noted
that this bucket was not the most efficient way to escape a
character. The reason for this is that the transient memory has to be
copied internally to prevent it going out of scope. We could instead
have used memory that's guaranteed never to go out of scope, by replacing
case '<': return apr_bucket_transient_create("<", 4, alloc) ;
with
static const char* lt = "<" ;
...
case '<': return apr_bucket_immortal_create(lt, 4, alloc) ;
When we create an immortal bucket, we guarantee that the memory won't go
out of scope during the lifetime of the bucket, so the APR never needs
to copy it internally.
A third variant on the same principle is the pool bucket. This refers
to memory allocated on a pool, and will have to
be copied internally if and only if the pool is destroyed within the
lifetime of the bucket.