Added function to append cloned data from another buffer (to be used by TCP).

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19370 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-11-25 14:30:54 +00:00
parent 604d21a600
commit 224e38e302
2 changed files with 68 additions and 1 deletions
+2
View File
@@ -61,6 +61,8 @@ struct net_buffer_module_info {
status_t (*remove_header)(net_buffer *buffer, size_t bytes); status_t (*remove_header)(net_buffer *buffer, size_t bytes);
status_t (*remove_trailer)(net_buffer *buffer, size_t bytes); status_t (*remove_trailer)(net_buffer *buffer, size_t bytes);
status_t (*trim)(net_buffer *buffer, size_t newSize); status_t (*trim)(net_buffer *buffer, size_t newSize);
status_t (*append_cloned)(net_buffer *buffer, net_buffer *source,
uint32 offset, size_t bytes);
status_t (*associate_data)(net_buffer *buffer, void *data); status_t (*associate_data)(net_buffer *buffer, void *data);
@@ -60,7 +60,7 @@ static status_t remove_header(net_buffer *_buffer, size_t bytes);
static status_t remove_trailer(net_buffer *_buffer, size_t bytes); static status_t remove_trailer(net_buffer *_buffer, size_t bytes);
#if 0 #if 1
static void static void
dump_buffer(net_buffer *_buffer) dump_buffer(net_buffer *_buffer)
{ {
@@ -837,6 +837,70 @@ trim_data(net_buffer *_buffer, size_t newSize)
} }
/*!
Appends data coming from buffer \a source to the buffer \a buffer. It only
clones the data, though, that is the data is not copied, just referenced.
*/
status_t
append_cloned_data(net_buffer *_buffer, net_buffer *_source, uint32 offset,
size_t bytes)
{
net_buffer_private *buffer = (net_buffer_private *)_buffer;
net_buffer_private *source = (net_buffer_private *)_source;
TRACE(("append_cloned_data(buffer %p, source %p, offset = %ld, bytes = %ld)\n",
buffer, source, offset, bytes));
if (source->size < offset + bytes)
return B_BAD_VALUE;
// find data_node to start with from the source buffer
data_node *node = (data_node *)list_get_first_item(&source->buffers);
while (node->offset + node->used < offset) {
node = (data_node *)list_get_next_item(&source->buffers, node);
if (node == NULL) {
// trim size greater than buffer size
return B_BAD_VALUE;
}
}
while (node != NULL && bytes > 0) {
data_node *clone = (data_node *)alloc_data_header_space(node->header,
sizeof(data_node));
if (clone == NULL) {
// There is not enough space in the buffer for another node
// TODO: handle this case!
panic("appending clone buffer in new header not implemented\n");
return ENOBUFS;
}
if (offset)
offset -= node->offset;
clone->header = node->header;
clone->offset = buffer->size;
clone->start = node->start + offset;
clone->used = min_c(bytes, node->used - offset);
clone->header_space = 0;
clone->tail_space = 0;
list_add_item(&buffer->buffers, clone);
offset = 0;
bytes -= clone->used;
buffer->size += clone->used;
node = (data_node *)list_get_next_item(&source->buffers, node);
}
if (bytes != 0)
panic("add_cloned_data() failed, bytes != 0!\n");
dprintf(" append cloned result:\n");
dump_buffer(buffer);
return B_OK;
}
/*! /*!
Tries to directly access the requested space in the buffer. Tries to directly access the requested space in the buffer.
If the space is contiguous, the function will succeed and place a pointer If the space is contiguous, the function will succeed and place a pointer
@@ -1006,6 +1070,7 @@ net_buffer_module_info gNetBufferModule = {
remove_header, remove_header,
remove_trailer, remove_trailer,
trim_data, trim_data,
append_cloned_data,
NULL, // associate_data NULL, // associate_data