⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stubio.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                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 + -