io_ctx
. The
io_ctx
context is used by SETREF to abstract nearly all
input and output. Notice that no "create" method is defined. C++
programmers will recognize this as an "abstract base class". It
is only possible to create an object of type io_ctx
by creating an object of a
subtype of io_ctx
(for instance io_ctx_stdio
,
which is implemented using the stdio package).
The interface for io_ctx
is taken from the
stdio
package.
As is common to all contexts with virtual methods, the virtual
methods are invoked using macros. In the case of io_ctx
,
the methods
IO_delete()
IO_fread()
IO_fwrite()
IO_fgetc()
IO_fputc()
IO_ungetc()
IO_fflush()
IO_ftell()
IO_fseek()
ctx
argument appears
more than once in the macro expansion. Therefore, it is
safe to use arguments with side effects (in particular,
those using the ++
or --
operator)
for all arguments except ctx
. The macros
should always be used to invoke the underlying functions,
rather than invoking the functions directly.
/* The following structure defines objects of type io_ctx. * As with all contexts containing virtual methods, the type * consists of 2 pieces of data: a "vtbl" pointer and a opaque * pointer to subtype-specific data. */ typedef struct io_ctx_ *io_ctx; struct io_ctx_ { /* The virtual function table (vtbl) definition * for all objects of type io_ctx. Do not call * these functions directly. Use the provided * macros. */ struct io_ctx_vtbl_ { int (*fgetc_) PROTO_LIST((VOID*)); int (*fputc_) PROTO_LIST((UCHAR, VOID*)); int (*fread_) PROTO_LIST((char*, int, int, VOID*)); int (*fwrite_) PROTO_LIST((CONST char*, int, int, VOID*)); int (*fseek_) PROTO_LIST((VOID*, long, position)); int (*ftell_) PROTO_LIST((VOID*)); int (*fflush_) PROTO_LIST((VOID*)); int (*ungetc_) PROTO_LIST((int, VOID*)); /* Contexts with virtual methods always contain a * virtual delete function which is used to delete * the context. */ int (*delete_io_ctx) PROTO_LIST((io_ctx*)); } *vtbl; /* "handle" is a opaque pointer to subtype-specific data. * Users should never manipulate this data directly. */ VOID *handle; }; /* int IO_delete(ctxp) * io_ctx *ctxp; */ #define IO_delete(ctxp) \ SAFE_DELETE_VCALL__(ctxp,((*(ctxp))->vtbl->delete_io_ctx((ctxp)))) /* int IO_fgetc(ctx) * io_ctx ctx; */ #define IO_fgetc(ctx) ((ctx)->vtbl->fgetc_((ctx)->handle)) /* int IO_fputc(c, ctx) * char c; * io_ctx ctx; */ #define IO_fputc(c, ctx) ((ctx)->vtbl->fputc_((c), (ctx)->handle)) /* long IO_ftell(ctx) * io_ctx ctx; */ #define IO_ftell(ctx) ((ctx)->vtbl->ftell_((ctx)->handle)) /* int IO_fflush(ctx) * io_ctx ctx; */ #define IO_fflush(ctx) ((ctx)->vtbl->fflush_((ctx)->handle)) /* int IO_ungetc(c, ctx) * char c; * io_ctx ctx; */ #define IO_ungetc(c, ctx) ((ctx)->vtbl->ungetc_((c), (ctx)->handle)) /* int IO_fread(ptr, size, nitems, ctx) * char *ptr; * int size; * int nitems; * io_ctx ctx; */ #define IO_fread(ptr, size, nitems, ctx) \ ((ctx)->vtbl->fread_((ptr),(size),(nitems),(ctx)->handle)) /* int IO_fwrite(ptr, size, nitems, ctx) * char *ptr; * int size; * int nitems; * io_ctx ctx; */ #define IO_fwrite(ptr, size, nitems, ctx) \ ((ctx)->vtbl->fwrite_((ptr),(size),(nitems),(ctx)->handle)) /* int IO_fseek(ctx, offset, ptrname) * io_ctx ctx; * long offset; * position ptrname; */ #define IO_fseek(ctx, offset, pos) \ ((ctx)->vtbl->fseek_((ctx)->handle,(offset),(pos))) typedef int position; /* either BOF, CUR, or EOF */ #ifndef FSEEK_BOF # define FSEEK_BOF 0 # define FSEEK_CUR 1 # define FSEEK_EOF 2 #endif
Copyright © 1996, 1997, Visa International Service Association and MasterCard International Incorporated
All Rights Reserved.