#include <stdlib.h>
#include <isc/buffer.h>
#include <isc/region.h>
#include <string.h>
#include <isc/util.h>
void
isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) {
REQUIRE(b != NULL);
ISC__BUFFER_INIT(b, base, length);
}
void
isc__buffer_invalidate(isc_buffer_t *b) {
REQUIRE(!ISC_LINK_LINKED(b, link));
ISC__BUFFER_INVALIDATE(b);
}
void
isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
REQUIRE(r != NULL);
ISC__BUFFER_USEDREGION(b, r);
}
void
isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
REQUIRE(r != NULL);
ISC__BUFFER_AVAILABLEREGION(b, r);
}
void
isc__buffer_add(isc_buffer_t *b, unsigned int n) {
REQUIRE(b->used + n <= b->length);
ISC__BUFFER_ADD(b, n);
}
void
isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
REQUIRE(b->used >= n);
ISC__BUFFER_SUBTRACT(b, n);
}
void
isc__buffer_clear(isc_buffer_t *b) {
ISC__BUFFER_CLEAR(b);
}
void
isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
REQUIRE(r != NULL);
ISC__BUFFER_REMAININGREGION(b, r);
}
void
isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
REQUIRE(r != NULL);
ISC__BUFFER_ACTIVEREGION(b, r);
}
void
isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
REQUIRE(b->current + n <= b->used);
ISC__BUFFER_SETACTIVE(b, n);
}
void
isc__buffer_first(isc_buffer_t *b) {
ISC__BUFFER_FIRST(b);
}
void
isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
REQUIRE(b->current + n <= b->used);
ISC__BUFFER_FORWARD(b, n);
}
void
isc_buffer_compact(isc_buffer_t *b) {
unsigned int length;
void *src;
src = isc_buffer_current(b);
length = isc_buffer_remaininglength(b);
(void)memmove(b->base, src, (size_t)length);
if (b->active > b->current)
b->active -= b->current;
else
b->active = 0;
b->current = 0;
b->used = length;
}
uint8_t
isc_buffer_getuint8(isc_buffer_t *b) {
unsigned char *cp;
uint8_t result;
REQUIRE(b->used - b->current >= 1);
cp = isc_buffer_current(b);
b->current += 1;
result = ((uint8_t)(cp[0]));
return (result);
}
void
isc__buffer_putuint8(isc_buffer_t *b, uint8_t val) {
REQUIRE(b->used + 1 <= b->length);
ISC__BUFFER_PUTUINT8(b, val);
}
uint16_t
isc_buffer_getuint16(isc_buffer_t *b) {
unsigned char *cp;
uint16_t result;
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);
}
void
isc__buffer_putuint16(isc_buffer_t *b, uint16_t val) {
REQUIRE(b->used + 2 <= b->length);
ISC__BUFFER_PUTUINT16(b, val);
}
uint32_t
isc_buffer_getuint32(isc_buffer_t *b) {
unsigned char *cp;
uint32_t result;
REQUIRE(b->used - b->current >= 4);
cp = isc_buffer_current(b);
b->current += 4;
result = ((unsigned int)(cp[0])) << 24;
result |= ((unsigned int)(cp[1])) << 16;
result |= ((unsigned int)(cp[2])) << 8;
result |= ((unsigned int)(cp[3]));
return (result);
}
void
isc__buffer_putuint32(isc_buffer_t *b, uint32_t val) {
REQUIRE(b->used + 4 <= b->length);
ISC__BUFFER_PUTUINT32(b, val);
}
void
isc__buffer_putuint48(isc_buffer_t *b, uint64_t val) {
uint16_t valhi;
uint32_t vallo;
REQUIRE(b->used + 6 <= b->length);
valhi = (uint16_t)(val >> 32);
vallo = (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)
{
REQUIRE(b->used + length <= b->length);
ISC__BUFFER_PUTMEM(b, base, length);
}
void
isc__buffer_putstr(isc_buffer_t *b, const char *source) {
unsigned int l;
unsigned char *cp;
REQUIRE(source != NULL);
l = strlen(source);
REQUIRE(l <= isc_buffer_availablelength(b));
cp = isc_buffer_used(b);
memmove(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(r != NULL);
base = isc_buffer_used(b);
available = isc_buffer_availablelength(b);
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_buffer_t **dynbuffer,
unsigned int length)
{
isc_buffer_t *dbuf;
REQUIRE(dynbuffer != NULL);
REQUIRE(*dynbuffer == NULL);
dbuf = malloc(length + sizeof(isc_buffer_t));
if (dbuf == NULL)
return (ISC_R_NOMEMORY);
isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t),
length);
*dynbuffer = dbuf;
return (ISC_R_SUCCESS);
}
void
isc_buffer_free(isc_buffer_t **dynbuffer) {
isc_buffer_t *dbuf;
REQUIRE(dynbuffer != NULL);
dbuf = *dynbuffer;
*dynbuffer = NULL;
isc_buffer_invalidate(dbuf);
free(dbuf);
}
isc_result_t
isc_mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
isc_region_t tr;
isc_buffer_availableregion(target, &tr);
if (length > tr.length)
return (ISC_R_NOSPACE);
memmove(tr.base, base, length);
isc_buffer_add(target, length);
return (ISC_R_SUCCESS);
}
isc_result_t
isc_str_tobuffer(const char *source, isc_buffer_t *target) {
unsigned int l;
isc_region_t region;
isc_buffer_availableregion(target, ®ion);
l = strlen(source);
if (l > region.length)
return (ISC_R_NOSPACE);
memmove(region.base, source, l);
isc_buffer_add(target, l);
return (ISC_R_SUCCESS);
}