diff Plugins/Input/timidity/libtimidity/stream.c @ 285:d1762728ea4b trunk

[svn] Timidity support, via external contractor dai+audacious@cdr.jp.
author nenolod
date Wed, 14 Dec 2005 08:51:51 -0800
parents
children c1dfb4b13be8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/timidity/libtimidity/stream.c	Wed Dec 14 08:51:51 2005 -0800
@@ -0,0 +1,188 @@
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "string.h"
+
+#include "timidity.h"
+#include "timidity_internal.h"
+#include "common.h"
+
+struct _MidIStream
+{
+  MidIStreamReadFunc read;
+  MidIStreamCloseFunc close;
+  void *ctx;
+};
+
+typedef struct StdIOContext
+{
+  FILE *fp;
+  int autoclose;
+} StdIOContext;
+
+size_t
+stdio_istream_read (void *ctx, void *ptr, size_t size, size_t nmemb)
+{
+  return fread (ptr, size, nmemb, ((StdIOContext *) ctx)->fp);
+}
+
+int
+stdio_istream_close (void *ctx)
+{
+  int ret = 0;
+  if (((StdIOContext *) ctx)->autoclose)
+    ret = fclose (((StdIOContext *) ctx)->fp);
+  free (ctx);
+  return ret;
+}
+
+typedef struct MemContext
+{
+  sint8 *base;
+  sint8 *current;
+  sint8 *end;
+  int autofree;
+} MemContext;
+
+size_t
+mem_istream_read (void *ctx, void *ptr, size_t size, size_t nmemb)
+{
+  MemContext *c;
+  size_t count;
+
+  c = (MemContext *) ctx;
+  count = nmemb;
+
+  if (c->current + count * size > c->end)
+    count = (c->end - c->current) / size;
+
+  memcpy (ptr, c->current, count * size);
+  c->current += count * size;
+
+  return count;
+}
+
+int
+mem_istream_close (void *ctx)
+{
+  if (((MemContext *) ctx)->autofree)
+    free (((MemContext *) ctx)->base);
+  free (ctx);
+  return 0;
+}
+
+MidIStream *
+mid_istream_open_fp (FILE * fp, int autoclose)
+{
+  StdIOContext *ctx;
+  MidIStream *stream;
+
+  stream = safe_malloc (sizeof (MidIStream));
+  if (stream == NULL)
+    return NULL;
+
+  ctx = safe_malloc (sizeof (StdIOContext));
+  if (ctx == NULL)
+    {
+      free (stream);
+      return NULL;
+    }
+  ctx->fp = fp;
+  ctx->autoclose = autoclose;
+
+  stream->ctx = ctx;
+  stream->read = stdio_istream_read;
+  stream->close = stdio_istream_close;
+
+  return stream;
+}
+
+MidIStream *
+mid_istream_open_file (const char *file)
+{
+  FILE *fp;
+
+  fp = fopen (file, "rb");
+  if (fp == NULL)
+    return NULL;
+
+  return mid_istream_open_fp (fp, 1);
+}
+
+MidIStream *
+mid_istream_open_mem (void *mem, size_t size, int autofree)
+{
+  MemContext *ctx;
+  MidIStream *stream;
+
+  stream = safe_malloc (sizeof (MidIStream));
+  if (stream == NULL)
+    return NULL;
+
+  ctx = safe_malloc (sizeof (MemContext));
+  if (ctx == NULL)
+    {
+      free (stream);
+      return NULL;
+    }
+  ctx->base = mem;
+  ctx->current = mem;
+  ctx->end = ((sint8 *) mem) + size;
+  ctx->autofree = autofree;
+
+  stream->ctx = ctx;
+  stream->read = mem_istream_read;
+  stream->close = mem_istream_close;
+
+  return stream;
+}
+
+MidIStream *
+mid_istream_open_callbacks (MidIStreamReadFunc read,
+			    MidIStreamCloseFunc close, void *context)
+{
+  MidIStream *stream;
+
+  stream = safe_malloc (sizeof (MidIStream));
+  if (stream == NULL)
+    return NULL;
+
+  stream->ctx = context;
+  stream->read = read;
+  stream->close = close;
+
+  return stream;
+}
+
+size_t
+mid_istream_read (MidIStream * stream, void *ptr, size_t size, size_t nmemb)
+{
+  return stream->read (stream->ctx, ptr, size, nmemb);
+}
+
+void
+mid_istream_skip (MidIStream * stream, size_t len)
+{
+  size_t c;
+  char tmp[1024];
+  while (len > 0)
+    {
+      c = len;
+      if (c > 1024)
+	c = 1024;
+      len -= c;
+      if (c != mid_istream_read (stream, tmp, 1, c))
+	{
+	  DEBUG_MSG ("mid_istream_skip error\n");
+	}
+    }
+}
+
+int
+mid_istream_close (MidIStream * stream)
+{
+  int ret = stream->close (stream->ctx);
+  free (stream);
+  return ret;
+}