OIOIC的.c文件源代码


/**
 *
 * 文 件 名:oioic.c
 *
 * 描    述:OIOIC 的 .c 文件。
 *
 * 创 建 者:赵平智   <[email protected]>
 *
 * 创建日期:20050310
 *
 * 版    本:1.0.10
 *
 * 版权(C)2005-2010 赵平智。保留所有权利。   
 *
 * 备    注:
 *
 *
 * * 维护历史 *
 *
 *   <日期>              <修改者>
 *   <修改内容...>
 *
 **/

#include <stdlib.h>
#include <string.h>
#include "oioic.h"


/*=====================+ Interface +=====================*/

/**
*
* 名称:OIOIC_Open
* 描述:Open接口。
* 参数:pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Open(OBJECT* This, const VR* pCaller)
{
 This->RefCnt++;
 return IR_P;
}

/**
*
* 名称:OIOIC_Input
* 描述:Input接口。
* 参数:IStrm --- [IN] 输入流;
*      Qty --- [IN] 输入的Byte数量;
*      pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Input(OBJECT* This, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
 return IR_O_SBOOIX;
}

/**
*
* 名称:OIOIC_Output
* 描述:Output接口。
* 参数:OStrm --- [OUT] 输出流的流向;
*      Cty --- [IN] OStrm所指存储空间的容量;
*      pQty --- [OUT] 指向实际输出的Byte数量;
*      pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Output(OBJECT* This, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)

    return IR_O_SBOOIX;
}

/**
*
* 名称:OIOIC_IOput
* 描述:IOput接口。
* 参数:IStrm --- [IN] 输入流;
*        Qty --- [IN] 输入的Byte数量;
*        OStrm --- [OUT] 输出流的流向;
*        Cty --- [IN] OStrm所指存储空间的容量;
*        pQty --- [OUT] 指向实际输出的Byte数量;
*        pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_IOput(OBJECT* This, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
 return IR_O_SBOOIX;
}

/**
*
* 名称:OIOIC_Interact0
* 描述:Interact0接口。
* 参数:Act --- [IN] 交互行为;
*      pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Interact0(OBJECT* This, ACTION Act, const VR* pCaller)
{
 EM_OIOIC*  pem = (EM_OIOIC*)This->pEM;

 switch( Act )
 {
  case ASK_SHARED: /* 问共享么。*/
   if(pem->mds & MOD_SHARED)
    return IR_N;
   return IR_P;
  case SET_SHARED: /* 设置共享。*/
   pem->mds &= ~MOD_SHARED;
   return IR_P;
  case SET_UNSHARED: /* 设置非共享。*/
   pem->mds |= MOD_SHARED;
   return IR_P;
  case SET_BLOCKI: /* 设置阻断输入。*/
   pem->mds &= ~MOD_BLOCKI;
   return IR_P;
  case SET_UNBLOCKI: /* 设置非阻断输入。*/
   pem->mds |= MOD_BLOCKI;
   return IR_P;
  case SET_BLOCKO: /* 设置阻断输出。*/
   pem->mds &= ~MOD_BLOCKO;
   return IR_P;
  case SET_UNBLOCKO: /* 设置非阻断输出。*/
   pem->mds |= MOD_BLOCKO;
   return IR_P;
  case CMD_RESET: /* 重置。*/
   pem->IQ.Front = pem->IQ.Rear = pem->IQ.Dtrm - 1;
   pem->IQ.Qty = pem->IQ.Lost = 0;
   pem->OQ.Front = pem->OQ.Rear = pem->OQ.Dtrm - 1;
   pem->OQ.Qty = pem->OQ.Lost = 0;
   return IR_P;
  default:
   break;     
 }

 return IR_O_SBOOIX;   
}

/**
*
* 名称:OIOIC_Interact1
* 描述:Interact1接口。
* 参数:Act --- [IN] 交互行为;
*      OStrm --- [OUT] 输出流的流向;
*      Cty --- [IN] OStrm所指存储空间的容量;
*      pQty --- [OUT] 指向实际输出的Byte数量;
*      pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Interact1(OBJECT* This, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
 EM_OIOIC*   pem = (EM_OIOIC*)(This->pEM);

 switch( Act )
 {
  case GET_IQCTY: /* 获取IQ容量。*/
   assert( Cty >= sizeof(BYTKTY) );
   *((BYTKTY*)OStrm) = pem->IQ.Cty;
   *pQty = sizeof(BYTKTY);
   return IR_P;
  case GET_OQCTY: /* 获取OQ容量。*/
   assert( Cty >= sizeof(BYTKTY) );
   *((BYTKTY*)OStrm) = pem->OQ.Cty;
   *pQty = sizeof(BYTKTY);
   return IR_P;
  default:
   break;      
 }
 
 return IR_O_SBOOIX;
}

/**
*
* 名称:OIOIC_Interact2
* 描述:Interact2接口。
* 参数:Act --- [IN] 交互行为;
*      IStrm --- [IN] 输入流;
*      Qty --- [IN] 输入的Byte数量;
*      pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Interact2(OBJECT* This, ACTION  Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
 EM_OIOIC*   pem = (EM_OIOIC*)(This->pEM);

 switch( Act )
 {
  case SET_IQCTY: /* 设置IQ容量。*/
   assert( sizeof(BYTKTY) == Qty );
   if(pem->IQ.Dtrm != NULL)
    free(pem->IQ.Dtrm);
   pem->IQ.Dtrm = (BYTE*)calloc(*((BYTKTY*)IStrm), 1);
   if( pem->IQ.Dtrm != NULL )
   {
    pem->IQ.Front = pem->IQ.Rear = pem->IQ.Dtrm - 1;
    pem->IQ.Cty = *((BYTKTY*)IStrm);
    pem->IQ.Qty = pem->IQ.Lost = 0;
    return IR_P;
   }else
   {
    return IR_N;
   }
  case SET_OQCTY: /* 设置OQ容量。*/
   assert( sizeof(BYTKTY) == Qty );
   if(pem->OQ.Dtrm != NULL)
    free(pem->OQ.Dtrm);
   pem->OQ.Dtrm = (BYTE*)calloc(*((BYTKTY*)IStrm), 1);
   if( pem->OQ.Dtrm != NULL )
   {
    pem->OQ.Front = pem->OQ.Rear = pem->OQ.Dtrm - 1;
    pem->OQ.Cty = *((BYTKTY*)IStrm);
    pem->OQ.Qty = pem->OQ.Lost = 0;
    return IR_P;
   }else
   {
    return IR_N;
   }
  default:
   break;      
 }
 
 return IR_O_SBOOIX;
}

/**
*
* 名称:OIOIC_Interact3
* 描述:Interact3接口。
* 参数:Act --- [IN] 交互行为;
*      IStrm --- [IN] 输入流;
*      Qty --- [IN] 输入的Byte数量;
*      OStrm --- [OUT] 输出流的流向;
*      Cty --- [IN] OStrm所指存储空间的容量;
*      pQty --- [OUT] 指向实际输出的Byte数量;
*      pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Interact3(OBJECT* This, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)

 return IR_O_SBOOIX;
}

/**
*
* 名称:OIOIC_Close
* 描述:Close接口。
* 参数:pCaller --- [IN] 来访者。
*/
static IRESULT  OIOIC_Close(OBJECT* This, const VR* pCaller)
{
 This->RefCnt--;
 return IR_P;
}

/*========================+ TOG +========================*/

/**
*
* 名称:TOG_OIOIC
*/
VOID  TOG_OIOIC(OBJECT* pObj)
{
 pObj->Open = OIOIC_Open;
 pObj->Input = OIOIC_Input;
 pObj->Output = OIOIC_Output;
 pObj->IOput = OIOIC_IOput;
 pObj->Interact0 = OIOIC_Interact0;
 pObj->Interact1 = OIOIC_Interact1;
 pObj->Interact2 = OIOIC_Interact2;
 pObj->Interact3 = OIOIC_Interact3;
 pObj->Close = OIOIC_Close;
}

/*=============+ InitAIBofND & InitABNofND +=============*/

/* 注:InitAIBofND 和 InitABNofND只由CRT函数调用。*/

/**
*
* 名称:InitAIBofND
* 描述:初始化ND的AIB。
* 参数:pND --- [IN] ND指针;
*      pMsn --- [IN] IB的MSN数组;
*      nib --- [IN] pMsn所指数组的元素个数,即IB的数量。
* 备注:1. 只由CRT函数调用。
*      2. 注意,pMsn所指数组元素的排序决定了IB的访问顺序。
*/
VOID  InitAIBofND(OBJECT* pND, MLDSN* pMsn, NUMIB nib)
{
 NUMND   i;
 NUMIB   j;
 
 pND->NIB = nib;
 
 while(nib)
 {
  j = pND->NIB-nib;
  for(i=1; i<pND->NND; i++)
  {
   if( *(pMsn+j) == (pND->po_AND+i)->MSN )
   {
    *(pND->ppo_AIB+j) = pND->po_AND+i;
    break;
   }
  }
  nib--;
 }

/**
*
* 名称:InitABNofND
* 描述:初始化ND的ABN。
* 参数:pND --- [IN] ND指针;
*      pMsn --- [IN] BN的MSN数组;
*      nbn --- [IN] pMsn所指数组的元素个数,即BN的数量。
* 备注:只由CRT函数调用。
*/
VOID  InitABNofND(OBJECT* pND, MLDSN* pMsn, NUMBN nbn)
{
 NUMND  i;
 NUMBN  j;
 
 pND->NBN = nbn;
 
 while(nbn)
 {
  j = pND->NBN-nbn;
  for(i=1; i<pND->NND; i++)
  {
   if( *(pMsn+j) == (pND->po_AND+i)->MSN )
   {
    *(pND->ppo_ABN+j) = pND->po_AND+i;
    break;
   }
  }
  nbn--;
 }
}

/*=============+ CallerCome & CallerLeave +==============*/

/* 注:不允许外面使用 CallerCome 和 CallerLeave。*/

/**
*
* 名称:CallerCome
* 描述:来访者来访,登记来访记录。
* 参数:pND --- [IN] ND地址;
*       pCaller --- [IN] 来访者。
* 备注:不允许外面使用。
*/
FRESULT CallerCome(OBJECT* pND, const VR* pCaller)
{   
 NUMCS   i;
 VR*   pVR;
 
 /* 先检查有没有这个VR。 */
 for(i=0; i<pND->NCS; i++)
 {
  pVR = pND->pvr_ACS+i;
  if((pVR->cr == pCaller->cr) && (pVR->mr == pCaller->mr))
   return FR_N_HASVR; /* 已经有这个VR了。*/
 }

 /* 加上这个VR。 */
 for(i=0; i<pND->NCS; i++)
 {
  pVR = pND->pvr_ACS+i;
  if( 0 == pVR->cr )
  {
   *pVR = *pCaller;
   return FR_P;
  }
 }
  
 return FR_N; 
}

/**
*
* 名称:CallerLeave
* 描述:来访者离开,清除来访记录。
* 参数:pND --- [IN] ND地址;
*       pCaller --- [IN] 来访者。
* 备注:不允许外面使用。
*/
FRESULT CallerLeave(OBJECT* pND, const VR* pCaller)
{
 NUMBN  i;
 NUMCS  j;
 VR*  pVR;
 
 /* 首先ND的BN */
 for(i=0; i<pND->NBN; i++)
 {
  for(j=0; j<(*(pND->ppo_ABN+i))->NCS; j++)
  {
   pVR = (*(pND->ppo_ABN+i))->pvr_ACS+j;
     if((pVR->cr == pCaller->cr) && (pVR->mr == pCaller->mr))
    pVR->cr = pVR->mr = 0;
  }
 }
 
 /* 然后ND自己 */
 for(j=0; j<pND->NCS; j++)
 {
  pVR = pND->pvr_ACS+j;
  if((pVR->cr == pCaller->cr) && (pVR->mr == pCaller->mr))
   pVR->cr = pVR->mr = 0;
 }

 return FR_P;
}

/*==================+ Enqueue & Dequeue +================*/

/**
*
* 名称:Enqueue
* 描述:向指定的队列入列指定数量的Byte。
* 参数:IData --- [IN] 入列数据;
*       Qty --- [IN] 入列的Byte数量。
*/
FRESULT  Enqueue(QUEUE* pq, BYTE* IData, BYTKTY Qty)
{
    BYTE*     newRear;  /* 入列成功后pq->Rear应该所处的位置。*/
 BYTKTY   ctyFree, qtyEnq;
 
 assert( pq != NULL );
 assert( IData != NULL );
 
 ctyFree = pq->Cty - pq->Qty;
 qtyEnq = (ctyFree > Qty) ? Qty : ctyFree;

 
 if( 0 == qtyEnq )
 {
  if( Qty > 0 )
  {
   pq->Lost = Qty;  /* 丢失了 Qty 个Byte !*/
   return FR_N_LOST;
  }

  return FR_O_VAINLY;
 }

  
 newRear = pq->Dtrm + (pq->Rear + qtyEnq - pq->Dtrm ) % pq->Cty;
 if(newRear > pq->Rear) /* 如果入列成功,pq->Rear不须循环?*/
 {
  memcpy(pq->Rear+1, IData, qtyEnq);
 }else /* 如果入列成功,pq->Rear须循环。*/
 { 
  BYTKTY   qty1, qty2;
  qty1 = pq->Dtrm + pq->Cty - pq->Rear - 1;
  if(qty1 > 0)
   memcpy(pq->Rear+1, IData, qty1);
  qty2 = qtyEnq - qty1;
  memcpy(pq->Dtrm, IData + qty1, qty2);
 }

 pq->Rear = newRear;
 pq->Qty += qtyEnq;

 if(pq->Dtrm-1 == pq->Front)
  pq->Front = pq->Dtrm;

 if(ctyFree < Qty)
 {
    pq->Lost = Qty - ctyFree;  /* 丢失了 Qty - ctyFree 个Byte !*/
    return FR_N_LOST;
 }
 
 return FR_P;
}

/**
*
* 名称:Dequeue
* 描述:从指定队列出列Byte。
* 参数:OData --- [OUT] 出列数据的存储位置;
*       Cty --- [IN] OData所指存储空间的容量;
*       pQty --- [OUT] 指向实际出列的Byte数量。
*/
FRESULT  Dequeue(QUEUE* pq, BYTE* OData, BYTKTY Cty, BYTKTY* pQty)
{
 BYTE*    newFront;  /* 出列成功后pq->Front应该所处的位置。*/
    BYTKTY   qtyDeq;  /* 实际出列数据量。*/

 assert( pq != NULL );
 assert( OData != NULL );
 assert( Cty != 0 );
 assert( pQty != NULL );
 
 *pQty = 0; /* 先将出列数置0。*/
 
 if( pq->Qty != 0 )
 {
  qtyDeq = (Cty > pq->Qty) ? pq->Qty : Cty;

  newFront = pq->Dtrm + (pq->Front + qtyDeq - pq->Dtrm) % pq->Cty;
  if(newFront > pq->Front) /* 出列后,pq->Front不须循环? */
  {
   memcpy(OData, pq->Front, qtyDeq);
  }else /* 出列后,pq->Front须循环。*/
  {
   BYTKTY   qty1, qty2;
   qty1 = pq->Dtrm + pq->Cty - pq->Front;
   qty2 = qtyDeq - qty1;
   memcpy(OData, pq->Front, qty1);
   memcpy(OData + qty1, pq->Dtrm, qty2);
  }

  pq->Qty -= qtyDeq;

  if(0 == pq->Qty)
   pq->Front = pq->Rear = pq->Dtrm -1;
  else
   pq->Front = newFront;

 }else
 {
    return FR_O_VAINLY;
 }

 *pQty = qtyDeq;
 
 if(pq->Lost > 0)
 {
    pq->Lost = 0;
    return  FR_N_LOST;
 } 

 return FR_P;
}

/*=================+ GetBN & GetEMofBN +=================*/

/**
*
* 名称:GetBN
* 描述:获取指定BN的地址。
* 参数:pND --- [IN] ND指针;
*      msn --- [IN] BN的M。
* 返回:BN的指针。
*/
OBJECT*  GetBN(OBJECT* pND, MLDSN msn)
{
 NUMBN   i;
 
 assert( pND != NULL );

 for(i=0; i<pND->NBN; i++)
 {
  if( msn == (*(pND->ppo_ABN+i))->MSN )
   return  *(pND->ppo_ABN+i);
 }
 
 return NULL;  /* 没有这个BN。*/
}

/**
*
* 名称:GetEMofBN
* 描述:获取指定BN的EM地址。
* 参数:pND --- [IN] ND指针;
*      msn --- [IN] BN的M。
* 返回:EM的指针。
*/
EM*  GetEMofBN(OBJECT* pND, MLDSN msn)
{
 NUMBN   i;
 
 assert( pND != NULL );

 for(i=0; i<pND->NBN; i++)
 {
  if( msn == (*(pND->ppo_ABN+i))->MSN )
   return  (*(pND->ppo_ABN+i))->pEM;
 }
 
 return NULL;

/*===================+ GetIQ & GetOQ +===================*/

/**
*
* 名称:GetIQ
* 描述:获取节点的IQ指针。
* 参数:pND --- [IN] 节点指针。
* 返回:IQ的指针。
*/
QUEUE*  GetIQ(OBJECT* pND)
{
 NUMBN   i;
 
 assert( pND != NULL );

 for(i=0; i<pND->NBN; i++)
 {
  if( MSN_OIOIC == (*(pND->ppo_ABN+i))->MSN )
   return  &((EM_OIOIC*)((*(pND->ppo_ABN+i))->pEM))->IQ;
 }
 
 return NULL;
}

/**
*
* 名称:GetOQ
* 描述:获取节点的OQ指针。
* 参数:pND --- [IN] 节点指针。
* 返回:OQ的指针。
*/
QUEUE*  GetOQ(OBJECT* pND)
{
 NUMBN   i;
 
 assert( pND != NULL );

 for(i=0; i<pND->NBN; i++)
 {
  if( MSN_OIOIC == (*(pND->ppo_ABN+i))->MSN )
   return  &((EM_OIOIC*)((*(pND->ppo_ABN+i))->pEM))->OQ;
 }
 
 return NULL;
}


/*==================+  非内联VO函数  +===================*/

/* 注意:内联VO函数和非内联VO函数的功能是完全相同的。*/


#if INLINE_VOFUNCTION == 0

/**
*
* 名称:VO_Open
* 描述:接口Open的VO函数。
* 参数:pObject --- [IN] 指向对象;
*       pCaller --- [IN] 来访者。
*/                 
IRESULT  VO_Open(OBJECT* pObject, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );
 
 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Open(pObject, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}
      
/**
*
* 名称:VO_Input
* 描述:接口Input的VO函数。
* 参数:pObject --- [IN] 指向对象;
*      IStrm --- [IN] 输入流;
*      Qty --- [IN] 输入的Byte数量;
*      pCaller --- [IN] 来访者。
*/         
IRESULT  VO_Input(OBJECT* pObject, BYTE* IStrm, BYTKTY Qty, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( IStrm != NULL );
 assert( Qty > 0 );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr !=0 );

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Input(pObject, IStrm, Qty, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_Output
* 描述:接口Output的VO函数。
* 参数:pObject --- [IN] 指向对象;
*      OStrm --- [OUT] 输出流的流向;
*      Cty --- [IN] OStrm所指存储空间的容量;
*      pQty --- [OUT] 指向实际输出的Byte数量;
*      pCaller --- [IN] 来访者。
*/     
IRESULT  VO_Output(OBJECT* pObject, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( OStrm != NULL );
 assert( Cty > 0 );
 assert( pQty != NULL );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );

 *pQty = 0;

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Output(pObject, OStrm, Cty, pQty, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_IOput
* 描述:接口IOput的VO函数。
*  参数:pObject --- [IN] 指向对象;
*        IStrm --- [IN] 输入流;
*        Qty --- [IN] 输入的Byte数量;
*        OStrm --- [OUT] 输出流的流向;
*        Cty --- [IN] OStrm所指存储空间的容量;
*        pQty --- [OUT] 指向实际输出的Byte数量;
*        pCaller --- [IN] 来访者。
*/ 
IRESULT  VO_IOput(OBJECT* pObject, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);
 
 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( IStrm != NULL );
 assert( Qty > 0 );
 assert( OStrm != NULL );
 assert( Cty > 0 );
 assert( pQty != NULL );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );
 
 *pQty = 0;

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->IOput(pObject, IStrm, Qty, OStrm, Cty, pQty, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_Interact0
* 描述:接口Interact0的VO函数。
* 参数:pObject --- [IN] 指向对象;
*       Act --- [IN] 交互行为;
*       pCaller --- [IN] 来访者。
*/       
IRESULT  VO_Interact0(OBJECT* pObject, ACTION Act, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( (MSKAC & Act) == AC0 );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );
 
 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Interact0(pObject, Act, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_Interact1
* 描述:接口Interact1的VO函数。
* 参数:pObject --- [IN] 指向对象;
*      Act --- [IN] 交互行为;
*      OStrm --- [OUT] 输出流的流向;
*      Cty --- [IN] OStrm所指存储空间的容量;
*      pQty --- [OUT] 指向实际输出的Byte数量;
*      pCaller --- [IN] 来访者。
*/      
IRESULT  VO_Interact1(OBJECT* pObject, ACTION Act, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( (MSKAC & Act) == AC1 );
 assert( OStrm != NULL );
 assert( Cty > 0 );
 assert( pQty != NULL );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );

 *pQty = 0;

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Interact1(pObject, Act, OStrm, Cty, pQty, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_Interact2
* 描述:接口Interact2的VO函数。
* 参数:pObject --- [IN] 指向对象;
*       Act --- [IN] 交互行为;
*       IStrm --- [IN] 输入流;
*       Qty --- [IN] 输入的Byte数量;
*       pCaller --- [IN] 来访者。
*/      
IRESULT  VO_Interact2(OBJECT* pObject, ACTION Act, BYTE* IStrm, BYTKTY Qty, const VR* pCaller) 
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;
 
 assert( pObject != NULL );
 assert( (MSKAC & Act) == AC2 );
 assert( IStrm != NULL );
 assert( Qty > 0 );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Interact2(pObject, Act, IStrm, Qty, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_Interact3
* 描述:接口Interact3的VO函数。
* 参数:pObject --- [IN] 指向对象;
*      Act --- [IN] 交互行为;
*      IStrm --- [IN] 输入流;
*      Qty --- [IN] 输入的Byte数量;
*      OStrm --- [OUT] 输出流的流向;
*      Cty --- [IN] OStrm所指存储空间的容量;
*      pQty --- [OUT] 指向实际输出的Byte数量;
*      pCaller --- [IN] 来访者。
*/      
IRESULT  VO_Interact3(OBJECT* pObject, ACTION Act, BYTE* IStrm, BYTKTY Qty, BYTE* OStrm, BYTKTY Cty, BYTKTY* pQty, const VR* pCaller) 
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;

 assert( pObject != NULL );
 assert( (MSKAC & Act) == AC3 );
 assert( IStrm != NULL );
 assert( Qty > 0 );
 assert( OStrm != NULL );
 assert( Cty > 0 );
 assert( pQty != NULL );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );

 *pQty = 0;

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Interact3(pObject, Act, IStrm, Qty, OStrm, Cty, pQty, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

/**
*
* 名称:VO_Close
* 描述:接口Close的VO函数。
* 参数:pObject --- [IN] 指向对象;
*       pCaller --- [IN] 来访者。
*/      
IRESULT  VO_Close(OBJECT* pObject, const VR* pCaller)
{
 extern  FRESULT CallerCome(OBJECT* pND, const VR* pCaller);
 extern  FRESULT CallerLeave(OBJECT* pND, const VR* pCaller);

 IRESULT  ir = IR_O;
 
 assert( pObject != NULL );
 assert( pCaller->cr != 0 );
 assert( pCaller->mr != 0 );

 if( FR_P == CallerCome(pObject, pCaller) )
 {
  ir = pObject->Close(pObject, pCaller);
  CallerLeave(pObject, pCaller);
 }else { ir = IR_N; }
 
 return ir;
}

#endif