/*
 * xmlIO.c : implementation of the I/O interfaces used by the parser
 *
 * See Copyright for the status of this software.
 *
 * Daniel.Veillard@w3.org
 */

#ifdef WIN32
#include "win32config.h"
#else
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif

#include "xmlmemory.h"
#include "parser.h"
#include "parserInternals.h"
#include "xmlIO.h"
#include "nanohttp.h"
#include "nanoftp.h"

/* #define DEBUG_INPUT */
/* #define VERBOSE_FAILURE */
/* #define DEBUG_EXTERNAL_ENTITIES */

#ifdef DEBUG_INPUT
#define MINLEN 40
#else
#define MINLEN 4000
#endif

/**
 * xmlAllocParserInputBuffer:
 * @enc:  the charset encoding if known
 *
 * Create a buffered parser input for progressive parsing
 *
 * Returns the new parser input or NULL
 */
xmlParserInputBufferPtr
xmlAllocParserInputBuffer(xmlCharEncoding enc) {
    xmlParserInputBufferPtr ret;

    ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
    if (ret == NULL) {
        fprintf(stderr, "xmlAllocParserInputBuffer : out of memory!\n");
	return(NULL);
    }
    memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
    ret->buffer = xmlBufferCreate();
    if (ret->buffer == NULL) {
        xmlFree(ret);
	return(NULL);
    }
    ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
    ret->encoder = xmlGetCharEncodingHandler(enc);
    ret->fd = -1;
    ret->httpIO = NULL;
    ret->ftpIO = NULL;

    return(ret);
}

/**
 * xmlFreeParserInputBuffer:
 * @in:  a buffered parser input
 *
 * Free up the memory used by a buffered parser input
 */
void
xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) {
    if (in->buffer != NULL) {
        xmlBufferFree(in->buffer);
	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);
    memset(in, 0xbe, (size_t) sizeof(xmlParserInputBuffer));
    xmlFree(in);
}

/**
 * xmlParserInputBufferCreateFilename:
 * @filename:  a C string containing the filename
 * @enc:  the charset encoding if known
 *
 * Create a buffered parser input for the progressive parsing of a file
 * If filename is "-' then we use stdin as the input.
 * Automatic support for ZLIB/Compress compressed document is provided
 * by default if found at compile-time.
 * Do an encoding check if enc == XML_CHAR_ENCODING_NONE
 *
 * Returns the new parser input or NULL
 */
xmlParserInputBufferPtr
xmlParserInputBufferCreateFilename(const char *filename, xmlCharEncoding enc) {
    xmlParserInputBufferPtr ret;
#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.
     */
    ret = xmlAllocParserInputBuffer(enc);
    if (ret != NULL) {
#ifdef HAVE_ZLIB_H
        ret->gzfile = input;
#else
        ret->fd = input;
#endif
        ret->httpIO = httpIO;
        ret->ftpIO = ftpIO;
    }

    return(ret);
}

/**
 * xmlParserInputBufferCreateFile:
 * @file:  a FILE* 
 * @enc:  the charset encoding if known
 *
 * Create a buffered parser input for the progressive parsing of a FILE *
 * buffered C I/O
 *
 * Returns the new parser input or NULL
 */
xmlParserInputBufferPtr
xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) {
    xmlParserInputBufferPtr ret;

    if (file == NULL) return(NULL);

    ret = xmlAllocParserInputBuffer(enc);
    if (ret != NULL)
        ret->file = file;

    return(ret);
}

/**
 * xmlParserInputBufferCreateFd:
 * @fd:  a file descriptor number
 * @enc:  the charset encoding if known
 *
 * Create a buffered parser input for the progressive parsing for the input
 * from a file descriptor
 *
 * Returns the new parser input or NULL
 */
xmlParserInputBufferPtr
xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
    xmlParserInputBufferPtr ret;

    if (fd < 0) return(NULL);

    ret = xmlAllocParserInputBuffer(enc);
    if (ret != NULL)
        ret->fd = fd;

    return(ret);
}

/**
 * xmlParserInputBufferPush:
 * @in:  a buffered parser input
 * @buf:  an char array
 * @len:  the size in bytes of the array.
 *
 * Push the content of the arry in the input buffer
 * This routine handle the I18N transcoding to internal UTF-8
 * This is used when operating the parser in progressive (push) mode.
 *
 * Returns the number of chars read and stored in the buffer, or -1
 *         in case of error.
 */
int
xmlParserInputBufferPush(xmlParserInputBufferPtr in, int len, const char *buf) {
    int nbchars = 0;

    if (len < 0) return(0);
    if (in->encoder != NULL) {
        xmlChar *buffer;
	int processed = len;

	buffer = (xmlChar *) xmlMalloc((len + 1) * 2 * sizeof(xmlChar));
	if (buffer == NULL) {
	    fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n");
	    return(-1);
	}
	nbchars = in->encoder->input(buffer, (len + 1) * 2 * sizeof(xmlChar),
	                             (xmlChar *) buf, &processed);
	/*
	 * TODO : we really need to have something atomic or the 
	 *        encoder must report the number of bytes read
	 */
	if (nbchars < 0) {
	    fprintf(stderr, "xmlParserInputBufferPush: encoder error\n");
	    xmlFree(buffer);
	    return(-1);
	}
	if (processed  != len) {
	    fprintf(stderr,
	            "TODO xmlParserInputBufferPush: processed  != len\n");
	    xmlFree(buffer);
	    return(-1);
	}
        buffer[nbchars] = 0;
        xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars);
	xmlFree(buffer);
    } else {
	nbchars = len;
        xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
    }
#ifdef DEBUG_INPUT
    fprintf(stderr, "I/O: pushed %d chars, buffer %d/%d\n",
            nbchars, in->buffer->use, in->buffer->size);
#endif
    return(nbchars);
}

/**
 * xmlParserInputBufferGrow:
 * @in:  a buffered parser input
 * @len:  indicative value of the amount of chars to read
 *
 * Grow up the content of the input buffer, the old data are preserved
 * This routine handle the I18N transcoding to internal UTF-8
 * This routine is used when operating the parser in normal (pull) mode
 * TODO: one should be able to remove one extra copy
 *
 * Returns the number of chars read and stored in the buffer, or -1
 *         in case of error.
 */
int
xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
    char *buffer = NULL;
#ifdef HAVE_ZLIB_H
    gzFile input = (gzFile) in->gzfile;
#endif
    int res = 0;
    int nbchars = 0;
    int buffree;

    if ((len <= MINLEN) && (len != 4)) 
        len = MINLEN;
    buffree = in->buffer->size - in->buffer->use;
    if (buffree <= 0) {
        fprintf(stderr, "xmlParserInputBufferGrow : buffer full !\n");
	return(0);
    }
    if (len > buffree) 
        len = buffree;

    buffer = xmlMalloc((len + 1) * sizeof(char));
    if (buffer == NULL) {
        fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n");
	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);
    } else {
        fprintf(stderr, "xmlParserInputBufferGrow : no input !\n");
	xmlFree(buffer);
	return(-1);
    }
    if (res == 0) {
	xmlFree(buffer);
        return(0);
    }
    if (res < 0) {
	perror ("read error");
	xmlFree(buffer);
	return(-1);
    }
    if (in->encoder != NULL) {
        xmlChar *buf;
	int wrote = res;

	buf = (xmlChar *) xmlMalloc((res + 1) * 2 * sizeof(xmlChar));
	if (buf == NULL) {
	    fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n");
	    xmlFree(buffer);
	    return(-1);
	}
	nbchars = in->encoder->input(buf, (res + 1) * 2 * sizeof(xmlChar),
	                             BAD_CAST buffer, &wrote);
        buf[nbchars] = 0;
        xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
	xmlFree(buf);

	/*
	 * Check that the encoder was able to process the full input
	 */
	if (wrote != res) {
	    fprintf(stderr, 
	        "TODO : xmlParserInputBufferGrow wrote %d != res %d\n",
		wrote, res);
	    /*
	     * TODO !!!
	     * Need to keep the unprocessed input in a buffer in->unprocessed
	     */
	}

    } else {
	nbchars = res;
        buffer[nbchars] = 0;
        xmlBufferAdd(in->buffer, (xmlChar *) buffer, nbchars);
    }
#ifdef DEBUG_INPUT
    fprintf(stderr, "I/O: read %d chars, buffer %d/%d\n",
            nbchars, in->buffer->use, in->buffer->size);
#endif
    xmlFree(buffer);
    return(nbchars);
}

/**
 * xmlParserInputBufferRead:
 * @in:  a buffered parser input
 * @len:  indicative value of the amount of chars to read
 *
 * Refresh the content of the input buffer, the old data are considered
 * consumed
 * This routine handle the I18N transcoding to internal UTF-8
 *
 * Returns the number of chars read and stored in the buffer, or -1
 *         in case of error.
 */
int
xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) {
    /* xmlBufferEmpty(in->buffer); */
    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));
    else
        return(0);
}

/*
 * xmlParserGetDirectory:
 * @filename:  the path to a file
 *
 * lookup the directory for that file
 *
 * Returns a new allocated string containing the directory, or NULL.
 */
char *
xmlParserGetDirectory(const char *filename) {
    char *ret = NULL;
    char dir[1024];
    char *cur;
    char sep = '/';

    if (filename == NULL) return(NULL);
#ifdef WIN32
    sep = '\\';
#endif

    strncpy(dir, filename, 1023);
    dir[1023] = 0;
    cur = &dir[strlen(dir)];
    while (cur > dir) {
         if (*cur == sep) break;
	 cur --;
    }
    if (*cur == sep) {
        if (cur == dir) dir[1] = 0;
	else *cur = 0;
	ret = xmlMemStrdup(dir);
    } else {
        if (getcwd(dir, 1024) != NULL) {
	    dir[1023] = 0;
	    ret = xmlMemStrdup(dir);
	}
    }
    return(ret);
}

/****************************************************************
 *								*
 *		External entities loading			*
 *								*
 ****************************************************************/

/*
 * xmlDefaultExternalEntityLoader:
 * @URL:  the URL for the entity to load
 * @ID:  the System ID for the entity to load
 * @ctxt:  the context in which the entity is called or NULL
 *
 * By default we don't load external entitites, yet.
 *
 * Returns a new allocated xmlParserInputPtr, or NULL.
 */
static
xmlParserInputPtr
xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
                               xmlParserCtxtPtr ctxt) {
    xmlParserInputPtr ret = NULL;
#ifdef DEBUG_EXTERNAL_ENTITIES
    fprintf(stderr, "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
#endif
    if (URL == NULL) {
        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
	    ctxt->sax->warning(ctxt, "failed to load external entity \"%s\"\n",
	                       ID);
        return(NULL);
    }
    ret = xmlNewInputFromFile(ctxt, URL);
    if (ret == NULL) {
        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
	    ctxt->sax->warning(ctxt, "failed to load external entity \"%s\"\n",
	                       URL);
    }
    return(ret);
}

static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
       xmlDefaultExternalEntityLoader;

/*
 * xmlSetExternalEntityLoader:
 * @f:  the new entity resolver function
 *
 * Changes the defaultexternal entity resolver function for the application
 */
void
xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
    xmlCurrentExternalEntityLoader = f;
}

/*
 * xmlGetExternalEntityLoader:
 *
 * Get the default external entity resolver function for the application
 *
 * Returns the xmlExternalEntityLoader function pointer
 */
xmlExternalEntityLoader
xmlGetExternalEntityLoader(void) {
    return(xmlCurrentExternalEntityLoader);
}

/*
 * xmlLoadExternalEntity:
 * @URL:  the URL for the entity to load
 * @ID:  the System ID for the entity to load
 * @ctxt:  the context in which the entity is called or NULL
 *
 * Load an external entity, note that the use of this function for
 * unparsed entities may generate problems
 * TODO: a more generic External entitiy API must be designed
 *
 * Returns the xmlParserInputPtr or NULL
 */
xmlParserInputPtr
xmlLoadExternalEntity(const char *URL, const char *ID,
                      xmlParserCtxtPtr ctxt) {
    return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));
}

