network/stack: Add clone_ancillary_data.
Change-Id: I98a56344ffbf0c691a797ad7ce69ba1de08bbbee Reviewed-on: https://review.haiku-os.org/c/haiku/+/9859 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
@@ -175,6 +175,7 @@ struct net_stack_module_info {
|
|||||||
status_t (*add_ancillary_data)(ancillary_data_container* container,
|
status_t (*add_ancillary_data)(ancillary_data_container* container,
|
||||||
const ancillary_data_header* header, const void* data,
|
const ancillary_data_header* header, const void* data,
|
||||||
void (*destructor)(const ancillary_data_header*, void*),
|
void (*destructor)(const ancillary_data_header*, void*),
|
||||||
|
void (*clone)(const ancillary_data_header*, void*),
|
||||||
void** _allocatedData);
|
void** _allocatedData);
|
||||||
status_t (*remove_ancillary_data)(ancillary_data_container* container,
|
status_t (*remove_ancillary_data)(ancillary_data_container* container,
|
||||||
void* data, bool destroy);
|
void* data, bool destroy);
|
||||||
@@ -182,6 +183,8 @@ struct net_stack_module_info {
|
|||||||
ancillary_data_container* to);
|
ancillary_data_container* to);
|
||||||
void* (*next_ancillary_data)(const ancillary_data_container* container,
|
void* (*next_ancillary_data)(const ancillary_data_container* container,
|
||||||
void* previousData, ancillary_data_header* _header);
|
void* previousData, ancillary_data_header* _header);
|
||||||
|
status_t (*clone_ancillary_data)(const ancillary_data_container* from,
|
||||||
|
ancillary_data_container* to);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ unix_add_ancillary_data(net_protocol *self, ancillary_data_container *container,
|
|||||||
"container\n", find_thread(NULL), count);
|
"container\n", find_thread(NULL), count);
|
||||||
|
|
||||||
error = gStackModule->add_ancillary_data(container, &header,
|
error = gStackModule->add_ancillary_data(container, &header,
|
||||||
descriptors, destroy_scm_rights_descriptors, NULL);
|
descriptors, destroy_scm_rights_descriptors, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup on error
|
// cleanup on error
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct ancillary_data : DoublyLinkedListLinkImpl<ancillary_data> {
|
|||||||
|
|
||||||
ancillary_data_header header;
|
ancillary_data_header header;
|
||||||
void (*destructor)(const ancillary_data_header*, void*);
|
void (*destructor)(const ancillary_data_header*, void*);
|
||||||
|
void (*clone)(const ancillary_data_header*, void*);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DoublyLinkedList<ancillary_data> ancillary_data_list;
|
typedef DoublyLinkedList<ancillary_data> ancillary_data_list;
|
||||||
@@ -69,6 +70,8 @@ delete_ancillary_data_container(ancillary_data_container* container)
|
|||||||
\param data If not \c NULL, the data are copied into the allocated storage.
|
\param data If not \c NULL, the data are copied into the allocated storage.
|
||||||
\param destructor If not \c NULL, this function will be invoked with the
|
\param destructor If not \c NULL, this function will be invoked with the
|
||||||
data as parameter when the container is destroyed.
|
data as parameter when the container is destroyed.
|
||||||
|
\param clone If not \c NULL, this function will be invoked with the
|
||||||
|
data as parameter when the container is cloned.
|
||||||
\param _allocatedData Will be set to the storage allocated for the data.
|
\param _allocatedData Will be set to the storage allocated for the data.
|
||||||
\return \c B_OK when everything goes well, another error code otherwise.
|
\return \c B_OK when everything goes well, another error code otherwise.
|
||||||
*/
|
*/
|
||||||
@@ -76,6 +79,7 @@ status_t
|
|||||||
add_ancillary_data(ancillary_data_container* container,
|
add_ancillary_data(ancillary_data_container* container,
|
||||||
const ancillary_data_header* header, const void* data,
|
const ancillary_data_header* header, const void* data,
|
||||||
void (*destructor)(const ancillary_data_header*, void*),
|
void (*destructor)(const ancillary_data_header*, void*),
|
||||||
|
void (*clone)(const ancillary_data_header*, void*),
|
||||||
void** _allocatedData)
|
void** _allocatedData)
|
||||||
{
|
{
|
||||||
// check parameters
|
// check parameters
|
||||||
@@ -94,6 +98,7 @@ add_ancillary_data(ancillary_data_container* container,
|
|||||||
ancillary_data *ancillaryData = new(dataBuffer) ancillary_data;
|
ancillary_data *ancillaryData = new(dataBuffer) ancillary_data;
|
||||||
ancillaryData->header = *header;
|
ancillaryData->header = *header;
|
||||||
ancillaryData->destructor = destructor;
|
ancillaryData->destructor = destructor;
|
||||||
|
ancillaryData->clone = clone;
|
||||||
|
|
||||||
container->data_list.Add(ancillaryData);
|
container->data_list.Add(ancillaryData);
|
||||||
|
|
||||||
@@ -203,3 +208,43 @@ next_ancillary_data(const ancillary_data_container* container, void* previousDat
|
|||||||
|
|
||||||
return ancillaryData->Data();
|
return ancillaryData->Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Clones all ancillary data from container \c from to the end of the list of
|
||||||
|
ancillary data of container \c to.
|
||||||
|
|
||||||
|
\param from The container from which to clone the ancillary data.
|
||||||
|
\param to The container to which to add the ancillary data.
|
||||||
|
\return \c B_OK when everything goes well, another error code otherwise.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
clone_ancillary_data(const ancillary_data_container* from,
|
||||||
|
ancillary_data_container* to)
|
||||||
|
{
|
||||||
|
ancillary_data *ancillaryData = from->data_list.Head();
|
||||||
|
|
||||||
|
while (ancillaryData != NULL) {
|
||||||
|
// allocate buffer
|
||||||
|
void *dataBuffer = malloc(_ALIGN(sizeof(ancillary_data)) + ancillaryData->header.len);
|
||||||
|
if (dataBuffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
// init and attach the structure
|
||||||
|
ancillary_data *clone = new(dataBuffer) ancillary_data;
|
||||||
|
clone->header = ancillaryData->header;
|
||||||
|
if (ancillaryData->clone != NULL)
|
||||||
|
ancillaryData->clone(&ancillaryData->header, ancillaryData->Data());
|
||||||
|
clone->destructor = ancillaryData->destructor;
|
||||||
|
clone->clone = ancillaryData->clone;
|
||||||
|
|
||||||
|
to->data_list.Add(clone);
|
||||||
|
|
||||||
|
if (ancillaryData->Data() != NULL)
|
||||||
|
memcpy(clone->Data(), ancillaryData->Data(), ancillaryData->header.len);
|
||||||
|
|
||||||
|
ancillaryData = from->data_list.GetNext(ancillaryData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ void delete_ancillary_data_container(ancillary_data_container* container);
|
|||||||
status_t add_ancillary_data(ancillary_data_container* container,
|
status_t add_ancillary_data(ancillary_data_container* container,
|
||||||
const ancillary_data_header* header, const void* data,
|
const ancillary_data_header* header, const void* data,
|
||||||
void (*destructor)(const ancillary_data_header*, void*),
|
void (*destructor)(const ancillary_data_header*, void*),
|
||||||
|
void (*clone)(const ancillary_data_header*, void*),
|
||||||
void** _allocatedData);
|
void** _allocatedData);
|
||||||
status_t remove_ancillary_data(ancillary_data_container* container, void* data,
|
status_t remove_ancillary_data(ancillary_data_container* container, void* data,
|
||||||
bool destroy);
|
bool destroy);
|
||||||
@@ -24,6 +25,8 @@ void* move_ancillary_data(ancillary_data_container* from,
|
|||||||
|
|
||||||
void* next_ancillary_data(const ancillary_data_container* container,
|
void* next_ancillary_data(const ancillary_data_container* container,
|
||||||
void* previousData, ancillary_data_header* _header);
|
void* previousData, ancillary_data_header* _header);
|
||||||
|
status_t clone_ancillary_data(const ancillary_data_container* from,
|
||||||
|
ancillary_data_container* to);
|
||||||
|
|
||||||
|
|
||||||
#endif // NET_ANCILLARY_DATA_H
|
#endif // NET_ANCILLARY_DATA_H
|
||||||
|
|||||||
@@ -989,7 +989,8 @@ net_stack_module_info gNetStackModule = {
|
|||||||
add_ancillary_data,
|
add_ancillary_data,
|
||||||
remove_ancillary_data,
|
remove_ancillary_data,
|
||||||
move_ancillary_data,
|
move_ancillary_data,
|
||||||
next_ancillary_data
|
next_ancillary_data,
|
||||||
|
clone_ancillary_data
|
||||||
};
|
};
|
||||||
|
|
||||||
module_info* modules[] = {
|
module_info* modules[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user