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

📄 _pi3expr.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				strncpy( pszBuffer, pMessage, iLen );
				iLength -= iLen;
				pszBuffer = &(pszBuffer[iLen]);
				};
			};
		PIDBIterator_delete( pIter );
		};

	return iTotalLen;
}

static int sc_g( Context &tContext, char *pszBuffer, int iLength ) 
{ 
	int iOn = (int)PIDB_lookup( tContext.tPIHTTP.pConnectionDB, PIDBTYPE_STRING,
		KEY_HTTPS_KEYSIZE, 0 );
	const char *pString;
	int iValueLen;
	if ( iOn )
		{
		pString = "on";
		iValueLen = 2;
		}
	else
		{
		pString = "off";
		iValueLen = 3;
		};
	int iLen = iValueLen < iLength ? iValueLen : iLength;
	if ( iLen>0 )
		{
		assert( pszBuffer ); 
		strncpy( pszBuffer, pString, iLen ); 
		};
	return iValueLen; 
}

static int sc_t( Context &tContext, char *pszBuffer, int iLength ) 
{ 
	(void)tContext; 
	enum { BUF_SIZE=255 }; 
	char szBuf[BUF_SIZE+1]; 
	
	PIPlatform_beforeUnsafeBlock();
	time_t tT;
	time( &tT );
#if 0
	struct tm *pTms = gmtime( &tT );
	int iValueLen = strftime( szBuf, BUF_SIZE, "%d/%b/%Y:%H:%M:%S +0000", pTms );
#endif
	struct tm *pTms = gmtime( &tT );
	/*
	** Bit of wierd logic here, but were taking into account timezone
	** adjustment on new years eve. Hence use of year. The year multiplier
	** doesn't matter once its greater than 365 (its only used for
	** comparision between gmt and localtime, and they are both multiplyied
	** by the same number
	*/
	int iGmtYearDay = ( pTms->tm_year * 366 ) + pTms->tm_yday;
	int iGmtHourMin = ( pTms->tm_hour * 60 ) + pTms->tm_min ;
	pTms = localtime( &tT );
	int iValueLen = strftime( szBuf, BUF_SIZE, "%d/%b/%Y:%H:%M:%S", pTms );
	int iYearDay = ( pTms->tm_year * 366 ) + pTms->tm_yday;
	int iHourMin = ( pTms->tm_hour * 60 ) + pTms->tm_min ;
	PIPlatform_afterUnsafeBlock();

	int iAdjust = ( iHourMin - iGmtHourMin ) ;
	if ( iGmtYearDay>iYearDay )
		{ iAdjust -= ( 24 * 60 ) ; };
	char cSign;
	if ( iAdjust > 0 )
		{
		cSign = '+';
		}
	else
		{
		cSign = '-';
		iAdjust = -iAdjust;
		};
	sprintf( &(szBuf[20]), " %c%02d%02d", cSign, iAdjust / 60, iAdjust % 60 );
	iValueLen += 6;
	
	int iLen = iValueLen < iLength ? iValueLen : iLength;	
	if ( iLen>0 ) 
		{ 
		assert( pszBuffer ); 
		strncpy( pszBuffer, szBuf, iLen ); 
		}; 
	return iValueLen; 
}

static int sc_T( Context &tContext, char *pszBuffer, int iLength ) 
{ 
	(void)tContext; 
	enum { BUF_SIZE=63 }; 
	char szBuf[BUF_SIZE+1]; 

	long lSeconds;	
	long lMicroSeconds;	
	PITimer_elapsed( tContext.tPIHTTP.pTimer, &lSeconds, &lMicroSeconds );
	sprintf( szBuf, "%ld.%06ld", (long)lSeconds, (long)lMicroSeconds );
	int iValueLen = strlen( szBuf );
	int iLen = iValueLen < iLength ? iValueLen : iLength;
	if ( iLen>0 )
		{
		assert( pszBuffer ); 
		strncpy( pszBuffer, szBuf, iLen ); 
		};
	return iValueLen; 
}

#undef S
#undef F
#undef C
#undef Q
#undef R

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
void Internal_InitShortcuts()
{
	aFunctions['a'] = sc_a;	/* administrator */
	aFunctions['A'] = sc_A;	/* IP address of remote client */
	aFunctions['b'] = sc_b;	/* bytes sent */
	aFunctions['c'] = sc_c;	/* content-type */
	aFunctions['C'] = sc_C;	/* content-type - incoming */
	aFunctions['d'] = sc_d;	/* debugging flag */
	aFunctions['D'] = sc_D;	/* handler time delta */
	aFunctions['e'] = sc_e;	/* SSL cipher name */
	aFunctions['E'] = sc_E;	/* error messages */
	aFunctions['f'] = sc_f;	/* filename */
	aFunctions['g'] = sc_g;	/* Using SSL?, g='Guarded'?, */
	aFunctions['G'] = sc_G;	/* SSL secret key size (g='Geheimnis') */
	aFunctions['h'] = sc_h;	/* remote host */
	aFunctions['H'] = sc_H;	/* request HTTP protocol */
	aFunctions['i'] = sc_i;	/* remote ident */
	aFunctions['I'] = sc_I;	/* path info section */
	aFunctions['k'] = sc_k;	/* thread id */
	aFunctions['K'] = sc_K;	/* SSL keysize */
	aFunctions['l'] = sc_l;	/* local address */
	aFunctions['m'] = sc_m;	/* request method from client */
	aFunctions['M'] = sc_M;	/* end of line sequence */
	aFunctions['n'] = sc_n;	/* name of current handler object */
	aFunctions['N'] = sc_N;	/* name of current handler phase */
	aFunctions['o'] = sc_o;	/* object name of virtual host */
	aFunctions['p'] = sc_p;	/* server port */
	aFunctions['P'] = sc_P;	/* process id */	
	aFunctions['q'] = sc_q;	/* query string from client */
	aFunctions['r'] = sc_r;	/* request line */
	aFunctions['R'] = sc_R;	/* name of result code from last handler */
	aFunctions['s'] = sc_s;	/* status */
	aFunctions['S'] = sc_S;	/* server stamp */
	aFunctions['t'] = sc_t;	/* time in CLF */
	aFunctions['T'] = sc_T;	/* time taken to service request */
	aFunctions['u'] = sc_u;	/* remote user */
	aFunctions['U'] = sc_U;	/* URL requested */
	aFunctions['v'] = sc_v;	/* server name */
	aFunctions['x'] = sc_x;	/* authentication type */
	aFunctions['X'] = sc_X;	/* depth of request in subrequest hierarchy */
	aFunctions['y'] = sc_y;	/* content-length : outgoing */
	aFunctions['Y'] = sc_Y;	/* content-length : incoming */
	aFunctions['z'] = sc_z;	/* script name */
	aFunctions['Z'] = sc_Z;	/* path translated */

	iShortcutsInitialized = 1;
}
	
/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class ShortcutComponent : public ComponentBase
{
private:
	SCFnWrite fnWrite;

public:
	ShortcutComponent( char c )
	:	fnWrite( 0 )
		{
		if ( !iShortcutsInitialized )
			{
	  		Internal_InitShortcuts();
			};
		fnWrite = aFunctions[c];
		};
	
	virtual void WriteDebugTree( int iIndent ) const
		{
		for(int i=0; i<iIndent; i++ )
			{ cerr << INDENT_PATTERN; };
		cerr << "Shortcut:" << endl;
		};

	virtual int Write( Context &tContext, char *pszBuffer, int iLength ) const
		{
		if ( !fnWrite ) 
			{ return 0; };
		return (fnWrite)( tContext, pszBuffer, iLength );
		};

	virtual int IsOK() const { return fnWrite!=0; };
	virtual int IsStatic() const	{ return 0; /* some sc's only */ };
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Token class. Encapsulates a token in the input stream.
\*____________________________________________________________________________*/
class Token
{
public:
	enum Type {
		DOLLAR=1,
		PERCENT,
		OPEN_PAREN,
		CLOSE_PAREN,
		COMMA,
		AMPERSAND,
		NUMBER,
		IDENTIFIER,
		LITERAL,
		OTHER
		};
	Type eType;
	PIString sStr;
	char cChar;
	long lVal;

	/* --- constructors --- */
	Token( const Token &tT )
		: eType( tT.eType ), sStr( tT.sStr ),
		cChar( tT.cChar ), lVal( tT.lVal )
		{};
	Token( Type eTheType, char c ) : eType( eTheType ), cChar( c ), lVal( 0 )
		{};
	Token( char c ) : eType( OTHER ), cChar( c ), lVal( 0 )
		{};
	Token( Type eTheType, const PIString &sTheString )
		: eType( eTheType ), sStr( sTheString ), cChar( '\0' ), lVal( 0 )
		{ 
		const char *pS = sStr;
		cChar = pS ? *pS : '\0';
		};

	/* --- descriptions --- */
	void GetDescription( PIString &sDescription )
		{
		switch( eType )
			{
			case DOLLAR: 
			case PERCENT: 
			case OPEN_PAREN: 
			case CLOSE_PAREN: 
			case COMMA: 
			case AMPERSAND: 
			case OTHER: 
				{
				char szX[] = "X";
				*szX = cChar;
				sDescription = szX;
				break;
				};

			case NUMBER:		sDescription = "Number"; break;
			case IDENTIFIER:	sDescription = "Identifier"; break;
			default:
				assert( 0 ); sDescription = "Unknown";
			};
		};
};

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
class TokenSource
{
private:
	PIString sExpression;
	int iPos;
	Token *pPushedBack;		
	
public:
	TokenSource( const char *pTheExpression )
	:	sExpression( pTheExpression ),
		iPos( 0 ),
		pPushedBack( 0 )
		{
		};

	~TokenSource()
		{
		PI_DELETE( pPushedBack );
		};

	inline const PIString &GetRawString()	{ return sExpression; };
	inline int GetPosition()				{ return iPos; };

private:
	void Internal_PushBack()
		{ assert( iPos>0 ); iPos--; };

	Token *Internal_GetNextToken( PIString &sError )
		{
		enum {
			NORMAL=1,
			ESCAPED,
			QUOTED,
			COMMENT_START,
			IN_COMMENT,
			COMMENT_END,
			IDENTIFIER
			} eState = NORMAL;

		/* --- persistent variables --- */
		PIString sBuffer;

		/* --- lexical state machine --- */
		for(;;)
			{
			if ( sExpression.Len()==iPos )
				{
				switch( eState )
					{
					case NORMAL:	return 0;
					case COMMENT_START:	return PI_NEW( Token( '/' ) );
					case ESCAPED:	return PI_NEW( Token( '\\' ) );
					case IDENTIFIER:
						return PI_NEW(Token( Token::IDENTIFIER, sBuffer ));
					case QUOTED:
						sError = "End of expression reading quoted literal.";
						return 0;
					case IN_COMMENT:
					case COMMENT_END:
						sError = "End of expression in reading comment.";
						return 0;
					default: assert( 0 ); return 0;
					};
				};
			const char *pTmp = sExpression;
			char c = pTmp[iPos++];

			switch( eState )
				{
				case NORMAL:
					if ( c=='\\' )
						{ eState = ESCAPED; break; }
					else if ( (isalpha(c)) || (c=='_') )
						{
						char szX[] = "X";
						*szX = c;
						sBuffer = szX;
						eState = IDENTIFIER;
						break;
						};
					switch( c )
						{
						case '\\': eState = ESCAPED; break;
						case '\'': eState = QUOTED; break;
						case '/': eState = COMMENT_START; break;
						case '%': return PI_NEW( Token(Token::PERCENT, '%'));
						case '$': return PI_NEW( Token(Token::DOLLAR, '$') );
						case '(': return PI_NEW( Token(Token::OPEN_PAREN,'(') );
						case ')': return PI_NEW( Token(Token::CLOSE_PAREN,')'));
						case ',': return PI_NEW( Token(Token::COMMA,',') );
						case '&': return PI_NEW( Token(Token::AMPERSAND,'&') );
						default:;
							return PI_NEW( Token( c ) );
						};
					break;

				case COMMENT_START:
					if ( c=='*' )
						{ eState = IN_COMMENT; break; };
					Internal_PushBack();	
					return PI_NEW( Token( '/' ) );

				case IN_COMMENT:
					if ( c=='*' )
						{ eState = COMMENT_END; break; };
					break;

				case COMMENT_END:
					if ( c=='/' )
						{ eState = NORMAL; break; };
					eState = IN_COMMENT;
					break;

				case IDENTIFIER:
					if ( !(isalnum(c) || (c=='_')) )
						{
						eState = NORMAL;
						Internal_PushBack();
						return PI_NEW(Token( Token::IDENTIFIER, sBuffer ));
						};
					sBuffer.Concatenate( c );
					break;

				case ESCAPED:
					eState = NORMAL;
					switch( c )
						{
						case '\\': c = '\\'; break;
						case 'a': c = '\a'; break;
						case 'b': c = '\b'; break;
						case 'f': c = '\f'; break;
						case 'n': c = '\n'; break;
						case 'r': c = '\r'; break;
						case 't': c = '\t'; break;
						case 'v': c = '\v'; break;
						default:;
						};
					return PI_NEW( Token( c ) );

				case QUOTED:
					if ( c=='\'' )
						{
						eState = NORMAL;
						return PI_NEW(Token( Token::LITERAL, sBuffer ));
						};
					sBuffer.Concatenate( c );
					break;

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

		/* --- should never get here --- */
		assert( 0 );
		return 0;
		};

public:
	inline Token *GetNextToken( PIString &sError )
		{ 
		if ( pPushedBack )
			{
			Token *pTmp = pPushedBack;
			pPushedBack = 0;
			return pTmp;
			};
		return Internal_GetNextToken( sError );
		};

	inline void PushBack( Token *pToPushBack )
		{
		assert( !pPushedBack );
		pPushedBack = pToPushBack;
		};
};

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
int Internal_ExpressionToString( Context &tContext,
	_Pi3Expression *pExpr, char *pszBuffer, int iLength )
{
	return pExpr->Write( tContext, pszBuffer, iLength );
}

/*____________________________________________________________________________*\
 *
 Class:
 Description:
		- make this more efficient by having functions be objects.
\*____________________________________________________________________________*/
class FunctionComponent : public ComponentBase
{
protected:
	/* ---
	encapsulation of a function arguments
	--- */
	class FunctionArgument
	{
	public:
		enum { STRING=0, NUMBER, EXPRESSION } eType;
		union {	
			PIString *pString;
			int iNumber;
			_Pi3Expression *pExpr;
			};

		FunctionArgument( PIString *pTheString )

⌨️ 快捷键说明

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