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

📄 _pi3expr.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
Respectively case sensitive and insensitive comparision of two text
patterns.

<H5>
	dblookup(dbname,type,variable[,flags][,fnvalue][,first][,last])
</H5>
<STRONG>NOTE:</STRONG>This function is not currently supported to the full
specification as described here.
Iterate over a number of elements of a specific type in a particular database.
<CENTER>
Function arguments:-
<TABLE BORDER=1>
<TH>Argument position
<TH>Description
<TH>Default, (+)=Mandatory
<TH>Values

<TR>
<TD>1
<TD>name of database
<TD>+
<TD>program|connection|host|request|response

<TR>
<TD>2
<TD>type of element
<TD>+
<TD>rfc822|string|opaque

<TR>
<TD>3
<TD>variable name
<TD>+
<TD>a variable name (or empty for all)

<TR>
<TD>4
<TD>db flags affecting lookup
<TD>0
<TD>pidbflag_propagateup|pidbflag_fastkey|0

<TR>
<TD>5
<TD>callback argument
<TD>&amp;_()
<TD>Expression invoked for value of every db entry 

<TR>
<TD>6
<TD>start index
<TD>0
<TD>Number

<TR>
<TD>7
<TD>end index
<TD>0
<TD>Number

</TABLE>
</CENTER>


<H5>
	dbreplace(dbname,type,variable,value[,flags])
</H5>
Replace the value of a variable of the specific type in a particular
database. The function arguments are the same as described above.

<H5>
	if(boolean,true_text,false_text)
</H5>
If boolean is true (i.e., boolean is any character sequence with length
greater than zero), then this function evaluates to true_text, otherwise this
function evaluates to false_text.

<H5>
	not(boolean)
</H5>
If boolean is true (i.e., boolean is any character sequence with length
greater than zero), then this function returns a zero length text string
(false), otherwise a non-zero length text string (true) is returned.
The net result is the negation of the boolean argument.

<H5>
	regexp(regexp,text)
</H5>
Determine if the regular expression 'regex' matches the text 'text'. 
Returns 'true' (non-empty text) on success, 'false' (empty text) on
failure.
Regular expression matching is done using the function HTTPUtil_regexMatch(),
reference that function to see which regular expression constructs which
are supported.

<H5>
	trunc(text,number)
</H5>
Truncate text to the the decimal value of number.

/*___+++HTMLDOC_END+++___*/
#endif

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Component context, largely used for nested functions.
\*____________________________________________________________________________*/
class Context
{
public:
	PIHTTP &tPIHTTP;
	enum { CONTEXT_SIZE=10 };
	Context *pParent;
	void *pData;
	const char *aString[CONTEXT_SIZE];
	int aLength[CONTEXT_SIZE];

	Context(
			Context *pTheParent,
			PIHTTP &tThePIHTTP,
			void *pTheData )
	:	tPIHTTP( tThePIHTTP ),
		pParent( pTheParent ),
		pData( pTheData )
		{
		memset( aString, 0, sizeof( const char * ) * CONTEXT_SIZE );
		memset( aLength, 0, sizeof( int ) * CONTEXT_SIZE );
		};

	/* --- traverse up list of contexts --- */
	inline Context *GetContext( int iOffset )
		{
		assert( iOffset>=0 );
		if ( !pParent )
			{ return 0; };
		if ( iOffset==0 )
			{ return this; };
		return  pParent->GetContext( iOffset-1 );
		};
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class StringComponent : public ComponentBase
{
private:
	PIString sString;

public:
	/* --- string with length iLen --- */
	StringComponent( const char *pString, int iLen )
	:	sString( pString, iLen )
		{};

	/* --- null terminated string --- */
	StringComponent( const char *pString )	
	:	sString( pString )
		{};

	virtual void WriteDebugTree( int iIndent ) const
		{
		for(int i=0; i<iIndent; i++ )
			{ cerr << INDENT_PATTERN; };
		cerr << "String:'" << sString << "'" << endl;
		};

	virtual int Write( Context &, char *pszBuffer, int iLength ) const
		{
		if ( iLength>0 )
			{
			assert( pszBuffer );
			strncpy( pszBuffer, sString, iLength );
			};
		return sString.Len();
		};

	virtual int IsOK() const		{ return 1; };
	virtual int IsStatic() const	{ return 1; };
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class ExpressionComponent : public ComponentBase
{
private:
	DblList lComponents;
	int iOK;
	int iStatic;

	/* --- internal methods --- */
	int Compile( Context &tContext, DblList &lRawComponents,
		PIString & /* sError */ )
		{
		/* ---
		optimize the expression by merging static components 
		together
		--- */

		/* --- make a really big buffer --- */
		enum { BUF_SIZE=32767 };
		char *pszBuffer = PI_NEW( char[BUF_SIZE+1] );	/* too big for auto */
		assert( pszBuffer );
	
		/* --- iterate over components merging where possible --- */
		int iLength = 0;	/* --- length of buffer with static data --- */
		iStatic = 1;		/* --- mark this static till we know otherwise ---*/
		for( ; lRawComponents.Size() ; )
			{
			ComponentBase *pComp = (ComponentBase *)lRawComponents.Cap();
			assert( pComp );
			if ( pComp->IsStatic() )
				{
				/* --- static --- */
				int iWritten = pComp->Write( tContext, &(pszBuffer[iLength]),
					BUF_SIZE-iLength );
				assert( iWritten!=-1 );
				if ( iWritten==-1 )
					{
					PI_DELETE( pComp );
					PI_DELETE( [] pszBuffer );
					return 0;
					};
				if ( (iLength+iWritten)<=BUF_SIZE )
					{
					/* --- component is written into buffer, start next one --*/
					PI_DELETE( pComp );
					iLength+=iWritten;
					continue;
					};
				/* --- else don't merge this component --- */
				};
				
			/* --- flush the buffer --- */
			if ( iLength )
				{
				/* --- previous components have been written --- */
				lComponents.Append( (DblList::type)PI_NEW(
					StringComponent( pszBuffer, iLength ) ) );
				iLength = 0;
				};
			iStatic = 0;
			lComponents.Append( (DblList::type)pComp );
			};

		if ( iLength )
			{
			/* --- previous components have been written --- */
			lComponents.Append( (DblList::type)PI_NEW(
				StringComponent( pszBuffer, iLength ) ) );
			iLength = 0;
			};
	
		PI_DELETE( [] pszBuffer );
		return 1;
		};

	/* --- forbid copy constructor --- */
	ExpressionComponent( const ExpressionComponent & )
		{ assert( 0 ); };

public:
	ExpressionComponent( Context &tContext, DblList &lRawComponents,
		PIString &sError )
	:	iOK( 0 ),
		iStatic( 0 )
		{
		if ( Compile( tContext, lRawComponents, sError ) )
			{ iOK = 1; };
		};

	~ExpressionComponent()
		{
		for( DblListIterator i( lComponents ); !i.BadIndex(); i++ )
			{
			ComponentBase *pComp = (ComponentBase *)i.Current();
			PI_DELETE( pComp );
			};
		};

	virtual void WriteDebugTree( int /* iIndent */ ) const
		{
#if 0
		for(int i=0; i<iIndent; i++ )
			{ cerr << INDENT_PATTERN; };
		cerr << "String:'" << sString << "'" << endl;
#endif
		};

	virtual int Write( Context &tContext, char *pszBuffer, int iMaxLen ) const
		{
		int iWrittenSoFar = 0;
		int iLengthSoFar = 0;
		for( ConstDblListIterator i( lComponents ); !i.BadIndex(); i++ )
			{
			ComponentBase *pComp = (ComponentBase *)i.Current();
			assert( pComp );
			int iWritten = pComp->Write( tContext,
					&( pszBuffer[iWrittenSoFar] ), iMaxLen-iWrittenSoFar );

			if ( iWritten==-1 )
				{
				assert( 0 );
				return -1;
				};

			/* else */
			iLengthSoFar += iWritten;

			if ( iLengthSoFar>iMaxLen )
				{
				iWritten = iMaxLen - iWrittenSoFar;
				};

			iWrittenSoFar += iWritten;
			assert( iWrittenSoFar<=iMaxLen );
			};

		return iLengthSoFar;
		};

	virtual int IsOK() const
		{
		return iOK;
		};
	virtual int IsStatic() const	
		{
		return iStatic;
		};
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class ParameterComponent : public ComponentBase
{
private:
	FnPi3Write tFunction;

public:
	ParameterComponent( FnPi3Write tTheFunction )	
	:	tFunction( tTheFunction )
		{
		if ( !tTheFunction )
			{ return; };
		}

	virtual void WriteDebugTree( int iIndent ) const 
		{
		for(int i=0; i<iIndent; i++ )
			{ cerr << INDENT_PATTERN; };
		cerr << "Parameter:" << endl;
		};

	virtual int Write( Context &tContext, char *pszBuffer, int iLength ) const
		{
		assert( tFunction );
		return (tFunction)(&(tContext.tPIHTTP), tContext.pData, pszBuffer,
			iLength );
		};

	virtual int IsOK() const { return tFunction!=0; };
	virtual int IsStatic()	const { return 0; /* some params only */ };
};

/*____________________________________________________________________________*\
 *
 Description:
\*____________________________________________________________________________*/
typedef int (* SCFnWrite)( Context &, char *, int );
int iShortcutsInitialized = 0;
static SCFnWrite aFunctions[256];

/* --- macros to simplify shortcut functions --- */
#define O PIDBTYPE_OPAQUE
#define S PIDBTYPE_STRING
#define F PIDBTYPE_RFC822
#define C(x,y) PIDB_lookup( tContext.tPIHTTP.GetConnectionDB(), x, y, 0 )
#define Q(x,y) PIDB_lookup( tContext.tPIHTTP.GetRequestDB(), x, y, 0 )
#define R(x,y) PIDB_lookup( tContext.tPIHTTP.GetResponseDB(), x, y, 0 )
#define V(x,y) PIDB_lookup( tContext.tPIHTTP.GetHostDB(), x, y, 0 )
#define SC_STR_FUNCTION(fn, value)\
static int (fn)( Context &tContext, char *pszBuffer, int iLength ) \
{ \
	(void)tContext; \
	const char *pString = (const char *)(value); \
	if ( !pString )	{ return 0; }; \
	int iValueLen = strlen( pString ); \
	int iLen = iValueLen < iLength ? iValueLen : iLength;	\
	if ( iLen>0 ) \
		{ \
		assert( pszBuffer ); \
		strncpy( pszBuffer, pString, iLen ); \
		}; \
	return iValueLen; \
}
#	define SC_NUM_FUNCTION(fn, value, flags)\
static int (fn)( Context &tContext, char *pszBuffer, int iLength ) \
{ \
	(void)tContext; \
	enum { BUF_SIZE=63 }; \
	char szBuf[BUF_SIZE+1]; \
	*szBuf = '\0'; \
	sprintf( szBuf, flags, (value) ); \
	int iValueLen = strlen( szBuf ); \
	int iLen = iValueLen < iLength ? iValueLen : iLength;	\
	if ( iLen>0 ) \
		{ \
		assert( pszBuffer ); \
		strncpy( pszBuffer, szBuf, iLen ); \
		}; \
	return iValueLen; \
}

SC_STR_FUNCTION( sc_a, V( F, "Administrator") );
SC_STR_FUNCTION( sc_A, C( S, KEY_INT_REMOTEADDR ) );
SC_NUM_FUNCTION( sc_b, tContext.tPIHTTP.GetIOBuffer().GetBytesSent(), "%d" );
SC_STR_FUNCTION( sc_c, R( F, KEY_HTTP_CONTENTTYPE ) );
SC_STR_FUNCTION( sc_C, Q( F, KEY_HTTP_CONTENTTYPE ) );
SC_STR_FUNCTION( sc_d, HTTPCore_debugEnabled() ? "true" : "" );
SC_NUM_FUNCTION( sc_D, tContext.tPIHTTP.iDelta, "%d" );
SC_STR_FUNCTION( sc_e, C( S, KEY_HTTPS_CIPHERNAME ) );
SC_STR_FUNCTION( sc_f, R( S, KEY_INT_PATH ) );
SC_STR_FUNCTION( sc_G, C( S, KEY_HTTPS_SECRETKEYSIZE ) );
SC_STR_FUNCTION( sc_h, C( S, KEY_INT_REMOTEHOST ) );
SC_STR_FUNCTION( sc_H, Q( S, KEY_HTTP_PROTOCOL ) );
SC_STR_FUNCTION( sc_i, C( S, KEY_INT_REMOTEIDENT ) );
SC_STR_FUNCTION( sc_I, R( S, KEY_INT_PATHINFO ) );
SC_NUM_FUNCTION( sc_k, (long)PIThread_getSystemHandle( PIThread_getCurrent() ),
		"%ld");
SC_STR_FUNCTION( sc_K, C( S, KEY_HTTPS_KEYSIZE ) );
SC_STR_FUNCTION( sc_m, Q( S, KEY_HTTP_METHOD ) );
#if POSIX
SC_STR_FUNCTION( sc_M, "\n" );
#else
SC_STR_FUNCTION( sc_M, "\r\n" );
#endif
SC_STR_FUNCTION( sc_n, tContext.tPIHTTP.pHandlerName );
SC_STR_FUNCTION( sc_N, HTTPUtil_phaseNumberToName(
		tContext.tPIHTTP.ciPhase ) );
SC_STR_FUNCTION( sc_l, C( S, KEY_INT_LOCALADDR ) );
SC_STR_FUNCTION( sc_o, V( F, KEY_INT_OBJECTNAME ) );
SC_STR_FUNCTION( sc_p, HTTPUtil_getHostPort(&(tContext.tPIHTTP)) );
SC_NUM_FUNCTION( sc_P, PIPlatform_getProcessId(), "%d" );
SC_STR_FUNCTION( sc_q, Q( S, KEY_HTTP_QUERYSTRING ) );
SC_STR_FUNCTION( sc_r, Q( S, KEY_HTTP_CLF ) );
SC_STR_FUNCTION( sc_R, HTTPUtil_rcNumberToName(
		tContext.tPIHTTP.iLastResultCode ) );
SC_NUM_FUNCTION( sc_s, tContext.tPIHTTP.iStatus, "%d" );
SC_STR_FUNCTION( sc_S, HTTPCore_getServerStamp() );
SC_STR_FUNCTION( sc_u, R( S, KEY_INT_REMOTEUSER ) );
SC_STR_FUNCTION( sc_U, Q( S, KEY_HTTP_URI ) );
SC_STR_FUNCTION( sc_v, HTTPUtil_getHostName(&(tContext.tPIHTTP)) );
SC_STR_FUNCTION( sc_x, R( S, KEY_INT_AUTHTYPE ) );
SC_NUM_FUNCTION( sc_X, tContext.tPIHTTP.iDepth, "%d" );
SC_STR_FUNCTION( sc_y, R( F, KEY_HTTP_CONTENTLENGTH ) );
SC_STR_FUNCTION( sc_Y, Q( F, KEY_HTTP_CONTENTLENGTH ) );
SC_STR_FUNCTION( sc_z, R( S, KEY_INT_SCRIPTNAME ) );
SC_STR_FUNCTION( sc_Z, R( S, KEY_INT_PATHTRANSLATED ) );

/* ---
	Functions which don't conform to the standard template
--- */
static int sc_E( Context &tContext, char *pszBuffer, int iLength ) 
{ 
	/* ---
	Print out all error messages	
	--- */
	int iTotalLen = 0;
	PIDBIterator *pIter = PIDB_getIterator( tContext.tPIHTTP.pResponseDB,
		PIDBTYPE_STRING, KEY_INT_ERRORMESSAGE, 0 );
	if ( pIter )
		{
		for( ;
			PIDBIterator_atValidElement( pIter );
			PIDBIterator_next( pIter ) )
			{
			const char *pDummy;
			const char *pMessage = (const char *)PIDBIterator_current( 
				pIter, &pDummy );
			int iLen = strlen( pMessage );	
			iTotalLen += iLen;
			if ( iLen>iLength ) 
				{ iLen = iLength; };
			if ( iLen )
				{
				assert( pszBuffer );

⌨️ 快捷键说明

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