📄 stubio.cpp
字号:
return 0;
}
else
{
lHTTPEquivalents.Append( (DblList::type)pHeader );
};
}
else if ( !PIUtil_stricmp( pVar, KEY_CONF_ACCEPTINTERVAL ) )
{
iAcceptInterval = atoi( pVal );
}
else if ( !PIUtil_stricmp( pVar, KEY_CONF_SENDINTERVAL ) )
{
iSendInterval = atoi( pVal );
}
else
{
os << "Unknown parameter '" << pVar << "'." << ends;
CONFIG_ERR( pObject, os.str() );
return 0;
};
/* --- OK --- */
return 1;
};
static int ParameterFn( void *pData, const char *pVar, const char *pVal,
const char *pWhere )
{
assert( pData );
return ((StubIO *)pData)->Parameter( pVar, pVal, pWhere );
};
/* --- forbid copy constructor --- */
StubIO( const StubIO & )
{ assert( 0 ); };
public:
StubIO( PIObject *pTheObject, int iArgc, const char *ppArgv[] )
:
pObject( pTheObject ),
pIOObject( 0 ),
iAcceptInterval( DEFAULT_INTERVAL ),
iSendInterval( DEFAULT_INTERVAL ),
lRecords(),
lHTTPEquivalents(),
iErrorAfter( -1 ),
pIORecord( 0 ),
iNextRecord( 0 ),
iPos( 0 ),
bOK( 0 ),
pSaveDB( 0 )
{
/* --- constructor --- */
if ( !PIObject_readParameters( pObject, iArgc, ppArgv,
StubIO::ParameterFn, this ) )
{ return; };
if ( !lRecords.Size() )
{
CONFIG_ERR( pObject, "StubIO: no definition for \
'DataFile'.");
return;
};
bOK = ( lRecords.Size()>0 );
return;
};
/* --- */
StubIO( PIObject *pTheObject, StubIO *pPrototype, int, const char *[] )
:
pObject( pTheObject ),
pIOObject( pPrototype ),
iAcceptInterval( DEFAULT_INTERVAL ),
iSendInterval( DEFAULT_INTERVAL ),
lRecords(),
lHTTPEquivalents(),
iErrorAfter( -1 ),
pIORecord( 0 ),
iNextRecord( 0 ),
iPos( 0 ),
bOK( 0 ),
pSaveDB( 0 )
{
assert( pIOObject );
if ( !pIOObject ) { return; };
/* ---
Make new child IO DB
--- */
pSaveDB = PIObject_getDB( pObject );
PIDB *pDB = PIDB_new( 0, "DB" );
PIObject_setDB( pObject, pDB );
/* ---
Check error after number
--- */
if ( pIOObject->iErrorAfter != -1 )
{
assert( (pIOObject->iErrorAfter)>=0 );
if ( !pIOObject->iErrorAfter )
{ return; }; /* --- Cause an error --- */
(pIOObject->iErrorAfter)--;
};
/* ---
Add the headers
--- */
for( DblListIterator i( pIOObject->lHTTPEquivalents );
!i.BadIndex(); i++ )
{
((RFC822Header *)i.Current())->ReplaceHeader( pDB,
PIDBTYPE_STRING );
};
iSendInterval = pIOObject->iSendInterval;
iAcceptInterval = pIOObject->iAcceptInterval;
assert( iNextRecord<pIOObject->lRecords.Size() );
iNextRecord=pIOObject->iNextRecord++;
pIORecord = (IOResponseRecord *)pIOObject->lRecords[iNextRecord];
if ( pIOObject->iNextRecord>=pIOObject->lRecords.Size() )
{ pIOObject->iNextRecord = 0; };
bOK=1;
/* ---
Wait the accept timeout interval
--- */
if ( iAcceptInterval>0 )
{ PIPlatform_sleep( iAcceptInterval*1000 ); };
};
~StubIO()
{
if ( !pIOObject )
{
/* --- prototype object --- */
for( DblListIterator i( lRecords ); !i.BadIndex(); i++ )
{ PI_DELETE( (IOResponseRecord *)i.Current() ); };
for( DblListIterator j( lHTTPEquivalents ); !j.BadIndex(); j++ )
{ PI_DELETE( (RFC822Header *)j.Current() ); };
lRecords.Clear();
}
else if ( pSaveDB )
{
/* --- not prototype object --- */
PIDB_delete( PIObject_getDB( pObject ) );
PIObject_setDB( pObject, pSaveDB );
};
};
/* --- */
inline int Out( void *, int iLen, int *piSent, int, const char *[] )
{
if ( !IsOK() ) { return PIAPI_ERROR; };
*piSent = iLen;
/* --
Using a random way of decreasing *piSent would simulate
outgoing TCP fragmentation
--- */
if ( iSendInterval>0 )
{ PIPlatform_sleep( iSendInterval*1000 ); };
PIThread_userYield();
return PIAPI_COMPLETED;
};
/* --- */
inline int In( void *pData, int iLen, int *piReceived, int,
const char *[] )
{
assert( pIORecord );
if ( !IsOK() ) { return PIAPI_ERROR; };
int iSend = pIORecord->iDataSize - iPos;
/* ---
NOTE: using a random way to decrease iSend at this
point would simulate fragmentation
--- */
if ( iLen < iSend ) { iSend = iLen; };
if ( iSend )
{
memcpy( pData, &( pIORecord->pInData[iPos] ), iSend );
};
*piReceived = iSend;
iPos+=iSend;
PIThread_userYield();
return PIAPI_COMPLETED;
};
inline int IsOK() { return bOK; };
};
/*____________________________________________________________________________*\
*
Function: StubIO_onClassLoad
Synopsis:
Description:
This is called on program startup, restart or shutdown.
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StubIO_onClassLoad( PIClass_LoadAction eAction, void * )
{
switch( eAction )
{
case STARTUP:
break;
case SHUTDOWN:
break;
default:;
};
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: StubIO_StubIO
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StubIO_StubIO( PIObject *pObj, int iArgc,
const char *ppArgv[] )
{
StubIO *pStubIO = PI_NEW( StubIO( pObj, iArgc, ppArgv ) );
if (!( pStubIO && pStubIO->IsOK() ))
{
PI_DELETE( pStubIO );
return PIAPI_ERROR;
};
PIObject_setUserData( pObj, pStubIO );
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: StubIO_copyStubIO
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StubIO_copyStubIO( PIObject *pObj, int iArgc,
const char *ppArgv[] )
{
StubIO *pPrototype = (StubIO *)PIObject_getUserData( pObj );
StubIO *pStubIO = PI_NEW( StubIO( pObj, pPrototype, iArgc, ppArgv ) );
if (!( pStubIO && pStubIO->IsOK() ))
{
PIObject_setUserData( pObj, 0 );
PI_DELETE( pStubIO );
return PIAPI_ABORT;
};
PIObject_setUserData( pObj, pStubIO );
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: StubIO_xStubIO
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StubIO_xStubIO( PIObject *pObj, int,
const char *[] )
{
assert( pObj );
StubIO *pStubIO = (StubIO *)PIObject_getUserData( pObj );
if ( pStubIO ) { PI_DELETE( pStubIO ); };
return PIAPI_COMPLETED;
}
/*____________________________________________________________________________*\
*
Function: StubIO_out
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StubIO_out( PIObject *pObj, void *pData, int iLen,
int *piSent, int iArgc, const char *ppArgv[] )
{
assert( pObj && PIObject_getUserData( pObj ) );
return ((StubIO *)PIObject_getUserData( pObj ) )->Out( pData, iLen,
piSent, iArgc, ppArgv );
}
/*____________________________________________________________________________*\
*
Function: StubIO_in
Synopsis:
Description:
\*____________________________________________________________________________*/
PUBLIC_PIAPI int StubIO_in( PIObject *pObj, void *pData, int iLen,
int *piReceived, int iArgc, const char *ppArgv[] )
{
assert( pObj && PIObject_getUserData( pObj ) );
return ((StubIO *)PIObject_getUserData( pObj ) )->In( pData, iLen,
piReceived, iArgc, ppArgv );
}
/* ---
Class configuration specification
--- */
#if 0
/*___+++CNF_BEGIN+++___*/
<Class>
Name StubIOClass
Type IO
Library IO
OnClassLoad StubIO_onClassLoad
Constructor StubIO_StubIO
CopyConstructor StubIO_copyStubIO
Destructor StubIO_xStubIO
Out StubIO_out
In StubIO_in
</Class>
<Object>
Name StubIO
Class StubIOClass
AcceptInterval 0
SendInterval 0
</Object>
/*___+++CNF_END+++___*/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -