#ifndef XPKMASTER_HOOK_C
#define XPKMASTER_HOOK_C

/* Routinesheader

	Name:		hook.c
	Main:		xpkmaster
	Versionstring:	$VER: hook.c 1.5 (13.09.1998)
	Author:		SDI
	Distribution:	Freeware
	Description:	Hook handling functions

 1.0   05.10.96 : first real version
 1.1   27.12.96 : removed V37 defines
 1.2   20.12.97 : nearly rewritten
 1.3   09.01.98 : added XPK_ALLINONE
 1.4   26.08.98 : returns XPKERR_BADPARAMS, when no hook exists
 1.5   13.09.98 : added seek support
*/

#include <exec/types.h>
#include "xpkmaster.h"

#ifdef DEBUG
static STRPTR action_names[8] =
{"<zero>", "XIO_READ", "XIO_WRITE", "XIO_FREE", "XIO_ABORT", "XIO_GETBUF",
"XIO_SEEK", "XIO_TOTSIZE" };
#endif

static APTR callhook(struct XpkBuffer *xbuf, ULONG action, APTR buf,
LONG size, struct XpkMasterMsg *msg, struct Hook *hook)
{
  LONG res;

  msg->xmm_Type = action;
  msg->xmm_Ptr = (STRPTR) buf;
  msg->xmm_Size = size;

  if(!hook)
  {
    xbuf->xb_Result = XPKERR_BADPARAMS;
    return 0;
  }

  if((res = CallRegHook(hook->h_Entry, hook, msg, 0)))
  {
    xbuf->xb_Result = res;
#ifdef DEBUG
    DebugError("hook%s: %s <%ld> (%ld)", msg == &xbuf->xb_RMsg ? "read" :
    "write", action_names[(action&7)], action, xbuf->xb_Result);
#endif
  }

  if(xbuf->xb_Result)
    return 0;
  else if(msg->xmm_Ptr)
    return (APTR) msg->xmm_Ptr;
  else
    return (APTR) -1; /* SEEK may return 0 on success! */
}

/*************************** read from input hook ************************/

XPK_ALLINONE APTR hookread(struct XpkBuffer *xbuf, ULONG action, APTR buf,
LONG size)
{
  if(action == XIO_READ || action == XIO_SEEK)
    xbuf->xb_InBufferPos += size;
  return callhook(xbuf, action, buf, size, &xbuf->xb_RMsg, xbuf->xb_RHook);
}

/*************************** write to output hook ************************/

XPK_ALLINONE APTR hookwrite(struct XpkBuffer *xbuf, ULONG action, APTR buf,
LONG size)
{
  return callhook(xbuf, action, buf, size, &xbuf->xb_WMsg, xbuf->xb_WHook);
}

#endif /* XPKMASTER_HOOK_C */
