Back to index

plt-scheme  4.2.1
gd_io_ss.c
Go to the documentation of this file.
00001 
00002 /*
00003    * io_ss.c
00004    *
00005    * Implements the Source/Sink interface.
00006    *
00007    * As will all I/O modules, most functions are for local use only (called
00008    * via function pointers in the I/O context).
00009    *
00010    * The Source/Sink model is the primary 'user' interface for alternate data
00011    * sources; the IOCtx interface is intended (at least in version 1.5) to be
00012    * used internally until it settles down a bit.
00013    *
00014    * This module just layers the Source/Sink interface on top of the IOCtx; no
00015    * support is provided for tell/seek, so GD2 writing is not possible, and 
00016    * retrieving parts of GD2 files is also not possible.
00017    *
00018    * A new SS context does not need to be created with both a Source and a Sink.
00019    *
00020    * Written/Modified 1999, Philip Warner.
00021    *
00022  */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #include "config.h"
00026 #endif
00027 
00028 #include <math.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include "gd.h"
00032 #include "gdhelpers.h"
00033 
00034 /* this is used for creating images in main memory */
00035 
00036 typedef struct ssIOCtx
00037 {
00038   gdIOCtx ctx;
00039   gdSourcePtr src;
00040   gdSinkPtr snk;
00041 }
00042 ssIOCtx;
00043 
00044 typedef struct ssIOCtx *ssIOCtxPtr;
00045 
00046 gdIOCtx *gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk);
00047 
00048 static int sourceGetbuf (gdIOCtx *, void *, int);
00049 static int sourceGetchar (gdIOCtx * ctx);
00050 static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size);
00051 static void sinkPutchar (gdIOCtx * ctx, int a);
00052 static void gdFreeSsCtx (gdIOCtx * ctx);
00053 
00054 /* return data as a dynamic pointer */
00055 gdIOCtx *
00056 gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
00057 {
00058   ssIOCtxPtr ctx;
00059 
00060   ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
00061   if (ctx == NULL)
00062     {
00063       return NULL;
00064     }
00065 
00066   ctx->src = src;
00067   ctx->snk = snk;
00068 
00069   ctx->ctx.getC = sourceGetchar;
00070   ctx->ctx.getBuf = sourceGetbuf;
00071 
00072   ctx->ctx.putC = sinkPutchar;
00073   ctx->ctx.putBuf = sinkPutbuf;
00074 
00075   ctx->ctx.tell = NULL;
00076   ctx->ctx.seek = NULL;
00077 
00078   ctx->ctx.gd_free = gdFreeSsCtx;
00079 
00080   return (gdIOCtx *) ctx;
00081 }
00082 
00083 static void
00084 gdFreeSsCtx (gdIOCtx * ctx)
00085 {
00086   gdFree (ctx);
00087 }
00088 
00089 
00090 static int
00091 sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
00092 {
00093   ssIOCtx *lctx;
00094   int res;
00095 
00096   lctx = (ssIOCtx *) ctx;
00097 
00098   res = ((lctx->src->source) (lctx->src->context, buf, size));
00099 
00100 /*
00101    ** Translate the return values from the Source object: 
00102    ** 0 is EOF, -1 is error
00103  */
00104 
00105   if (res == 0)
00106     {
00107       return EOF;
00108     }
00109   else if (res < 0)
00110     {
00111       return 0;
00112     }
00113   else
00114     {
00115       return res;
00116     };
00117 
00118 }
00119 
00120 static int
00121 sourceGetchar (gdIOCtx * ctx)
00122 {
00123   int res;
00124   unsigned char buf;
00125 
00126   res = sourceGetbuf (ctx, &buf, 1);
00127 
00128   if (res == 1)
00129     {
00130       return buf;
00131     }
00132   else
00133     {
00134       return EOF;
00135     };
00136 
00137 }
00138 
00139 static int
00140 sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
00141 {
00142   ssIOCtxPtr lctx;
00143   int res;
00144 
00145   lctx = (ssIOCtx *) ctx;
00146 
00147   res = (lctx->snk->sink) (lctx->snk->context, buf, size);
00148 
00149   if (res <= 0)
00150     {
00151       return 0;
00152     }
00153   else
00154     {
00155       return res;
00156     };
00157 
00158 }
00159 
00160 static void
00161 sinkPutchar (gdIOCtx * ctx, int a)
00162 {
00163   unsigned char b;
00164 
00165   b = a;
00166   sinkPutbuf (ctx, &b, 1);
00167 
00168 }