diff options
author | theuni <theuni-nospam-@xbmc.org> | 2011-01-24 16:05:21 -0500 |
---|---|---|
committer | theuni <theuni-nospam-@xbmc.org> | 2011-01-24 16:05:21 -0500 |
commit | c51b1189e3d5353e842991f5859ddcea0f73e426 (patch) | |
tree | ef2cb8a6184699aa614f3655dca4ce661cdc108e /lib/timidity/libarc/url_cache.c | |
parent | be61ebdc9e897fe40c6f371111724de79ddee8d5 (diff) |
Merged cptspiff's code-reshuffle branch.
Squashed commit due to build breakage during code-reshuffle history.
Conflicts:
xbmc/Util.cpp
xbmc/cdrip/CDDARipper.cpp
xbmc/filesystem/Directory.cpp
xbmc/filesystem/File.cpp
Diffstat (limited to 'lib/timidity/libarc/url_cache.c')
-rw-r--r-- | lib/timidity/libarc/url_cache.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/lib/timidity/libarc/url_cache.c b/lib/timidity/libarc/url_cache.c new file mode 100644 index 0000000000..dfcc422d71 --- /dev/null +++ b/lib/timidity/libarc/url_cache.c @@ -0,0 +1,255 @@ +/* + TiMidity++ -- MIDI to WAVE converter and player + Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp> + Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ +#include <stdio.h> +#include <stdlib.h> + +#include "timidity.h" +#include "url.h" +#include "memb.h" + +typedef struct _URL_cache +{ + char common[sizeof(struct _URL)]; + URL reader; + int memb_ok; + MemBuffer b; + long pos; + int autoclose; +} URL_cache; + +static long url_cache_read(URL url, void *buff, long n); +static int url_cache_fgetc(URL url); +static long url_cache_seek(URL url, long offset, int whence); +static long url_cache_tell(URL url); +static void url_cache_close(URL url); + +URL url_cache_open(URL url, int autoclose) +{ + URL_cache *urlp; + + if(url->type == URL_cache_t && autoclose) + { + if(((URL_cache *)url)->memb_ok) + delete_memb(&((URL_cache *)url)->b); + urlp = (URL_cache *)url; + url = urlp->reader; + } + else + { + if((urlp = (URL_cache *)alloc_url(sizeof(URL_cache))) == NULL) + { + if(autoclose) + url_close(url); + return NULL; + } + } + + /* common members */ + URLm(urlp, type) = URL_cache_t; + URLm(urlp, url_read) = url_cache_read; + URLm(urlp, url_gets) = NULL; + URLm(urlp, url_fgetc) = url_cache_fgetc; + URLm(urlp, url_seek) = url_cache_seek; + URLm(urlp, url_tell) = url_cache_tell; + URLm(urlp, url_close) = url_cache_close; + + /* private members */ + urlp->reader = url; + urlp->memb_ok = 1; + init_memb(&urlp->b); + urlp->pos = 0; + urlp->autoclose = autoclose; + + return (URL)urlp; +} + +void url_cache_disable(URL url) +{ + if(url->type == URL_cache_t) + url->url_seek = NULL; +} + +void url_cache_detach(URL url) +{ + if(url != NULL && url->type == URL_cache_t) + { + URL_cache *urlp = (URL_cache *)url; + if(urlp->autoclose && urlp->reader != NULL) + url_close(urlp->reader); + urlp->reader = NULL; + } +} + +static long url_cache_read(URL url, void *buff, long n) +{ + URL_cache *urlp = (URL_cache *)url; + MemBuffer *b = &urlp->b; + + if(!urlp->memb_ok) + { + if(urlp->reader == NULL) + return 0; + n = url_read(urlp->reader, buff, n); + if(n > 0) + urlp->pos += n; + return n; + } + + if(urlp->pos < b->total_size) + { + if(n > b->total_size - urlp->pos) + n = b->total_size - urlp->pos; + urlp->pos += read_memb(b, buff, n); + return n; + } + + if(url->url_seek == NULL) + { + delete_memb(b); + urlp->memb_ok = 0; + if(urlp->reader == NULL) + return 0; + n = url_read(urlp->reader, buff, n); + if(n > 0) + urlp->pos += n; + return n; + } + + if(urlp->reader == NULL) + return 0; + n = url_read(urlp->reader, buff, n); + if(n > 0) + { + push_memb(b, buff, n); + b->cur = b->tail; + b->cur->pos = b->cur->size; + urlp->pos += n; + } + return n; +} + +static int url_cache_fgetc(URL url) +{ + URL_cache *urlp = (URL_cache *)url; + MemBuffer *b = &urlp->b; + char c; + int i; + + if(!urlp->memb_ok) + { + if(urlp->reader == NULL) + return EOF; + if((i = url_getc(urlp->reader)) == EOF) + return EOF; + urlp->pos++; + return i; + } + + if(urlp->pos < b->total_size) + { + read_memb(b, &c, 1); + urlp->pos++; + return (int)(unsigned char)c; + } + + if(url->url_seek == NULL) + { + delete_memb(b); + urlp->memb_ok = 0; + if(urlp->reader == NULL) + return EOF; + if((i = url_getc(urlp->reader)) == EOF) + return EOF; + urlp->pos++; + return i; + } + + if(urlp->reader == NULL) + return EOF; + if((i = url_getc(urlp->reader)) == EOF) + return EOF; + c = (char)i; + push_memb(b, &c, 1); + b->cur = b->tail; + b->cur->pos = b->cur->size; + urlp->pos++; + return i; +} + +static long url_cache_seek(URL url, long offset, int whence) +{ + URL_cache *urlp = (URL_cache *)url; + MemBuffer *b = &urlp->b; + long ret, newpos, n, s; + + ret = urlp->pos; + switch(whence) + { + case SEEK_SET: + newpos = offset; + break; + case SEEK_CUR: + newpos = ret + offset; + break; + case SEEK_END: + while(url_cache_fgetc(url) != EOF) + ; + newpos = b->total_size + whence; + break; + default: + url_errno = errno = EPERM; + return -1; + } + if(newpos < 0) + newpos = 0; + n = newpos - ret; + + if(n < 0) + { + rewind_memb(b); + n = newpos; + urlp->pos = 0; + } + + s = skip_read_memb(b, n); + urlp->pos += s; + while(s++ < n && url_cache_fgetc(url) != EOF) + ; + return ret; +} + +static long url_cache_tell(URL url) +{ + return ((URL_cache *)url)->pos; +} + +static void url_cache_close(URL url) +{ + URL_cache *urlp = (URL_cache *)url; + if(urlp->autoclose && urlp->reader != NULL) + url_close(urlp->reader); + if(urlp->memb_ok) + delete_memb(&urlp->b); + free(urlp); +} |