/*****************************************************************************
 *
 * This example source code introduces a c library buffered I/O interface to
 * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(),
 * rewind(). Supported functions have identical prototypes to their normal c
 * lib namesakes and are preceaded by url_ .
 *
 * Using this code you can replace your program's fopen() with url_fopen()
 * and fread() with url_fread() and it become possible to read remote streams
 * instead of (only) local files. Local files (ie those that can be directly
 * fopened) will drop back to using the underlying clib implementations
 *
 * See the main() function at the bottom that shows an app that retrives from a
 * specified url using fgets() and fread() and saves as two output files.
 *
 * Coyright (c)2003 Simtec Electronics
 *
 * Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
 * reference to original curl example code
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This example requires libcurl 7.9.7 or later.
 */

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>
#include <errno.h>

#include <curl/curl.h>

enum fcurl_type_e { CFTYPE_NONE=0, CFTYPE_FILE=1, CFTYPE_CURL=2 };

struct fcurl_data
{
    enum fcurl_type_e type;	/* type of handle */
    union {
	CURL *curl;
	FILE *file;
    } handle;			/* handle */

    char *buffer;		/* buffer to store cached data*/
    int buffer_len;		/* currently allocated buffers length */
    int buffer_pos;		/* end of data in buffer*/
    int still_running;		/* Is background url fetch still in progress */
};

typedef struct fcurl_data URL_FILE;

/* exported functions */
URL_FILE *url_fopen(char *url,const char *operation);
int url_fclose(URL_FILE *file);
int url_feof(URL_FILE *file);
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
char * url_fgets(char *ptr, int size, URL_FILE *file);
void url_rewind(URL_FILE *file);

/* we use a global one for convenience */
CURLM *multi_handle;

/* curl calls this routine to get more data */
static size_t
write_callback(char *buffer,
	       size_t size,
	       size_t nitems,
	       void *userp)
{
    char *newbuff;
    int rembuff;

    URL_FILE *url = (URL_FILE *)userp;
    size *= nitems;

    rembuff=url->buffer_len - url->buffer_pos;//remaining space in buffer

    if(size > rembuff)
    {
	//not enuf space in buffer
	newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff));
	if(newbuff==NULL)
	{
	    fprintf(stderr,"callback buffer grow failed\n");
	    size=rembuff;
	}
	else
	{
	    /* realloc suceeded increase buffer size*/
	    url->buffer_len+=size - rembuff;
	    url->buffer=newbuff;

	    /*printf("Callback buffer grown to %d bytes\n",url->buffer_len);*/
	}
    }

    memcpy(&url->buffer[url->buffer_pos], buffer, size);
    url->buffer_pos += size;

    /*fprintf(stderr, "callback %d size bytes\n", size);*/

    return size;
}

/* use to attempt to fill the read buffer up to requested number of bytes */
static int
curl_fill_buffer(URL_FILE *file,int want,int waittime)
{
    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd;
    struct timeval timeout;
    int rc;

    /* only attempt to fill buffer if transactions still running and buffer
     * doesnt exceed required size already
     */
    if((!file->still_running) || (file->buffer_pos > want))
	return 0;

    /* attempt to fill buffer */
    do
    {
	FD_ZERO(&fdread);
	FD_ZERO(&fdwrite);
	FD_ZERO(&fdexcep);

	/* set a suitable timeout to fail on */
	timeout.tv_sec = 60; /* 1 minute */
	timeout.tv_usec = 0;

	/* get file descriptors from the transfers */
	curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

	rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

	switch(rc) {
	case -1:
	    /* select error */
	    break;

	case 0:
	    break;

	default:
	    /* timeout or readable/writable sockets */
	    /* note we *could* be more efficient and not wait for
	     * CURLM_CALL_MULTI_PERFORM to clear here and check it on re-entry
	     * but that gets messy */
	    while(curl_multi_perform(multi_handle, &file->still_running) ==
		  CURLM_CALL_MULTI_PERFORM);

	    break;
	}
    } while(file->still_running && (file->buffer_pos < want));
    return 1;
}

/* use to remove want bytes from the front of a files buffer */
static int
curl_use_buffer(URL_FILE *file,int want)
{
    /* sort out buffer */
    if((file->buffer_pos - want) <=0)
    {
	/* ditch buffer - write will recreate */
	if(file->buffer)
	    free(file->buffer);

	file->buffer=NULL;
	file->buffer_pos=0;
	file->buffer_len=0;
    }
    else
    {
	/* move rest down make it available for later */
	memmove(file->buffer,
		&file->buffer[want],
		(file->buffer_pos - want));

	file->buffer_pos -= want;
    }
    return 0;
}



URL_FILE *
url_fopen(char *url,const char *operation)
{
    /* this code could check for URLs or types in the 'url' and
       basicly use the real fopen() for standard files */

    URL_FILE *file;
    (void)operation;

    file = (URL_FILE *)malloc(sizeof(URL_FILE));
    if(!file)
	return NULL;

    memset(file, 0, sizeof(URL_FILE));

    if((file->handle.file=fopen(url,operation)))
    {
	file->type = CFTYPE_FILE; /* marked as URL */
    }
    else
    {
	file->type = CFTYPE_CURL; /* marked as URL */
	file->handle.curl = curl_easy_init();

	curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
	curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file);
	curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, FALSE);
	curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);

	if(!multi_handle)
	    multi_handle = curl_multi_init();

	curl_multi_add_handle(multi_handle, file->handle.curl);

	/* lets start the fetch */
	while(curl_multi_perform(multi_handle, &file->still_running) ==
	      CURLM_CALL_MULTI_PERFORM );

	if((file->buffer_pos == 0) && (!file->still_running))
	{
	    /* if still_running is 0 now, we should return NULL */

	    /* make sure the easy handle is not in the multi handle anymore */
	    curl_multi_remove_handle(multi_handle, file->handle.curl);

	    /* cleanup */
	    curl_easy_cleanup(file->handle.curl);

	    free(file);

	    file = NULL;
	}
    }
    return file;
}

int
url_fclose(URL_FILE *file)
{
    int ret=0;/* default is good return */

    switch(file->type)
    {
    case CFTYPE_FILE:
	ret=fclose(file->handle.file); /* passthrough */
	break;

    case CFTYPE_CURL:
	/* make sure the easy handle is not in the multi handle anymore */
	curl_multi_remove_handle(multi_handle, file->handle.curl);

	/* cleanup */
	curl_easy_cleanup(file->handle.curl);
	break;

    default: /* unknown or supported type - oh dear */
	ret=EOF;
	errno=EBADF;
	break;

    }

    if(file->buffer)
	free(file->buffer);/* free any allocated buffer space */

    free(file);

    return ret;
}

int
url_feof(URL_FILE *file)
{
    int ret=0;

    switch(file->type)
    {
    case CFTYPE_FILE:
	ret=feof(file->handle.file);
	break;

    case CFTYPE_CURL:
	if((file->buffer_pos == 0) && (!file->still_running))
	    ret = 1;
	break;
    default: /* unknown or supported type - oh dear */
	ret=-1;
	errno=EBADF;
	break;
    }
    return ret;
}

size_t
url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
{
    size_t want;

    switch(file->type)
    {
    case CFTYPE_FILE:
	want=fread(ptr,size,nmemb,file->handle.file);
	break;

    case CFTYPE_CURL:
	want = nmemb * size;

	curl_fill_buffer(file,want,1);

	/* check if theres data in the buffer - if not curl_fill_buffer()
	 * either errored or EOF */
	if(!file->buffer_pos)
	    return 0;

	/* ensure only available data is considered */
	if(file->buffer_pos < want)
	    want = file->buffer_pos;

	/* xfer data to caller */
	memcpy(ptr, file->buffer, want);

	curl_use_buffer(file,want);

	want = want / size;	/* number of items - nb correct op - checked
				 * with glibc code*/

	/*printf("(fread) return %d bytes %d left\n", want,file->buffer_pos);*/
	break;

    default: /* unknown or supported type - oh dear */
	want=0;
	errno=EBADF;
	break;

    }
    return want;
}

char *
url_fgets(char *ptr, int size, URL_FILE *file)
{
    int want = size - 1;/* always need to leave room for zero termination */
    int loop;

    switch(file->type)
    {
    case CFTYPE_FILE:
	ptr = fgets(ptr,size,file->handle.file);
	break;

    case CFTYPE_CURL:
	curl_fill_buffer(file,want,1);

	/* check if theres data in the buffer - if not fill either errored or
	 * EOF */
	if(!file->buffer_pos)
	    return NULL;

	/* ensure only available data is considered */
	if(file->buffer_pos < want)
	    want = file->buffer_pos;

	/*buffer contains data */
	/* look for newline or eof */
	for(loop=0;loop < want;loop++)
	{
	    if(file->buffer[loop] == '\n')
	    {
		want=loop+1;/* include newline */
		break;
	    }
	}

	/* xfer data to caller */
	memcpy(ptr, file->buffer, want);
	ptr[want]=0;/* allways null terminate */

	curl_use_buffer(file,want);

	/*printf("(fgets) return %d bytes %d left\n", want,file->buffer_pos);*/
	break;

    default: /* unknown or supported type - oh dear */
	ptr=NULL;
	errno=EBADF;
	break;
    }

    return ptr;/*success */
}

void
url_rewind(URL_FILE *file)
{
    switch(file->type)
    {
    case CFTYPE_FILE:
	rewind(file->handle.file); /* passthrough */
	break;

    case CFTYPE_CURL:
	/* halt transaction */
	curl_multi_remove_handle(multi_handle, file->handle.curl);

	/* restart */
	curl_multi_add_handle(multi_handle, file->handle.curl);

	/* ditch buffer - write will recreate - resets stream pos*/
	if(file->buffer)
	    free(file->buffer);

	file->buffer=NULL;
	file->buffer_pos=0;
	file->buffer_len=0;

	break;

    default: /* unknown or supported type - oh dear */
	break;

    }

}


/* Small main program to retrive from a url using fgets and fread saving the
 * output to two test files (note the fgets method will corrupt binary files if
 * they contain 0 chars */
int
main(int argc, char *argv[])
{
    URL_FILE *handle;
    FILE *outf;

    int nread;
    char buffer[256];
    char *url;

    if(argc < 2)
    {
	url="http://192.168.7.3/testfile";/* default to testurl */
    }
    else
    {
	url=argv[1];/* use passed url */
    }

    /* copy from url line by line with fgets */
    outf=fopen("fgets.test","w+");
    if(!outf)
    {
	perror("couldnt open fgets output file\n");
	return 1;
    }

    handle = url_fopen(url, "r");
    if(!handle)
    {
	printf("couldn't url_fopen()\n");
	fclose(outf);
	return 2;
    }

    while(!url_feof(handle))
    {
	url_fgets(buffer,sizeof(buffer),handle);
	fwrite(buffer,1,strlen(buffer),outf);
    }

    url_fclose(handle);

    fclose(outf);


    /* Copy from url with fread */
    outf=fopen("fread.test","w+");
    if(!outf)
    {
	perror("couldnt open fread output file\n");
	return 1;
    }

    handle = url_fopen("testfile", "r");
    if(!handle) {
	printf("couldn't url_fopen()\n");
	fclose(outf);
	return 2;
    }

    do {
	nread = url_fread(buffer, 1,sizeof(buffer), handle);
	fwrite(buffer,1,nread,outf);
    } while(nread);

    url_fclose(handle);

    fclose(outf);


    /* Test rewind */
    outf=fopen("rewind.test","w+");
    if(!outf)
    {
	perror("couldnt open fread output file\n");
	return 1;
    }

    handle = url_fopen("testfile", "r");
    if(!handle) {
	printf("couldn't url_fopen()\n");
	fclose(outf);
	return 2;
    }

	nread = url_fread(buffer, 1,sizeof(buffer), handle);
	fwrite(buffer,1,nread,outf);
	url_rewind(handle);

	buffer[0]='\n';
	fwrite(buffer,1,1,outf);

	nread = url_fread(buffer, 1,sizeof(buffer), handle);
	fwrite(buffer,1,nread,outf);


    url_fclose(handle);

    fclose(outf);


    return 0;/* all done */
}
