isc_result_t isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) { unsigned char *bdata; REQUIRE(dynbuffer != NULL); REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); REQUIRE((*dynbuffer)->mctx != NULL); if ((*dynbuffer)->length > length) return (ISC_R_NOSPACE); /* * XXXMUKS: This is far more expensive than plain realloc() as * it doesn't remap pages, but does ordinary copy. So is * isc_mem_reallocate(), which has additional issues. */ bdata = isc_mem_get((*dynbuffer)->mctx, length); if (bdata == NULL) return (ISC_R_NOMEMORY); memmove(bdata, (*dynbuffer)->base, (*dynbuffer)->length); isc_mem_put((*dynbuffer)->mctx, (*dynbuffer)->base, (*dynbuffer)->length); (*dynbuffer)->base = bdata; (*dynbuffer)->length = length; return (ISC_R_SUCCESS); }
isc_result_t isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) { isc_uint64_t len; REQUIRE(dynbuffer != NULL); REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); len = (*dynbuffer)->length; if ((len - (*dynbuffer)->used) >= size) return (ISC_R_SUCCESS); if ((*dynbuffer)->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)); /* Cap at UINT_MAX */ if (len > UINT_MAX) { len = UINT_MAX; } if ((len - (*dynbuffer)->used) < size) return (ISC_R_NOMEMORY); return (isc_buffer_reallocate(dynbuffer, (unsigned int) len)); }
isc_result_t isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { unsigned char *base; unsigned int available; isc_result_t result; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); /* * XXXDCL */ base = isc_buffer_used(b); available = isc_buffer_availablelength(b); if (ISC_UNLIKELY(b->autore)) { result = isc_buffer_reserve(&b, r->length); if (result != ISC_R_SUCCESS) return (result); } if (r->length > available) return (ISC_R_NOSPACE); memmove(base, r->base, r->length); b->used += r->length; return (ISC_R_SUCCESS); }
isc_result_t isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, unsigned int length) { isc_buffer_t *dbuf; unsigned char * bdata; REQUIRE(dynbuffer != NULL); REQUIRE(*dynbuffer == NULL); dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t)); if (dbuf == NULL) return (ISC_R_NOMEMORY); bdata = isc_mem_get(mctx, length); if (bdata == NULL) { isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t)); return (ISC_R_NOMEMORY); } isc_buffer_init(dbuf, bdata, length); dbuf->mctx = mctx; ENSURE(ISC_BUFFER_VALID(dbuf)); *dynbuffer = dbuf; return (ISC_R_SUCCESS); }
void isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 4 <= b->length); ISC__BUFFER_PUTUINT32(b, val); }
/** * @pre closure points to a valid isc_buffer * @pre isc_buffer has non-NULL mctx * @pre isc_buffer has NULL buffer OR a buffer allocated from mctx * * @post closure contains \0 terminated string which is concatenation * of previous context and input text */ static void buffer_append_str(void *closure, const char *text, int textlen) { isc_buffer_t *out_buf = closure; isc_region_t new_space; isc_region_t old_space; REQUIRE(ISC_BUFFER_VALID(out_buf)); REQUIRE(out_buf->mctx != NULL); REQUIRE(text != NULL); /* Allocate sufficiently long output buffer. */ isc_buffer_region(out_buf, &old_space); new_space.length = isc_buffer_length(out_buf) + textlen + 1; new_space.base = isc_mem_get(out_buf->mctx, new_space.length); RUNTIME_CHECK(new_space.base != NULL); isc_buffer_reinit(out_buf, new_space.base, new_space.length); if (old_space.base != NULL) isc_mem_put(out_buf->mctx, old_space.base, old_space.length); /* Append output text and \0-terminate it. * Overwrite \0 at the end if needed. */ if (isc_buffer_usedlength(out_buf) != 0) /* Previous string is \0 terminated, chop \0. */ isc_buffer_subtract(out_buf, 1); isc_buffer_putstr(out_buf, text); isc_buffer_putuint8(out_buf, '\0'); }
void isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, unsigned int length) { REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + length <= b->length); ISC__BUFFER_PUTMEM(b, base, length); }
void isc__buffer_first(isc_buffer_t *b) { /* * Make the consumed region empty. */ REQUIRE(ISC_BUFFER_VALID(b)); ISC__BUFFER_FIRST(b); }
void isc__buffer_clear(isc_buffer_t *b) { /* * Make the used region empty. */ REQUIRE(ISC_BUFFER_VALID(b)); ISC__BUFFER_CLEAR(b); }
void isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the used region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_USEDREGION(b, r); }
void isc__buffer_subtract(isc_buffer_t *b, unsigned int n) { /* * Decrease the 'used' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used >= n); ISC__BUFFER_SUBTRACT(b, n); }
void isc__buffer_add(isc_buffer_t *b, unsigned int n) { /* * Increase the 'used' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + n <= b->length); ISC__BUFFER_ADD(b, n); }
void isc__buffer_back(isc_buffer_t *b, unsigned int n) { /* * Decrease the 'consumed' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(n <= b->current); ISC__BUFFER_BACK(b, n); }
void isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the remaining region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_REMAININGREGION(b, r); }
void isc__buffer_forward(isc_buffer_t *b, unsigned int n) { /* * Increase the 'consumed' region of 'b' by 'n' bytes. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->current + n <= b->used); ISC__BUFFER_FORWARD(b, n); }
void isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the available region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_AVAILABLEREGION(b, r); }
void isc__buffer_setactive(isc_buffer_t *b, unsigned int n) { /* * Sets the end of the active region 'n' bytes after current. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->current + n <= b->used); ISC__BUFFER_SETACTIVE(b, n); }
void isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) { /* * Make 'r' refer to the active region of 'b'. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); ISC__BUFFER_ACTIVEREGION(b, r); }
void isc__buffer_invalidate(isc_buffer_t *b) { /* * Make 'b' an invalid buffer. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(!ISC_LINK_LINKED(b, link)); REQUIRE(b->mctx == NULL); ISC__BUFFER_INVALIDATE(b); }
void isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) { isc_result_t result; REQUIRE(ISC_BUFFER_VALID(b)); if (ISC_UNLIKELY(b->autore)) { result = isc_buffer_reserve(&b, 4); REQUIRE(result == ISC_R_SUCCESS); } REQUIRE(isc_buffer_availablelength(b) >= 4); ISC__BUFFER_PUTUINT32(b, val); }
void isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) { isc_uint16_t valhi; isc_uint32_t vallo; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used + 6 <= b->length); valhi = (isc_uint16_t)(val >> 32); vallo = (isc_uint32_t)(val & 0xFFFFFFFF); ISC__BUFFER_PUTUINT16(b, valhi); ISC__BUFFER_PUTUINT32(b, vallo); }
void isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base, unsigned int length) { isc_result_t result; REQUIRE(ISC_BUFFER_VALID(b)); if (ISC_UNLIKELY(b->autore)) { result = isc_buffer_reserve(&b, length); REQUIRE(result == ISC_R_SUCCESS); } REQUIRE(isc_buffer_availablelength(b) >= length); ISC__BUFFER_PUTMEM(b, base, length); }
unsigned int isc_bufferlist_availablecount(isc_bufferlist_t *bl) { isc_buffer_t *buffer; unsigned int length; REQUIRE(bl != NULL); length = 0; buffer = ISC_LIST_HEAD(*bl); while (buffer != NULL) { REQUIRE(ISC_BUFFER_VALID(buffer)); length += isc_buffer_availablelength(buffer); buffer = ISC_LIST_NEXT(buffer, link); } return (length); }
void isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) { isc_result_t result; isc_uint16_t valhi; isc_uint32_t vallo; REQUIRE(ISC_BUFFER_VALID(b)); if (ISC_UNLIKELY(b->autore)) { result = isc_buffer_reserve(&b, 6); REQUIRE(result == ISC_R_SUCCESS); } REQUIRE(isc_buffer_availablelength(b) >= 6); valhi = (isc_uint16_t)(val >> 32); vallo = (isc_uint32_t)(val & 0xFFFFFFFF); ISC__BUFFER_PUTUINT16(b, valhi); ISC__BUFFER_PUTUINT32(b, vallo); }
isc_uint8_t isc_buffer_getuint8(isc_buffer_t *b) { unsigned char *cp; isc_uint8_t result; /* * Read an unsigned 8-bit integer from 'b' and return it. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 1); cp = isc_buffer_current(b); b->current += 1; result = ((isc_uint8_t)(cp[0])); return (result); }
void isc_buffer_free(isc_buffer_t **dynbuffer) { isc_buffer_t *dbuf; isc_mem_t *mctx; REQUIRE(dynbuffer != NULL); REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); REQUIRE((*dynbuffer)->mctx != NULL); dbuf = *dynbuffer; *dynbuffer = NULL; /* destroy external reference */ mctx = dbuf->mctx; dbuf->mctx = NULL; isc_mem_put(mctx, dbuf->base, dbuf->length); isc_buffer_invalidate(dbuf); isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t)); }
void isc__buffer_putstr(isc_buffer_t *b, const char *source) { unsigned int l; unsigned char *cp; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(source != NULL); /* * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once. */ l = strlen(source); REQUIRE(l <= isc_buffer_availablelength(b)); cp = isc_buffer_used(b); memcpy(cp, source, l); b->used += l; }
isc_result_t isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { unsigned char *base; unsigned int available; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); /* * XXXDCL */ base = isc_buffer_used(b); available = isc_buffer_availablelength(b); if (r->length > available) return (ISC_R_NOSPACE); memcpy(base, r->base, r->length); b->used += r->length; return (ISC_R_SUCCESS); }
isc_uint16_t isc_buffer_getuint16(isc_buffer_t *b) { unsigned char *cp; isc_uint16_t result; /* * Read an unsigned 16-bit integer in network byte order from 'b', * convert it to host byte order, and return it. */ REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(b->used - b->current >= 2); cp = isc_buffer_current(b); b->current += 2; result = ((unsigned int)(cp[0])) << 8; result |= ((unsigned int)(cp[1])); return (result); }
isc_result_t isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src) { isc_buffer_t *dst = NULL; isc_region_t region; isc_result_t result; REQUIRE(dstp != NULL && *dstp == NULL); REQUIRE(ISC_BUFFER_VALID(src)); isc_buffer_usedregion(src, ®ion); result = isc_buffer_allocate(mctx, &dst, region.length); if (result != ISC_R_SUCCESS) return (result); result = isc_buffer_copyregion(dst, ®ion); RUNTIME_CHECK(result == ISC_R_SUCCESS); /* NOSPACE is impossible */ *dstp = dst; return (ISC_R_SUCCESS); }