| #ifndef _IPXE_XFERBUF_H |
| #define _IPXE_XFERBUF_H |
| |
| /** @file |
| * |
| * Data transfer buffer |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); |
| FILE_SECBOOT ( PERMITTED ); |
| |
| #include <stdint.h> |
| #include <ipxe/iobuf.h> |
| #include <ipxe/interface.h> |
| #include <ipxe/xfer.h> |
| |
| /** A data transfer buffer */ |
| struct xfer_buffer { |
| /** Data */ |
| void *data; |
| /** Size of data */ |
| size_t len; |
| /** Maximum required size of data */ |
| size_t max; |
| /** Current offset within data */ |
| size_t pos; |
| /** Data transfer buffer operations */ |
| struct xfer_buffer_operations *op; |
| }; |
| |
| /** Data transfer buffer operations */ |
| struct xfer_buffer_operations { |
| /** Reallocate data buffer |
| * |
| * @v xferbuf Data transfer buffer |
| * @v len New length (or zero to free buffer) |
| * @ret rc Return status code |
| */ |
| int ( * realloc ) ( struct xfer_buffer *xferbuf, size_t len ); |
| }; |
| |
| extern struct xfer_buffer_operations xferbuf_malloc_operations; |
| extern struct xfer_buffer_operations xferbuf_umalloc_operations; |
| extern struct xfer_buffer_operations xferbuf_fixed_operations; |
| extern struct xfer_buffer_operations xferbuf_void_operations; |
| |
| /** |
| * Initialise malloc()-based data transfer buffer |
| * |
| * @v xferbuf Data transfer buffer |
| * |
| * Data will be automatically allocated using malloc(). |
| */ |
| static inline __attribute__ (( always_inline )) void |
| xferbuf_malloc_init ( struct xfer_buffer *xferbuf ) { |
| xferbuf->op = &xferbuf_malloc_operations; |
| } |
| |
| /** |
| * Initialise umalloc()-based data transfer buffer |
| * |
| * @v xferbuf Data transfer buffer |
| * |
| * Data will be automatically allocated using umalloc() (and may |
| * therefore alter the system memory map). |
| */ |
| static inline __attribute__ (( always_inline )) void |
| xferbuf_umalloc_init ( struct xfer_buffer *xferbuf ) { |
| xferbuf->op = &xferbuf_umalloc_operations; |
| } |
| |
| /** |
| * Initialise fixed-size data transfer buffer |
| * |
| * @v xferbuf Data transfer buffer |
| * @v data Data buffer |
| * @v len Length of data buffer |
| * |
| * Data will be never be automatically allocated. |
| */ |
| static inline __attribute__ (( always_inline )) void |
| xferbuf_fixed_init ( struct xfer_buffer *xferbuf, void *data, size_t len ) { |
| xferbuf->data = data; |
| xferbuf->len = len; |
| xferbuf->op = &xferbuf_fixed_operations; |
| } |
| |
| /** |
| * Initialise void data transfer buffer |
| * |
| * @v xferbuf Data transfer buffer |
| * |
| * No data will be allocated, but the length will be recorded. This |
| * can be used to capture xfer_seek() results. |
| */ |
| static inline __attribute__ (( always_inline )) void |
| xferbuf_void_init ( struct xfer_buffer *xferbuf ) { |
| xferbuf->op = &xferbuf_void_operations; |
| } |
| |
| extern void xferbuf_detach ( struct xfer_buffer *xferbuf ); |
| extern void xferbuf_free ( struct xfer_buffer *xferbuf ); |
| extern int xferbuf_write ( struct xfer_buffer *xferbuf, size_t offset, |
| const void *data, size_t len ); |
| extern int xferbuf_read ( struct xfer_buffer *xferbuf, size_t offset, |
| void *data, size_t len ); |
| extern int xferbuf_deliver ( struct xfer_buffer *xferbuf, |
| struct io_buffer *iobuf, |
| struct xfer_metadata *meta ); |
| |
| extern struct xfer_buffer * xfer_buffer ( struct interface *intf ); |
| #define xfer_buffer_TYPE( object_type ) \ |
| typeof ( struct xfer_buffer * ( object_type ) ) |
| |
| #endif /* _IPXE_XFERBUF_H */ |