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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user