[xml] Callbacks for xmlIO

Date view Thread view Subject view Author view

From: Peter Jacobi (pj@walter-graphtek.com)
Date: Thu Mar 02 2000 - 04:32:43 EST


Dear All,

I would like to change the different 'input methods' in xmlIO.c to a
callback based scheme. This would decrease compile-time and
link-time dependancies and would allow to add new input methods
without changing xmlIO.c.

The diffs for a basic implementations are attached.

For each 'input method' for callbacks must be defined: A single
void* in xmlParserInputBuffer will hold the context, replacing
file, gzfile, fd, httpIO and ftpIO.

typedef int (*xmlInputMatchCallback) (char const *filename);
typedef void * (*xmlInputOpenCallback) (char const *filename);
typedef int (*xmlInputReadCallback) (void * context, char * buffer,
int len);
typedef void (*xmlInputCloseCallback) (void * context);

xmlInputMatchCallback will look whether the 'filename' indicates a
source processed by this input method.

xmlInputOpenCallback will initialize the context.

xmlInputReadCallback will look read the data.

xmlInputMatchCallback will cleanup the context.

Regards,
Peter Jacobi

53 a 54,102
> /* input from file descriptor */
> int fdMatch (char const *filename) {
> return strstr (filename, ":") == 0;
> }
> void * fdOpen (char const *filename) {
> int fd = -1;
> #ifdef WIN32
> fd = _open (filename, O_RDONLY | _O_BINARY);
> #else
> fd = open (filename, O_RDONLY);
> #endif
> return (void *) fd;
> }
> int fdRead (void * context, char * buffer, int len) {
> int fd = (int) context;
> return read (fd, &buffer[0], len);
> }
> void fdClose (void * context) {
> int fd = (int) context;
> close (fd);
> }
> xmlInputCallback fdInputCallback = {fdMatch, fdOpen, fdRead, fdClose};
>
> /* input from file descriptor */
> int fileMatch (char const *filename) {
> return strstr (filename, ":") == 0;
> }
> void * fileOpen (char const *filename) {
> FILE *file = fopen (filename, "r");
> return file;
> }
> int fileRead (void * context, char * buffer, int len) {
> FILE *file = context;
> return fread(&buffer[0], 1, len, file);
> }
> void fileClose (void * context) {
> FILE *file = context;
> fclose (file);
> }
> xmlInputCallback fileInputCallback = {fileMatch, fileOpen, fdRead, fileClose};
>
> /* default input method table */
> xmlInputCallback defaultInputCallbackTable [] = {
> {fdMatch, fdOpen, fdRead, fdClose},
> {fileMatch, fileOpen, fdRead, fileClose},
> {0, 0, 0, 0}
> };
> xmlInputCallback *xmlInputCallbackTable = defaultInputCallbackTable;
>
79,81 c 128,131
< ret->fd = -1;
< ret->httpIO = NULL;
< ret->ftpIO = NULL;
>
> ret->context = 0;
> ret->readcallback = 0;
> ret->closecallback = 0;
96,107 c 146,152
< in->buffer = NULL;
< }
< #ifdef HAVE_ZLIB_H
< if (in->gzfile != NULL)
< gzclose(in->gzfile);
< #endif
< if (in->httpIO != NULL)
< xmlNanoHTTPClose(in->httpIO);
< if (in->ftpIO != NULL)
< xmlNanoFTPClose(in->ftpIO);
< if (in->fd >= 0)
< close(in->fd);
> in->buffer = NULL;
> }
>
> if (in->closecallback != 0) {
> (*in->closecallback) (in->context);
> }
>
128,208 c 173,190
< #ifdef HAVE_ZLIB_H
< gzFile input = 0;
< #else
< int input = -1;
< #endif
< void *httpIO = NULL;
< void *ftpIO = NULL;
<
< if (filename == NULL) return(NULL);
<
< if (!strncmp(filename, "http://", 7)) {
< httpIO = xmlNanoHTTPOpen(filename, NULL);
< if (httpIO == NULL) {
< #ifdef VERBOSE_FAILURE
< fprintf (stderr, "Cannot read URL %s\n", filename);
< perror ("xmlNanoHTTPOpen failed");
< #endif
< return(NULL);
< }
< } else if (!strncmp(filename, "ftp://", 6)) {
< ftpIO = xmlNanoFTPOpen(filename);
< if (ftpIO == NULL) {
< #ifdef VERBOSE_FAILURE
< fprintf (stderr, "Cannot read URL %s\n", filename);
< perror ("xmlNanoFTPOpen failed");
< #endif
< return(NULL);
< }
< } else if (!strcmp(filename, "-")) {
< #ifdef HAVE_ZLIB_H
< input = gzdopen (fileno(stdin), "r");
< if (input == NULL) {
< #ifdef VERBOSE_FAILURE
< fprintf (stderr, "Cannot read from stdin\n");
< perror ("gzdopen failed");
< #endif
< return(NULL);
< }
< #else
< #ifdef WIN32
< input = -1;
< #else
< input = fileno(stdin);
< #endif
< if (input < 0) {
< #ifdef VERBOSE_FAILURE
< fprintf (stderr, "Cannot read from stdin\n");
< perror ("open failed");
< #endif
< return(NULL);
< }
< #endif
< } else {
< #ifdef HAVE_ZLIB_H
< input = gzopen (filename, "r");
< if (input == NULL) {
< #ifdef VERBOSE_FAILURE
< fprintf (stderr, "Cannot read file %s :\n", filename);
< perror ("gzopen failed");
< #endif
< return(NULL);
< }
< #else
< #ifdef WIN32
< input = _open (filename, O_RDONLY | _O_BINARY);
< #else
< input = open (filename, O_RDONLY);
< #endif
< if (input < 0) {
< #ifdef VERBOSE_FAILURE
< fprintf (stderr, "Cannot read file %s :\n", filename);
< perror ("open failed");
< #endif
< return(NULL);
< }
< #endif
< }
<
< /*
< * Allocate the Input buffer front-end.
< */
>
> xmlInputCallback *input = xmlInputCallbackTable;
> void *context = 0;
> while (
> input != 0 &&
> !(*input->matchcallback) (filename)
> ) {
> ++input;
> }
> if (input->matchcallback == 0) {
> perror ("no matching input method");
> return 0;
> }
> context = (*input->opencallback) (filename);
> if (context == 0) {
> perror ("open failed");
> return 0;
> }
211,219 c 193,197
< #ifdef HAVE_ZLIB_H
< ret->gzfile = input;
< #else
< ret->fd = input;
< #endif
< ret->httpIO = httpIO;
< ret->ftpIO = ftpIO;
< }
<
> ret->context = context;
> ret->readcallback = input->readcallback;
> ret->closecallback = input->closecallback;
> }
>
240,241 c 218,222
< if (ret != NULL)
< ret->file = file;
> if (ret != NULL) {
> ret->context = file;
> ret->readcallback = fileInputCallback.readcallback;
> ret->closecallback = fileInputCallback.closecallback;
> }
263,264 c 244,249
< if (ret != NULL)
< ret->fd = fd;
>
> if (ret != NULL) {
> ret->context = (void*) fd;
> ret->readcallback = fdInputCallback.readcallback;
> ret->closecallback = fdInputCallback.closecallback;
> }
363,376 c 348,352
< return(-1);
< }
< if (in->httpIO != NULL) {
< res = xmlNanoHTTPRead(in->httpIO, &buffer[0], len);
< } else if (in->ftpIO != NULL) {
< res = xmlNanoFTPRead(in->ftpIO, &buffer[0], len);
< } else if (in->file != NULL) {
< res = fread(&buffer[0], 1, len, in->file);
< #ifdef HAVE_ZLIB_H
< } else if (in->gzfile != NULL) {
< res = gzread(input, &buffer[0], len);
< #endif
< } else if (in->fd >= 0) {
< res = read(in->fd, &buffer[0], len);
> return(-1);
> }
>
> if (in->readcallback != 0) {
> res = (*in->readcallback) (in->context, &buffer[0], len);
448,453 c 426,429
< if ((in->httpIO != NULL) || (in->ftpIO != NULL) || (in->file != NULL) ||
< #ifdef HAVE_ZLIB_H
< (in->gzfile != NULL) ||
< #endif
< (in->fd >= 0))
< return(xmlParserInputBufferGrow(in, len));
>
> if (in->readcallback != 0)
>
> return(xmlParserInputBufferGrow(in, len));

20 a 21,37
> typedef int (*xmlInputMatchCallback) (char const *filename);
> typedef void * (*xmlInputOpenCallback) (char const *filename);
> typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
> typedef void (*xmlInputCloseCallback) (void * context);
>
> typedef struct _xmlInputCallback {
> xmlInputMatchCallback matchcallback;
> xmlInputOpenCallback opencallback;
> xmlInputReadCallback readcallback;
> xmlInputCloseCallback closecallback;
> } xmlInputCallback;
>
> extern xmlInputCallback fileInputCallback;
> extern xmlInputCallback fdInputCallback;
>
> extern xmlInputCallback *xmlInputCallbackTable;
>
25,29 c 42,45
< FILE *file; /* Input on file handler */
< void* gzfile; /* Input on a compressed stream */
< int fd; /* Input on a file descriptor */
< void *httpIO; /* Input from an HTTP stream */
< void *ftpIO; /* Input from an FTP stream */
>
> void* context;
> xmlInputReadCallback readcallback;
> xmlInputCloseCallback closecallback;

----
Message from the list xml@xmlsoft.org
Archived at : http://xmlsoft.org/messages/
to unsubscribe: echo "unsubscribe xml" | mail  majordomo@xmlsoft.org


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Wed Aug 02 2000 - 12:30:07 EDT