Back to index

tetex-bin  3.0
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 static int sourceGetbuf (gdIOCtx *, void *, int);
00047 static int sourceGetchar (gdIOCtx * ctx);
00048 static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size);
00049 static void sinkPutchar (gdIOCtx * ctx, int a);
00050 static void gdFreeSsCtx (gdIOCtx * ctx);
00051 
00052 /* return data as a dynamic pointer */
00053 BGD_DECLARE(gdIOCtx *) gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
00054 {
00055   ssIOCtxPtr ctx;
00056 
00057   ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
00058   if (ctx == NULL)
00059     {
00060       return NULL;
00061     }
00062 
00063   ctx->src = src;
00064   ctx->snk = snk;
00065 
00066   ctx->ctx.getC = sourceGetchar;
00067   ctx->ctx.getBuf = sourceGetbuf;
00068 
00069   ctx->ctx.putC = sinkPutchar;
00070   ctx->ctx.putBuf = sinkPutbuf;
00071 
00072   ctx->ctx.tell = NULL;
00073   ctx->ctx.seek = NULL;
00074 
00075   ctx->ctx.gd_free = gdFreeSsCtx;
00076 
00077   return (gdIOCtx *) ctx;
00078 }
00079 
00080 static void
00081 gdFreeSsCtx (gdIOCtx * ctx)
00082 {
00083   gdFree (ctx);
00084 }
00085 
00086 
00087 static int
00088 sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
00089 {
00090   ssIOCtx *lctx;
00091   int res;
00092 
00093   lctx = (ssIOCtx *) ctx;
00094 
00095   res = ((lctx->src->source) (lctx->src->context, buf, size));
00096 
00097 /*
00098    ** Translate the return values from the Source object: 
00099    ** 0 is EOF, -1 is error
00100  */
00101 
00102   if (res == 0)
00103     {
00104       return EOF;
00105     }
00106   else if (res < 0)
00107     {
00108       return 0;
00109     }
00110   else
00111     {
00112       return res;
00113     };
00114 
00115 }
00116 
00117 static int
00118 sourceGetchar (gdIOCtx * ctx)
00119 {
00120   int res;
00121   unsigned char buf;
00122 
00123   res = sourceGetbuf (ctx, &buf, 1);
00124 
00125   if (res == 1)
00126     {
00127       return buf;
00128     }
00129   else
00130     {
00131       return EOF;
00132     };
00133 
00134 }
00135 
00136 static int
00137 sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
00138 {
00139   ssIOCtxPtr lctx;
00140   int res;
00141 
00142   lctx = (ssIOCtx *) ctx;
00143 
00144   res = (lctx->snk->sink) (lctx->snk->context, buf, size);
00145 
00146   if (res <= 0)
00147     {
00148       return 0;
00149     }
00150   else
00151     {
00152       return res;
00153     };
00154 
00155 }
00156 
00157 static void
00158 sinkPutchar (gdIOCtx * ctx, int a)
00159 {
00160   unsigned char b;
00161 
00162   b = a;
00163   sinkPutbuf (ctx, &b, 1);
00164 
00165 }