mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-22 17:41:55 +00:00
Data-transfer interface should now be functionally complete.
This commit is contained in:
parent
817a446cc6
commit
5471bfbbbe
@ -115,7 +115,7 @@ static void downloader_job_start ( struct job_interface *job ) {
|
||||
container_of ( job, struct downloader, job );
|
||||
|
||||
/* Start data transfer */
|
||||
xfer_start ( &downloader->xfer );
|
||||
xfer_request_all ( &downloader->xfer );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,17 +152,30 @@ static struct job_interface_operations downloader_job_operations = {
|
||||
* @v pos New position
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int downloader_xfer_seek ( struct xfer_interface *xfer, size_t pos ) {
|
||||
static int downloader_xfer_seek ( struct xfer_interface *xfer, off_t offset,
|
||||
int whence ) {
|
||||
struct downloader *downloader =
|
||||
container_of ( xfer, struct downloader, xfer );
|
||||
off_t new_pos;
|
||||
int rc;
|
||||
|
||||
/* Ensure that we have enough buffer space for this buffer position */
|
||||
if ( ( rc = downloader_ensure_size ( downloader, pos ) ) != 0 )
|
||||
return rc;
|
||||
/* Calculate new buffer position */
|
||||
switch ( whence ) {
|
||||
case SEEK_SET:
|
||||
new_pos = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
new_pos = ( downloader->pos + offset );
|
||||
break;
|
||||
default:
|
||||
assert ( 0 );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Update current buffer position */
|
||||
downloader->pos = pos;
|
||||
/* Ensure that we have enough buffer space for this buffer position */
|
||||
if ( ( rc = downloader_ensure_size ( downloader, new_pos ) ) != 0 )
|
||||
return rc;
|
||||
downloader->pos = new_pos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -216,11 +229,11 @@ static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) {
|
||||
|
||||
/** Downloader data transfer interface operations */
|
||||
static struct xfer_interface_operations downloader_xfer_operations = {
|
||||
.start = ignore_xfer_start,
|
||||
.close = downloader_xfer_close,
|
||||
.vredirect = default_xfer_vredirect,
|
||||
.vredirect = vopen,
|
||||
.request = ignore_xfer_request,
|
||||
.seek = downloader_xfer_seek,
|
||||
.deliver = xfer_deliver_as_raw,
|
||||
.deliver_iob = xfer_deliver_as_raw,
|
||||
.deliver_raw = downloader_xfer_deliver_raw,
|
||||
};
|
||||
|
||||
|
68
src/core/hw.c
Normal file
68
src/core/hw.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <gpxe/refcnt.h>
|
||||
#include <gpxe/xfer.h>
|
||||
#include <gpxe/open.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* "Hello World" data source
|
||||
*
|
||||
*/
|
||||
|
||||
struct hw {
|
||||
struct refcnt refcnt;
|
||||
struct xfer_interface xfer;
|
||||
};
|
||||
|
||||
static const char hw_msg[] = "Hello world!\n";
|
||||
|
||||
static void hw_finished ( struct hw *hw, int rc ) {
|
||||
xfer_nullify ( &hw->xfer );
|
||||
xfer_close ( &hw->xfer, rc );
|
||||
ref_put ( &hw->refcnt );
|
||||
}
|
||||
|
||||
static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) {
|
||||
struct hw *hw = container_of ( xfer, struct hw, xfer );
|
||||
|
||||
hw_finished ( hw, rc );
|
||||
}
|
||||
|
||||
static int hw_xfer_request ( struct xfer_interface *xfer, off_t start __unused,
|
||||
int whence __unused, size_t len __unused ) {
|
||||
struct hw *hw = container_of ( xfer, struct hw, xfer );
|
||||
|
||||
xfer_deliver_raw ( xfer, hw_msg, sizeof ( hw_msg ) );
|
||||
hw_finished ( hw, 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct xfer_interface_operations hw_xfer_operations = {
|
||||
.close = hw_xfer_close,
|
||||
.vredirect = ignore_xfer_vredirect,
|
||||
.request = hw_xfer_request,
|
||||
.seek = ignore_xfer_seek,
|
||||
.deliver_iob = xfer_deliver_as_raw,
|
||||
.deliver_raw = ignore_xfer_deliver_raw,
|
||||
};
|
||||
|
||||
static int hw_open ( struct xfer_interface *xfer, struct uri *uri __unused ) {
|
||||
struct hw *hw;
|
||||
|
||||
hw = malloc ( sizeof ( *hw ) );
|
||||
if ( ! hw )
|
||||
return -ENOMEM;
|
||||
memset ( hw, 0, sizeof ( *hw ) );
|
||||
xfer_init ( &hw->xfer, &hw_xfer_operations, &hw->refcnt );
|
||||
|
||||
xfer_plug_plug ( &hw->xfer, xfer );
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct uri_opener hw_uri_opener __uri_opener = {
|
||||
.scheme = "hw",
|
||||
.open = hw_open,
|
||||
};
|
124
src/core/xfer.c
124
src/core/xfer.c
@ -39,19 +39,6 @@ void xfer_close ( struct xfer_interface *xfer, int rc ) {
|
||||
xfer_unplug ( xfer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to position
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v pos New position
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int xfer_seek ( struct xfer_interface *xfer, size_t pos ) {
|
||||
struct xfer_interface *dest = xfer_dest ( xfer );
|
||||
|
||||
return dest->op->seek ( dest, pos );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send redirection event
|
||||
*
|
||||
@ -84,6 +71,59 @@ int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request data
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v offset Offset to new position
|
||||
* @v whence Basis for new position
|
||||
* @v len Length of requested data
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int xfer_request ( struct xfer_interface *xfer, off_t offset, int whence,
|
||||
size_t len ) {
|
||||
struct xfer_interface *dest = xfer_dest ( xfer );
|
||||
|
||||
return dest->op->request ( dest, offset, whence, len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Request all data
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int xfer_request_all ( struct xfer_interface *xfer ) {
|
||||
return xfer_request ( xfer, 0, SEEK_SET, ~( ( size_t ) 0 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to position
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v offset Offset to new position
|
||||
* @v whence Basis for new position
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
|
||||
struct xfer_interface *dest = xfer_dest ( xfer );
|
||||
|
||||
return dest->op->seek ( dest, offset, whence );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate I/O buffer
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v len I/O buffer payload length
|
||||
* @ret iobuf I/O buffer
|
||||
*/
|
||||
struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) {
|
||||
struct xfer_interface *dest = xfer_dest ( xfer );
|
||||
|
||||
return dest->op->alloc_iob ( dest, len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deliver datagram
|
||||
*
|
||||
@ -91,10 +131,10 @@ int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) {
|
||||
* @v iobuf Datagram I/O buffer
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int xfer_deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
|
||||
int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
|
||||
struct xfer_interface *dest = xfer_dest ( xfer );
|
||||
|
||||
return dest->op->deliver ( dest, iobuf );
|
||||
return dest->op->deliver_iob ( dest, iobuf );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,15 +160,6 @@ int xfer_deliver_raw ( struct xfer_interface *xfer,
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ignore start() event
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
*/
|
||||
void ignore_xfer_start ( struct xfer_interface *xfer __unused ) {
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore close() event
|
||||
*
|
||||
@ -153,18 +184,46 @@ int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore request() event
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v offset Offset to new position
|
||||
* @v whence Basis for new position
|
||||
* @v len Length of requested data
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ignore_xfer_request ( struct xfer_interface *xfer __unused,
|
||||
off_t offset __unused, int whence __unused,
|
||||
size_t len __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore seek() event
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v pos New position
|
||||
* @v offset Offset to new position
|
||||
* @v whence Basis for new position
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ignore_xfer_seek ( struct xfer_interface *xfer __unused,
|
||||
size_t pos __unused ) {
|
||||
off_t offset __unused, int whence __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate I/O buffer
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v len I/O buffer payload length
|
||||
* @ret iobuf I/O buffer
|
||||
*/
|
||||
struct io_buffer *
|
||||
default_xfer_alloc_iob ( struct xfer_interface *xfer __unused, size_t len ) {
|
||||
return alloc_iob ( len );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deliver datagram as raw data
|
||||
*
|
||||
@ -195,16 +254,16 @@ int xfer_deliver_as_raw ( struct xfer_interface *xfer,
|
||||
* This function is intended to be used as the deliver_raw() method
|
||||
* for data transfer interfaces that prefer to handle I/O buffers.
|
||||
*/
|
||||
int xfer_deliver_as_iobuf ( struct xfer_interface *xfer,
|
||||
const void *data, size_t len ) {
|
||||
int xfer_deliver_as_iob ( struct xfer_interface *xfer,
|
||||
const void *data, size_t len ) {
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
iobuf = alloc_iob ( len );
|
||||
iobuf = xfer->op->alloc_iob ( xfer, len );
|
||||
if ( ! iobuf )
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy ( iob_put ( iobuf, len ), data, len );
|
||||
return xfer->op->deliver ( xfer, iobuf );
|
||||
return xfer->op->deliver_iob ( xfer, iobuf );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -225,11 +284,12 @@ int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
|
||||
|
||||
/** Null data transfer interface operations */
|
||||
struct xfer_interface_operations null_xfer_ops = {
|
||||
.start = ignore_xfer_start,
|
||||
.close = ignore_xfer_close,
|
||||
.vredirect = ignore_xfer_vredirect,
|
||||
.request = ignore_xfer_request,
|
||||
.seek = ignore_xfer_seek,
|
||||
.deliver = xfer_deliver_as_raw,
|
||||
.alloc_iob = default_xfer_alloc_iob,
|
||||
.deliver_iob = xfer_deliver_as_raw,
|
||||
.deliver_raw = ignore_xfer_deliver_raw,
|
||||
};
|
||||
|
||||
|
@ -16,22 +16,6 @@ struct xfer_interface;
|
||||
|
||||
/** Data transfer interface operations */
|
||||
struct xfer_interface_operations {
|
||||
|
||||
/* Missing features:
|
||||
*
|
||||
* notification of non-close status - e.g. connected/opened, ...
|
||||
*
|
||||
* prompt for data delivery
|
||||
*
|
||||
* I/O buffer preparation
|
||||
*
|
||||
*/
|
||||
|
||||
/** Start data transfer
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
*/
|
||||
void ( * start ) ( struct xfer_interface *xfer );
|
||||
/** Close interface
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
@ -47,14 +31,39 @@ struct xfer_interface_operations {
|
||||
*/
|
||||
int ( * vredirect ) ( struct xfer_interface *xfer, int type,
|
||||
va_list args );
|
||||
/** Request data
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v offset Offset to new position
|
||||
* @v whence Basis for new position
|
||||
* @v len Length of requested data
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * request ) ( struct xfer_interface *xfer, off_t offset,
|
||||
int whence, size_t len );
|
||||
/** Seek to position
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v pos New position
|
||||
* @v offset Offset to new position
|
||||
* @v whence Basis for new position
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* @c whence must be one of @c SEEK_SET or @c SEEK_CUR. A
|
||||
* successful return indicates that the interface is ready to
|
||||
* immediately accept datagrams; return -EAGAIN if this is not
|
||||
* the case.
|
||||
*/
|
||||
int ( * seek ) ( struct xfer_interface *xfer, size_t pos );
|
||||
/** Deliver datagram
|
||||
int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
|
||||
int whence );
|
||||
/** Allocate I/O buffer
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v len I/O buffer payload length
|
||||
* @ret iobuf I/O buffer
|
||||
*/
|
||||
struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
|
||||
size_t len );
|
||||
/** Deliver datagram as I/O buffer
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
* @v iobuf Datagram I/O buffer
|
||||
@ -63,9 +72,13 @@ struct xfer_interface_operations {
|
||||
* A data transfer interface that wishes to support only raw
|
||||
* data delivery should set this method to
|
||||
* xfer_deliver_as_raw().
|
||||
*
|
||||
* Interfaces may not temporarily refuse to accept data by
|
||||
* returning -EAGAIN; such a response may be treated as a
|
||||
* fatal error.
|
||||
*/
|
||||
int ( * deliver ) ( struct xfer_interface *xfer,
|
||||
struct io_buffer *iobuf );
|
||||
int ( * deliver_iob ) ( struct xfer_interface *xfer,
|
||||
struct io_buffer *iobuf );
|
||||
/** Deliver datagram as raw data
|
||||
*
|
||||
* @v xfer Data transfer interface
|
||||
@ -75,7 +88,11 @@ struct xfer_interface_operations {
|
||||
*
|
||||
* A data transfer interface that wishes to support only I/O
|
||||
* buffer delivery should set this method to
|
||||
* xfer_deliver_as_iobuf().
|
||||
* xfer_deliver_as_iob().
|
||||
*
|
||||
* Interfaces may not temporarily refuse to accept data by
|
||||
* returning -EAGAIN; such a response may be treated as a
|
||||
* fatal error.
|
||||
*/
|
||||
int ( * deliver_raw ) ( struct xfer_interface *xfer,
|
||||
const void *data, size_t len );
|
||||
@ -89,31 +106,43 @@ struct xfer_interface {
|
||||
struct xfer_interface_operations *op;
|
||||
};
|
||||
|
||||
/** Basis positions for seek() events */
|
||||
enum seek_whence {
|
||||
SEEK_SET = 0,
|
||||
SEEK_CUR,
|
||||
};
|
||||
|
||||
extern struct xfer_interface null_xfer;
|
||||
extern struct xfer_interface_operations null_xfer_ops;
|
||||
|
||||
extern void xfer_start ( struct xfer_interface *xfer );
|
||||
extern void xfer_close ( struct xfer_interface *xfer, int rc );
|
||||
extern int xfer_seek ( struct xfer_interface *xfer, size_t pos );
|
||||
extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
|
||||
va_list args );
|
||||
extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
|
||||
extern int xfer_deliver ( struct xfer_interface *xfer,
|
||||
struct io_buffer *iobuf );
|
||||
extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
|
||||
int whence, size_t len );
|
||||
extern int xfer_request_all ( struct xfer_interface *xfer );
|
||||
extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
|
||||
extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
|
||||
size_t len );
|
||||
extern int xfer_deliver_iob ( struct xfer_interface *xfer,
|
||||
struct io_buffer *iobuf );
|
||||
extern int xfer_deliver_raw ( struct xfer_interface *xfer,
|
||||
const void *data, size_t len );
|
||||
|
||||
extern void ignore_xfer_start ( struct xfer_interface *xfer );
|
||||
extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
|
||||
extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
|
||||
int type, va_list args );
|
||||
extern int default_xfer_vredirect ( struct xfer_interface *xfer,
|
||||
int type, va_list args );
|
||||
extern int ignore_xfer_seek ( struct xfer_interface *xfer, size_t pos );
|
||||
extern int ignore_xfer_request ( struct xfer_interface *xfer, off_t offset,
|
||||
int whence, size_t len );
|
||||
extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
|
||||
int whence );
|
||||
extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
|
||||
size_t len );
|
||||
extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
|
||||
struct io_buffer *iobuf );
|
||||
extern int xfer_deliver_as_iobuf ( struct xfer_interface *xfer,
|
||||
const void *data, size_t len );
|
||||
extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
|
||||
const void *data, size_t len );
|
||||
extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
|
||||
const void *data __unused, size_t len );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user