aboutsummaryrefslogtreecommitdiff
path: root/lib/timidity/libarc/url_cache.c
diff options
context:
space:
mode:
authortheuni <theuni-nospam-@xbmc.org>2011-01-24 16:05:21 -0500
committertheuni <theuni-nospam-@xbmc.org>2011-01-24 16:05:21 -0500
commitc51b1189e3d5353e842991f5859ddcea0f73e426 (patch)
treeef2cb8a6184699aa614f3655dca4ce661cdc108e /lib/timidity/libarc/url_cache.c
parentbe61ebdc9e897fe40c6f371111724de79ddee8d5 (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.c255
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);
+}