Commit 185ab78c authored by Lubomir Bulej's avatar Lubomir Bulej

Update byte buffer implementation

parent c67b40ac
#include "bufferbase.h"
#include "bytebuffer.h"
#include "bufferpack.h"
#include <string.h>
......@@ -25,42 +25,42 @@
void
buffer_append_jboolean (buffer_t * restrict buffer, jboolean value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (jboolean));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (jboolean));
*((jboolean *) dest) = value;
}
void
buffer_append_jbyte (buffer_t * restrict buffer, jbyte value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (jbyte));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (jbyte));
*((jbyte *) dest) = value;
}
void
buffer_append_jchar (buffer_t * restrict buffer, jchar value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (jchar));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (jchar));
*((jchar *) dest) = htons (value);
}
void
buffer_append_jshort (buffer_t * restrict buffer, jshort value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (jshort));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (jshort));
*((jshort *) dest) = htons (value);
}
void
buffer_append_jint (buffer_t * restrict buffer, jint value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (jint));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (jint));
*((jint *) dest) = htonl (value);
}
void
buffer_append_jlong (buffer_t * restrict buffer, jlong value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (jlong));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (jlong));
*((jlong *) dest) = htobe64 (value);
}
......@@ -88,9 +88,16 @@ buffer_append_jdouble (buffer_t * restrict buffer, jdouble value) {
//
void
buffer_append_uint8 (buffer_t * restrict buffer, uint8_t value) {
uint8_t * restrict dest = buffer_claim (buffer, sizeof (uint8_t));
*dest = value;
}
void
buffer_append_uint16 (buffer_t * restrict buffer, uint16_t value) {
uint8_t * restrict dest = buffer_reserve (buffer, sizeof (uint16_t));
uint8_t * restrict dest = buffer_claim (buffer, sizeof (uint16_t));
*((uint16_t *) dest) = htons (value);
}
......@@ -99,7 +106,7 @@ void
buffer_append_bytes (
buffer_t * restrict buffer, const void * restrict bytes, size_t count
) {
uint8_t * restrict dest = buffer_reserve (buffer, count);
uint8_t * restrict dest = buffer_claim (buffer, count);
memcpy (dest, bytes, count);
}
......@@ -107,21 +114,21 @@ buffer_append_bytes (
void
buffer_put_jshort (buffer_t * restrict buffer, jshort value, size_t position) {
uint8_t * restrict dest = buffer_ptr (buffer, position, sizeof (jshort));
uint8_t * restrict dest = buffer_ptr_block (buffer, position, sizeof (jshort));
*((jshort *) dest) = htons (value);
}
void
buffer_put_jint (buffer_t * restrict buffer, jint value, size_t position) {
uint8_t * restrict dest = buffer_ptr (buffer, position, sizeof (jint));
uint8_t * restrict dest = buffer_ptr_block (buffer, position, sizeof (jint));
*((jint *) dest) = htonl (value);
}
void
buffer_put_jlong (buffer_t * restrict buffer, jlong value, size_t position) {
uint8_t * restrict dest = buffer_ptr (buffer, position, sizeof (jlong));
uint8_t * restrict dest = buffer_ptr_block (buffer, position, sizeof (jlong));
*((jlong *) dest) = htobe64 (value);
}
......@@ -129,9 +136,23 @@ buffer_put_jlong (buffer_t * restrict buffer, jlong value, size_t position) {
void
buffer_append_utf8 (
buffer_t * restrict buffer, const uint8_t * value, uint16_t length
buffer_t * restrict buffer, const char * value, uint16_t length
) {
// Encode length followed by the UTF-encoded bytes.
buffer_append_uint16 (buffer, length);
buffer_append_bytes (buffer, value, length);
}
/**
* Drains all bytes from the source buffer to the destination
* buffer. The source buffer is cleared upon completion.
*/
void
buffer_drain_to (buffer_t * restrict src, buffer_t * restrict dst) {
size_t src_len = buffer_length (src);
uint8_t * src_bytes = buffer_ptr_block (src, 0, src_len);
buffer_append_bytes (dst, src_bytes, src_len);
buffer_clear (src);
}
#ifndef _BUFFERPACK_H_
#define _BUFFERPACK_H_
#include "bufferbase.h"
#include "bytebuffer.h"
#include <jvmti.h>
#include <stdint.h>
......@@ -19,6 +19,7 @@ void buffer_append_jdouble (buffer_t * restrict buffer, jdouble value);
//
void buffer_append_uint8 (buffer_t * restrict buffer, uint8_t value);
void buffer_append_uint16 (buffer_t * restrict buffer, uint16_t value);
void buffer_append_bytes (
......@@ -34,7 +35,9 @@ void buffer_put_jlong (buffer_t * restrict buffer, jlong value, size_t position)
//
void buffer_append_utf8 (
buffer_t * restrict buffer, const uint8_t * value, uint16_t length
buffer_t * restrict buffer, const char * value, uint16_t length
);
void buffer_drain_to (buffer_t * restrict src, buffer_t * restrict dst);
#endif /* _BUFFERPACK_H_ */
#include "bufferbase.h"
#include "bytebuffer.h"
#include "../common.h"
#include <assert.h>
......@@ -25,15 +25,8 @@ __buffer_assign (
static inline uint8_t *
__alloc_bytes (size_t capacity) {
assert (capacity > 0);
uint8_t * bytes = (uint8_t *) malloc (capacity);
check_error (
bytes != NULL,
"failed to allocate buffer of %u bytes", capacity
);
check_error (bytes == NULL, "failed to allocate %zu bytes", capacity);
return bytes;
}
......@@ -45,6 +38,7 @@ __alloc_bytes (size_t capacity) {
void
buffer_init (buffer_t * restrict buffer, const size_t capacity) {
assert (buffer != NULL);
assert (capacity > 0);
uint8_t * bytes = __alloc_bytes (capacity);
__buffer_assign (buffer, bytes, 0, capacity);
......@@ -80,36 +74,34 @@ __calculate_capacity (
}
static inline size_t
__buffer_remaining (const buffer_t * restrict buffer) {
// Capacity is always greater than position
return buffer->capacity - buffer->position;
}
/**
* Ensure that the given buffer has enough remaining scape to
* accomodate the given number of bytes. If necessary, the buffer
* is expanded to accomodate the requirement. Returns the new
* capacity of the buffer.
*/
size_t
buffer_ensure_capacity (buffer_t * restrict buffer, const size_t bytes_needed) {
assert (buffer != NULL);
static size_t
__buffer_ensure_remaining (buffer_t * restrict buffer, const size_t bytes_needed) {
//
// If the buffer does not have enough space remaining to accomodate
// the space needed, double the buffer capacity until it can do so.
// Then copy the buffer and update the capacity.
//
if (buffer_remaining (buffer) < bytes_needed) {
if (__buffer_remaining (buffer) < bytes_needed) {
size_t new_capacity = __calculate_capacity (
buffer_capacity (buffer), buffer_position (buffer),
bytes_needed
);
uint8_t * restrict new_bytes = (uint8_t *) malloc (new_capacity);
check_error (
new_bytes == NULL,
"failed to expand buffer from %u to %u bytes",
buffer_capacity (buffer), new_capacity
buffer->capacity, buffer_length (buffer), bytes_needed
);
uint8_t * restrict new_bytes = __alloc_bytes (new_capacity);
uint8_t * restrict old_bytes = buffer->bytes;
memcpy (new_bytes, old_bytes, buffer_position (buffer));
memcpy (new_bytes, old_bytes, buffer_length (buffer));
buffer->bytes = new_bytes;
buffer->capacity = new_capacity;
......@@ -117,69 +109,62 @@ buffer_ensure_capacity (buffer_t * restrict buffer, const size_t bytes_needed) {
free (old_bytes);
}
return buffer_capacity (buffer);
return buffer->capacity;
}
static inline uint8_t *
__buffer_ptr (const buffer_t * restrict buffer, size_t position) {
__buffer_ptr_at (const buffer_t * restrict buffer, size_t position) {
return buffer->bytes + position;
}
static inline uint8_t *
__buffer_ptr (const buffer_t * restrict buffer) {
return buffer->bytes + buffer->position;
}
/**
* Returns a pointer to a block of memory at the given position
* in the buffer. The block must be within the occupied part of
* the buffer and the block size must be greater than 0.
* Returns a pointer to a block of memory at the given position in the buffer.
* The block must be within the occupied part of the buffer and the block size
* must be greater than 0.
*/
uint8_t *
buffer_ptr (const buffer_t * restrict buffer, size_t position, size_t size) {
buffer_ptr_block (const buffer_t * restrict buffer, size_t position, size_t size) {
assert (buffer != NULL);
assert (size > 0);
const size_t end_position = position + size;
const size_t length = buffer_length (buffer);
check_error (
end_position > buffer_position (buffer),
"trying to get pointer to %u bytes at %u with only %u bytes present",
size, position, buffer_position (buffer)
end_position > length,
"trying to get pointer to %zu bytes at "
"position %zu in buffer with %zu bytes",
size, position, length
);
return __buffer_ptr (buffer, position);
return __buffer_ptr_at (buffer, position);
}
/**
* Returns a pointer to a block of memory of given size within
* the buffer, starting at the current position. If the buffer
* does not have enough remaining space, it is expanded to
* accomodate the requirement.
* Claims a block of given size starting at the current position in
* the given buffer and returns a pointer to the block. If necessary,
* the capacity of the buffer is expanded to accomodate the block.
*
* NOTE: The caller should never store pointers to the buffer between
* operations that might enlarge the buffer.
*/
uint8_t *
buffer_reserve (buffer_t * buffer, size_t size) {
buffer_claim (buffer_t * restrict buffer, const size_t size) {
assert (buffer != NULL);
assert (size > 0);
buffer_ensure_capacity (buffer, size);
__buffer_ensure_remaining (buffer, size);
size_t position = buffer_position (buffer);
uint8_t * result = __buffer_ptr (buffer, position);
uint8_t * result = __buffer_ptr (buffer);
buffer->position += size;
return result;
}
/**
* Copies a bytes from the buffer. The given position and number
* of bytes to copy must fit within the occupied space of the
* buffer. The destination buffer must have enough space and
* MUST NOT overlap with the given buffer's data space.
*/
void
buffer_get_bytes_at (
const buffer_t * restrict buffer, size_t position,
void * restrict dest, size_t count
) {
uint8_t * src = buffer_ptr (buffer, position, count);
memcpy (dest, (void * restrict) src, count);
}
#ifndef _BUFFERBASE_H_
#define _BUFFERBASE_H_
#ifndef _BYTEBUFFER_H_
#define _BYTEBUFFER_H_
#include <stdlib.h>
#include <stdint.h>
#define BUFFER_INITIAL_CAPACITY 512
typedef struct {
uint8_t * restrict bytes;
size_t position;
......@@ -16,14 +18,7 @@ typedef struct {
void buffer_init (buffer_t * restrict buffer, const size_t capacity);
void buffer_destroy (buffer_t * restrict buffer);
inline size_t
buffer_capacity (const buffer_t * restrict buffer) {
return buffer->capacity;
}
size_t buffer_ensure_capacity (buffer_t * restrict buffer, size_t capacity);
uint8_t * buffer_reserve (buffer_t * restrict buffer, size_t size);
uint8_t * buffer_claim (buffer_t * restrict buffer, const size_t size);
inline size_t
buffer_position (const buffer_t * restrict buffer) {
......@@ -31,9 +26,8 @@ buffer_position (const buffer_t * restrict buffer) {
}
inline size_t
buffer_remaining (const buffer_t * restrict buffer) {
// Capacity is always greater than position
return buffer->capacity - buffer->position;
buffer_length (const buffer_t * restrict buffer) {
return buffer->position;
}
inline void
......@@ -41,8 +35,8 @@ buffer_clear (buffer_t * restrict buffer) {
buffer->position = 0;
}
uint8_t * buffer_ptr (
uint8_t * buffer_ptr_block (
const buffer_t * restrict buffer, size_t position, size_t size
);
#endif /* _BUFFERBASE_H_ */
#endif /* _BYTEBUFFER_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment