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

📄 _pi3expr.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		:	eType( STRING ), pString( pTheString )	{ assert( pString ); };

		FunctionArgument( int iTheNumber )
		:	eType( NUMBER ), iNumber( iTheNumber )	{};

		FunctionArgument( _Pi3Expression *pTheExpr )
		:	eType( EXPRESSION ), pExpr( pTheExpr )	{ assert( pExpr ); };

		~FunctionArgument()
			{
			switch( eType )
				{
				case STRING:
					PI_DELETE( pString ); break;
				case NUMBER:
					break;
				case EXPRESSION:
					PI_DELETE( pExpr ); break;
				default:
					assert( 0 );
				};
			};

		int Write( Context &tContext, char *pszBuffer, int iLength ) const
			{
			switch( eType )
				{
				case STRING: {
					int iValueLen = pString->Len();
					int iLen = iValueLen>iLength ? iLength : iValueLen;
					if ( iLen>0 && pszBuffer )
						{ strncpy( pszBuffer, *pString, iLen ); };
					return iValueLen;
					};

				case NUMBER: {
					enum { NUM_BUF=63 };
					char szBuf[NUM_BUF+1];
					sprintf( szBuf, "%d", iNumber );
					int iValueLen = strlen( szBuf );
					int iLen = iValueLen>iLength ? iLength : iValueLen;
					strncpy( pszBuffer, szBuf, iLen );
					return iValueLen;
					};
					
				case EXPRESSION:
					return Internal_ExpressionToString(
						tContext, pExpr, pszBuffer, iLength );

				default:
					assert( 0 );
				};
			assert( 0 );
			return -1;
			};

		void WriteDebugTree( int iIndent ) const
			{
			switch( eType )
				{
				case STRING:
					cerr << "STRING:<" << *pString << ">";
					break;

				case NUMBER:
					cerr << "NUMBER:<" << iNumber << ">" << endl;
					break;

				case EXPRESSION:
					cerr << endl;
					pExpr->WriteDebugTree( iIndent+1 );
					break;

				default:
					assert( 0 );
				};
			};
	};

	int iOK;	

	/* --- some useful methods --- */
	void ExpressionToNumber( Context &tContext,
			_Pi3Expression *pExpr, int &iResult ) const
		{
		enum { BUF_SIZE=63 };
		char szBuf[BUF_SIZE+1];
		szBuf[BUF_SIZE]='\0';

		register int iNumberLength =
			pExpr->Write( tContext, szBuf, BUF_SIZE );

		iResult = iNumberLength>0 ? atoi( szBuf ) : iNumberLength;
		};

	void FunctionArgumentToNumber( Context &tContext,
			FunctionArgument *pArg, int &iResult ) const
		{
		if ( pArg->eType==FunctionArgument::NUMBER )
			{
			iResult = pArg->iNumber;
			}
		else
			{
			enum { BUF_SIZE=63 };
			char szBuf[BUF_SIZE+1];
			*szBuf='\0';
			int iNumberLength = pArg->Write( tContext, szBuf, BUF_SIZE );
			assert( iNumberLength!=-1 );

			iResult = iNumberLength>0 ? atoi( szBuf ) : iNumberLength;
			};
		};

	int FunctionArgumentToString( Context &tContext,
		FunctionArgument *pArg, char *pszBuffer, int iLength ) const
		{
		return pArg->Write( tContext, pszBuffer, iLength );
		};

	FunctionArgument *ExpressionToFunctionArgument( _Pi3Expression *pExpr )
		{
		if ( !pExpr )
			{ return 0; };

		if ( !pExpr->IsStatic() )
			{ return PI_NEW( FunctionArgument( pExpr ) ); };

		/* --- dummy --- */
		PIHTTP tPIHTTP( (PIDB *)0 );
		Context tContext( 0, tPIHTTP, 0 );
		int iLen = pExpr->Write( tContext, 0, 0 );
		if ( iLen==-1 )
			{
			assert( 0 );
			PI_DELETE( pExpr );
			return 0; 
			};
		if ( !iLen )
			{
			PI_DELETE( pExpr );
			return PI_NEW( FunctionArgument( PI_NEW( PIString ) ) );
			}

		char *pBuffer = PI_NEW( char[iLen+1] );
		assert( pBuffer );
		iLen = pExpr->Write( tContext, pBuffer, iLen );

		/* --- done with expression --- */
		PI_DELETE( pExpr );

		FunctionArgument *pArg = PI_NEW( FunctionArgument( 
			PI_NEW( PIString( pBuffer, iLen ) ) ) );

		PI_DELETE( [] pBuffer );

		return pArg;
		};

public:
	FunctionComponent()
	:	iOK( 0 )
		{};

	virtual ~FunctionComponent()
		{};
	
	virtual int IsOK() const { return iOK; };

	/* --- pure virtual functions for derived classes --- */
	virtual const char *GetName() const=0;
	virtual int Min()=0;
	virtual int Max()=0;

	/* ---
	Optimize expression. Return 1 on success, 0 on error
	--- */
	virtual int Compile( DblList &lExpressions, PIString &sError )=0;

	/* --- public functions --- */
	static FunctionComponent *MakeFunctionComponent( PIString &sFunctionName,
		TokenSource &tSource, FnPi3Write *pFunctions,
		PIString &sError, int &iNestedMessage );
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class TruncFunctionComponent : public FunctionComponent
{
private:
	FunctionArgument *pString;
	FunctionArgument *pLength;

public:
	TruncFunctionComponent()
	:	FunctionComponent(),
		pString( 0 ),
		pLength( 0 )
		{};

	virtual ~TruncFunctionComponent()
		{
 		PI_DELETE( pString );		
		PI_DELETE( pLength );
		};

	virtual const char *GetName() const		{ return "trunc"; };

	/* --- */
	virtual void WriteDebugTree( int iIndent ) const
		{
		for(int i=0; i<iIndent; i++ )
			{ cerr << INDENT_PATTERN; };
		cerr << "Function:'" << GetName() << "'";
		if ( IsStatic() )
			{ cerr << "<Static>"; }
		else
			{ cerr << "<Dynamic>"; }
		if ( !pString )
			{ cerr << endl; return; };
		pString->WriteDebugTree( iIndent );
		assert( pLength );
		cerr << ", ";
		pLength->WriteDebugTree( iIndent );
		};

	/* --- */
	virtual int Write( Context &tContext, char *pszBuffer, int iLength ) const
		{
		if ( !pString )
			{ return 0; };	/* --- string is empty --- */

		assert( pLength );

		int iTruncLength;
		if ( pLength->eType==FunctionArgument::NUMBER )
			{ iTruncLength = pLength->iNumber; }
		else
			{
			assert( pLength->eType==FunctionArgument::EXPRESSION );

			ExpressionToNumber( tContext, pLength->pExpr, iTruncLength );
			};

		if ( iTruncLength<=0 )
			{
			if ( !iTruncLength )
				{ return 0; };
			/* else	iTruncLength==-1 */
			assert( 0 );
			const char pError[] = "_Pi3Expression::trunc(): invalid length";
			strncpy( pszBuffer, pError, iLength );
			return ((int)sizeof( pError ));
			};

		/* --- 
		Write String
		--- */
		if ( pString->eType==FunctionArgument::EXPRESSION )
			{
			int iRet = pString->pExpr->Write( tContext, pszBuffer,
				iTruncLength );
			if ( iRet==-1 )
				{
				assert( 0 );
				return -1;
				};
			if ( iRet<iTruncLength )
				{ return iRet; };
			return iTruncLength;
			}
		else
			{
			assert( pString->eType==FunctionArgument::STRING );

			PIString &sString = *( pString->pString );
			assert( sString.Len() );
			if ( sString.Len()<iTruncLength )
				{ iTruncLength = sString.Len(); };
			strncpy( pszBuffer, sString, iTruncLength );
			return iTruncLength;
			};
		};

	virtual int Min()	{ return 2; };
	virtual int Max()	{ return 2; };

	/* ---
	Optimize expression. Return 1 on success, 0 on error
	--- */
	virtual int Compile( DblList &lExpressions, PIString &sError )
		{
		DblListIterator i( lExpressions );
		if ( i.BadIndex() ) { return 0; };
		_Pi3Expression *pEString = (_Pi3Expression *)i.Current();
		i++;
		if ( i.BadIndex() ) { return 0; };
		_Pi3Expression *pELength = (_Pi3Expression *)i.Current();

		/* --- make dummy PIHTTP object --- */
		PIHTTP tPIHTTP( (PIDB *)0 );
		Context tContext( 0, tPIHTTP, 0 );

		/* --- clear the list --- */
		assert( lExpressions.Size()==Min() );
		assert( lExpressions.Size()==Max() );
		lExpressions.Clear();

		/* --- set string argument --- */
		if ( !pEString->IsStatic() )
			{
			pString = PI_NEW( FunctionArgument( pEString ) );
			}
		else
			{	
			int iLength = pEString->Write( tContext, 0, 0 );
			if ( iLength<0 )
				{
				assert( 0 );
				return -1;
				};
			if ( iLength==0 )
				{
				PI_DELETE( pEString );
				pEString = 0;
				}
			else
				{
				char *pBuffer = PI_NEW( char[iLength+1] );
				pEString->Write( tContext, pBuffer, 0 );
				pBuffer[iLength] = '\0';
				pString = PI_NEW( FunctionArgument(
					PI_NEW( PIString( pBuffer, iLength ) ) ) );
				PI_DELETE( [] pBuffer );
				};
			};

		/* --- set length argument, if string is non-empty --- */
		if ( pString )
			{
			if ( !pELength->IsStatic() )
				{
				pLength = PI_NEW( FunctionArgument( pELength ) );
				}
			else
				{
				/* --- preprocess expression to a number --- */
				int iNumber=-1;
				ExpressionToNumber( tContext, pELength, iNumber );
				PI_DELETE( pELength );
				if ( iNumber==-1 )
					{
					sError = "_Pi3Expression::trunc(): invalid length argument";
					return 0;
					};
				pLength = PI_NEW( FunctionArgument( iNumber ) );
				};
			};

		/* --- done --- */
		iOK = 1;
		return 1;
		};

	virtual int IsStatic() const
		{
		if ( !pString )
			{ return 1; };	/* --- static because its empty --- */

		assert( pLength );

		return pString->eType==FunctionArgument::STRING && 
			pLength->eType==FunctionArgument::NUMBER;
		};
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	This function should be re-written.
\*____________________________________________________________________________*/
class AlignFunctionComponent : public FunctionComponent
{
private:
	FunctionArgument *pString;
	FunctionArgument *pLength;
	FunctionArgument *pFlags;
	FunctionArgument *pPadding;

public:
	AlignFunctionComponent()
	:	FunctionComponent(),
		pString( 0 ),
		pLength( 0 ),
		pFlags( 0 ),
		pPadding( 0 )
		{};

	virtual ~AlignFunctionComponent()
		{
 		PI_DELETE( pString );		
		PI_DELETE( pLength );
		PI_DELETE( pFlags );
		PI_DELETE( pPadding );
		};

	virtual const char *GetName() const		{ return "align"; };

	/* --- */
	virtual void WriteDebugTree( int iIndent ) const
		{
		for(int i=0; i<iIndent; i++ )
			{ cerr << INDENT_PATTERN; };
		cerr << "Function:'" << GetName() << "'";
		if ( IsStatic() )
			{ cerr << "<Static>"; }
		else
			{ cerr << "<Dynamic>"; }
		assert( pString );
		pString->WriteDebugTree( iIndent );
		cerr << ", ";
		assert( pFlags );
		pFlags->WriteDebugTree( iIndent );
		cerr << ", ";
		assert( pPadding );
		pPadding->WriteDebugTree( iIndent );
		};

	/* --- */
	virtual int Write( Context &tContext, char *pszBuffer, int iLength ) const 
		{
		assert( pString );
		assert( pLength );
		assert( pFlags );
		assert( pPadding );
		assert( pszBuffer || !iLength );

		/* --- get field length --- */
		int iFieldLength;			/* the length of the field to write */
		FunctionArgumentToNumber( tContext, pLength, iFieldLength );

		/* --- give error if field length is wrong --- */
		if ( iFieldLength<=0 )
			{
			if ( !iFieldLength )
				{
				return 0;
				};
			/* else	iFieldLength==-1 */
			const char pError[] = "_Pi3Expression::align(): invalid length";
			if ( iLength>0 )
				{ strncpy( pszBuffer, pError, iLength ); };
			return ((int)sizeof( pError ));
			};

		enum { BUF_SIZE=127 };

		/* --- get padding --- */
		char szPaddingBuf[BUF_SIZE+1];
		int iPaddingLen = pPadding->Write( tContext, szPaddingBuf,
			BUF_SIZE );
		if ( iPaddingLen==-1 )
			{ return -1; };
		if ( iPaddingLen>BUF_SIZE )
			{ iPaddingLen=BUF_SIZE; };
		PIString sPadding;
		if ( iPaddingLen>0 )
			{
			szPaddingBuf[iPaddingLen]='\0';
			sPadding = szPaddingBuf;
			}
		else
			{
			sPadding = "                    ";
			iPaddingLen = sPadding.Len();
			};

		/* --- get flags --- */
		char szFlagsBuf[BUF_SIZE+1];
		int iFlagsLen = pFlags->Write( tContext, szFlagsBuf, BUF_SIZE );
		if ( iFlagsLen==-1 )
			{ return -1; };
		if ( iFlagsLen>BUF_SIZE )
			{ iFlagsLen = BUF_SIZE; };
		char *pszFlagsBuf = szFlagsBuf;
		/* --- eat leading whitespace --- */
		while( iFlagsLen>0 && (isspace(*pszFlagsBuf)) )
			{
			iFlagsLen--;
			pszFlagsBuf++;
			};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -