}
void
-isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
+isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dbufp,
unsigned int length) {
- REQUIRE(dynbuffer != NULL && *dynbuffer == NULL);
+ REQUIRE(dbufp != NULL && *dbufp == NULL);
- isc_buffer_t *dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t));
- unsigned char *bdata = isc_mem_get(mctx, length);
+ isc_buffer_t *dbuf = isc_mem_get(mctx, sizeof(*dbuf) + length);
+ uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
isc_buffer_init(dbuf, bdata, length);
-
+ dbuf->extra = length;
dbuf->mctx = mctx;
- *dynbuffer = dbuf;
+ *dbufp = dbuf;
}
isc_result_t
-isc_buffer_reserve(isc_buffer_t *dynbuffer, unsigned int size) {
- size_t len;
+isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
+ REQUIRE(ISC_BUFFER_VALID(dbuf));
- REQUIRE(ISC_BUFFER_VALID(dynbuffer));
+ size_t len;
+ uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
- len = dynbuffer->length;
- if ((len - dynbuffer->used) >= size) {
+ len = dbuf->length;
+ if ((len - dbuf->used) >= size) {
return (ISC_R_SUCCESS);
}
- if (dynbuffer->mctx == NULL) {
+ if (dbuf->mctx == NULL) {
return (ISC_R_NOSPACE);
}
/* Round to nearest buffer size increment */
- len = size + dynbuffer->used;
- len = (len + ISC_BUFFER_INCR - 1 - ((len - 1) % ISC_BUFFER_INCR));
+ len = size + dbuf->used;
+ len = ISC_ALIGN(len, ISC_BUFFER_INCR);
/* Cap at UINT_MAX */
if (len > UINT_MAX) {
len = UINT_MAX;
}
- if ((len - dynbuffer->used) < size) {
+ if ((len - dbuf->used) < size) {
return (ISC_R_NOMEMORY);
}
- dynbuffer->base = isc_mem_reget(dynbuffer->mctx, dynbuffer->base,
- dynbuffer->length, len);
- dynbuffer->length = (unsigned int)len;
+ if (dbuf->base == bdata) {
+ dbuf->base = isc_mem_get(dbuf->mctx, len);
+ memmove(dbuf->base, bdata, dbuf->used);
+ } else {
+ dbuf->base = isc_mem_reget(dbuf->mctx, dbuf->base, dbuf->length,
+ len);
+ }
+ dbuf->length = (unsigned int)len;
return (ISC_R_SUCCESS);
}
void
-isc_buffer_free(isc_buffer_t **dynbuffer) {
- isc_buffer_t *dbuf;
- isc_mem_t *mctx;
+isc_buffer_free(isc_buffer_t **dbufp) {
+ REQUIRE(dbufp != NULL && ISC_BUFFER_VALID(*dbufp));
+ REQUIRE((*dbufp)->mctx != NULL);
- REQUIRE(dynbuffer != NULL);
- REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
- REQUIRE((*dynbuffer)->mctx != NULL);
+ isc_buffer_t *dbuf = *dbufp;
+ isc_mem_t *mctx = dbuf->mctx;
+ uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
+ unsigned int extra = dbuf->extra;
- dbuf = *dynbuffer;
- *dynbuffer = NULL; /* destroy external reference */
- mctx = dbuf->mctx;
+ *dbufp = NULL; /* destroy external reference */
dbuf->mctx = NULL;
- isc_mem_put(mctx, dbuf->base, dbuf->length);
+ if (dbuf->base != bdata) {
+ isc_mem_put(mctx, dbuf->base, dbuf->length);
+ }
+
isc_buffer_invalidate(dbuf);
- isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t));
+ isc_mem_put(mctx, dbuf, sizeof(*dbuf) + extra);
}
isc_result_t
* space in a buffer, we round the allocated buffer length up to the
* nearest * multiple of this value.
*/
-#define ISC_BUFFER_INCR 2048
+#define ISC_BUFFER_INCR 512
/*
* The following macros MUST be used only on valid buffers. It is the
unsigned int used;
unsigned int current;
unsigned int active;
+ /*! The extra bytes allocated for dynamic buffer */
+ unsigned int extra;
/*@}*/
/*! linkable */
ISC_LINK(isc_buffer_t) link;
isc_mem_t *mctx;
};
+#define ISC_BUFFER_STATIC_SIZE 512
+
/***
*** Functions
***/
isc_buffer_init(isc_buffer_t *b, void *base, unsigned int length) {
ISC_REQUIRE(b != NULL);
- *b = (isc_buffer_t){ .base = base,
- .length = length,
- .magic = ISC_BUFFER_MAGIC };
- ISC_LINK_INIT(b, link);
+ *b = (isc_buffer_t){
+ .base = base,
+ .length = length,
+ .link = ISC_LINK_INITIALIZER,
+ .magic = ISC_BUFFER_MAGIC,
+ };
}
/*!
*/
static inline void
isc_buffer_initnull(isc_buffer_t *b) {
- *b = (isc_buffer_t){ .magic = ISC_BUFFER_MAGIC };
- ISC_LINK_INIT(b, link);
+ *b = (isc_buffer_t){
+ .link = ISC_LINK_INITIALIZER,
+ .magic = ISC_BUFFER_MAGIC,
+ };
}
/*!
ISC_REQUIRE(!ISC_LINK_LINKED(b, link));
ISC_REQUIRE(b->mctx == NULL);
- b->magic = 0;
- b->base = NULL;
- b->length = 0;
- b->used = 0;
- b->current = 0;
- b->active = 0;
+ *b = (isc_buffer_t){
+ .magic = 0,
+ };
}
/*!
UNUSED(state);
b = NULL;
- isc_buffer_allocate(mctx, &b, 1024);
- assert_int_equal(b->length, 1024);
+ isc_buffer_allocate(mctx, &b, ISC_BUFFER_INCR);
+ assert_int_equal(b->length, ISC_BUFFER_INCR);
/*
- * 1024 bytes should already be available, so this call does
+ * 512 bytes should already be available, so this call does
* nothing.
*/
- result = isc_buffer_reserve(b, 1024);
+ result = isc_buffer_reserve(b, 512);
assert_int_equal(result, ISC_R_SUCCESS);
- assert_true(ISC_BUFFER_VALID(b));
assert_non_null(b);
- assert_int_equal(b->length, 1024);
+ assert_int_equal(b->length, ISC_BUFFER_INCR);
/*
- * This call should grow it to 2048 bytes as only 1024 bytes are
+ * This call should grow it to 1536 bytes as only 1024 bytes are
* available in the buffer.
*/
result = isc_buffer_reserve(b, 1025);
assert_int_equal(result, ISC_R_SUCCESS);
- assert_true(ISC_BUFFER_VALID(b));
assert_non_null(b);
- assert_int_equal(b->length, 2048);
+ assert_int_equal(b->length, 3 * ISC_BUFFER_INCR);
/*
- * 2048 bytes should already be available, so this call does
+ * 1536 bytes should already be available, so this call does
* nothing.
*/
- result = isc_buffer_reserve(b, 2000);
+ result = isc_buffer_reserve(b, 1500);
assert_int_equal(result, ISC_R_SUCCESS);
- assert_true(ISC_BUFFER_VALID(b));
assert_non_null(b);
- assert_int_equal(b->length, 2048);
+ assert_int_equal(b->length, 3 * ISC_BUFFER_INCR);
/*
- * This call should grow it to 4096 bytes as only 2048 bytes are
+ * This call should grow it to 4096 bytes as only 1536 bytes are
* available in the buffer.
*/
- result = isc_buffer_reserve(b, 3000);
+ result = isc_buffer_reserve(b, 3585);
assert_int_equal(result, ISC_R_SUCCESS);
- assert_true(ISC_BUFFER_VALID(b));
assert_non_null(b);
- assert_int_equal(b->length, 4096);
+ assert_int_equal(b->length, 8 * ISC_BUFFER_INCR);
/* Consume some of the buffer so we can run the next test. */
isc_buffer_add(b, 4096);
*/
result = isc_buffer_reserve(b, UINT_MAX);
assert_int_equal(result, ISC_R_NOMEMORY);
- assert_true(ISC_BUFFER_VALID(b));
assert_non_null(b);
- assert_int_equal(b->length, 4096);
+ assert_int_equal(b->length, 8 * ISC_BUFFER_INCR);
isc_buffer_free(&b);
}