/***************************************************************************
 *                                                                         *
 *   DATSTM.C                                                              *
 *                                                                         *
 *   Copyright (c) 1994-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   DataStream API - Interface between byte sources (servers) and         *
 *                    byte sinks (clients)                                 *
 *                                                                         *
 *   This .C file contains stubs and utilities for use by DataStream       *
 *   API routines, especially for fleshing out the routines in sink        *
 *   structures.                                                           *
 *                                                                         *
 *                                             - R. Stein  5/9/94          *
 *                                                                         *
 ***************************************************************************/

#define FILREV "$Revision: 6 $"

#include "gcomm.h"
#include "datstm.h"

#define bdsp ((struct bufstm *)(dsp))   /* used by xxbufs() routines       */

/*--- Stub routines for sinks implemented via moveit()  ---*/
/*---------------------------------------------------------*/
/*--- (Both parties may want to move the bytes, so the  ---*/
/*--- sink surrounds its datstm structure with a bufstm ---*/
/*--- structure, which specifies a buffer to interpose  ---*/
/*--- between the two non-lazy parties.)                ---*/

USHORT                             /*   returns room in buffer             */
swbufs(                            /* snkwin() stub for buffered DataStream*/
struct datstm FAR *dsp)            /*   dataStream structure inside bufstm */
{
     ASSERTM(bdsp->bufcnt <= bdsp->bufsiz,spr("bufcnt=%u bufsiz=%u",
                                              bdsp->bufcnt,bdsp->bufsiz));
     dsp->snkloc=bdsp->buffer+bdsp->bufcnt;
     dsp->snkmax=bdsp->bufsiz;
     return(bdsp->bufsiz-bdsp->bufcnt);
}

VOID
hobufs(                            /* hrsone() stub for buffered DataStream*/
struct datstm FAR *dsp,            /*   dataStream structure inside bufstm */
CHAR byte)                         /*   here's the one byte                */
{
     if (bdsp->bufcnt < bdsp->bufsiz) {
          bdsp->buffer[bdsp->bufcnt++]=byte;
          if (bdsp->bufcnt == bdsp->bufsiz) {
               dsp->didmov(dsp,0);      /* attempt to "flush" buffer       */
          }
     }
     else {
          dsp->flags|=DSTOVF;
     }
}

VOID
dmbufs(                            /* didmov() stub for buffered DataStream*/
struct datstm FAR *dsp,            /*   dataStream structure inside bufstm */
USHORT nactual)                    /*   this many were moved by the source */
{
     USHORT nfedback;

     ASSERTM(nactual <= bdsp->bufsiz,spr("nactual=%u",nactual));
     if ((bdsp->bufcnt+=nactual) > 0) {
          ASSERTM(bdsp->bufcnt <= bdsp->bufsiz,spr("bufcnt=%u bufsiz=%u",
                                                   bdsp->bufcnt,bdsp->bufsiz));
          nfedback=dsp->moveit(dsp,bdsp->buffer,(USHORT)bdsp->bufcnt);
          ASSERTM(nfedback <= bdsp->bufcnt,spr("nfedback=%u bufcnt=%u",
                                               nfedback,bdsp->bufcnt));
          if (0 < nfedback && nfedback < bdsp->bufcnt) {
               movmem(bdsp->buffer+nfedback,
                      bdsp->buffer,bdsp->bufcnt-nfedback);
          }
          bdsp->bufcnt-=nfedback;
     }
}

/*--- Stub routines for sinks implemented via snkwin() & didmov() ---*/
/*-------------------------------------------------------------------*/
/*--- (Neither party may want to move the bytes, so a movmem()    ---*/
/*--- may need to intervene between the two lazy parties.)        ---*/

USHORT                             /*   rets actual number of bytes moved  */
mviad(                             /* moveit() stub via didmov() & snkwin()*/
struct datstm FAR *dsp,            /*   dataStream structure               */
CHAR FAR *srcloc,                  /*   source location                    */
USHORT nwant)                      /*   number of bytes desired to move    */
{
     USHORT nroom,nactual,ntotal;
     INT tryit;

     ntotal=0;
     for (tryit=0 ; tryit <= 2 && nwant > 0 ; tryit++) {
          nroom=dsp->snkwin(dsp);
          if (nroom == 0) {
               break;
          }
          nactual=min(nwant,nroom);
          movmem(srcloc,dsp->snkloc,nactual);
          dsp->didmov(dsp,nactual);
          srcloc+=nactual;
          nwant-=nactual;
          ntotal+=nactual;
     }
     return(ntotal);
}

VOID
hviad(                             /* hrsone() stub via didmov() & snkwin()*/
struct datstm FAR *dsp,            /*   dataStream structure               */
CHAR byte)                         /*   data byte                          */
{
     if (dsp->snkwin(dsp) >= 1) {
          dsp->snkloc[0]=byte;
          dsp->didmov(dsp,1);
     }
     else {
          dsp->flags|=DSTOVF;
     }
}
