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

📄 dirindex.cpp

📁 mini http server,可以集成嵌入到程序中,实现简单的web功能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
<TD>SortDate
<TD>The sort order is determined by the file date.

<TR>
<TD>SortDscr
<TD>The sort order is determined by the annotations in the DescriptionFile.

<TR>
<TD>TagNew
<TD>All all files newer than NewThreshold are marked with NewPattern.

</TABLE>
</CENTER>
Multiple options may be listed together by seperating them using the pipe
('|') character. Whitespace will be stripped from the option pattern. Options
are matched without regard to case sensitivity. Unknown options will raise
a configuration error. The option directive may be repeated multiple times.

Phase:
	HANDLE

Returns:
	PIAPI_COMPLETED if a directory index was succesfully sent to the client.
	PIAPI_CONTINUE if this handler done nothing. PIAPI_ERROR and PIAPI_ABORT
	on generic and severe error conditions.

Note:
	A sorted HTML directory indes is made by using the above sort options and
	hyperlinks with special URL parameters within the table headers

	<XMP>
	...
	<TH><A HREF="%p?SortType=A">Type</A> \
	<TH><A HREF="%p?SortName=A">Name</A> \
	<TH><A HREF="%p?SortSize=A">Size</A> \
	<TH><A HREF="%p?SortDate=A">Last Modified</A> \
	<TH><A HREF="%p?SortDscr=A">Description</A> \
	...
	</XMP>

	The URL parameters are of the general form "SortType(Name,Size,Date,Dscr)=A(D)"
	for <B>A</B>scending or <B>D</B>escending sort order.

Example:
	<PRE>
	&lt;Object&gt;
		Name DirectoryIndex
		Class DirectoryIndexClass
		Options "Name | Size | MIMEType"
	&lt;/Object&gt;

	&lt;Object&gt;
		...
		Handle DirectoryIndex 
		...
	&lt;/Object&gt;
	</PRE>
/*___+++HTMLDOC_END+++___*/
#endif


/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Parse, store and add RFC822 headers to  response DB's.
\*____________________________________________________________________________*/
class RFC822Header
{
private:
	const char *pFKVariable;
	PIString sValue;
	int iOK;

public:
	RFC822Header( const char *pLine )
	:   pFKVariable( 0 ),
		iOK( 0 )
		{
		if ( !pLine )
			{ return; };
		int iLen = strlen( pLine );
		int i;
		for( i=0; i<iLen && pLine[i]!=':' && !(isspace(pLine[i])); i++);
		if ( !i || pLine[i]!=':' )
			{ return; };
		PIString sVariable( pLine, i );
		for( i++; i<iLen && (isspace(pLine[i])); i++);  /* scan past ws */
		pFKVariable = PIDB_getFastKey( sVariable, PIDBTYPE_RFC822 );
		sValue = &( pLine[i] );
		iOK = 1;
		};

	/* --- Replace this header in DB --- */
	void ReplaceHeader( PIDB *pDB )
		{
		assert( pDB );
		assert( pFKVariable );
		assert( iOK );
		PIDB_replace( pDB, PIDBTYPE_RFC822, pFKVariable,
			(void *)(const char *)sValue, PIDBFLAG_FASTKEY );
		};

	inline int IsOK()
		{ return iOK; };
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Maps a MIME type to an image path.
\*____________________________________________________________________________*/
class MIMEIcon
{
private:
	PIString sMIMEPattern;
	PIString sIconPath;

public:
	MIMEIcon( const char *pMIMEPattern, const char *pIconPath )
	:	sMIMEPattern( pMIMEPattern ), sIconPath( pIconPath )
		{};

	/*___
	____*/
	bool Matches( const PIString &sMIMEType )
		{
		return HTTPUtil_regexMatch(
				sMIMEPattern, sMIMEPattern.Len(),
				sMIMEType, sMIMEType.Len() ) ?
			true : false;
		};

	/*___
	____*/
	inline const PIString &GetPath()	{ return sIconPath; };
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class SwapFileName
{
public:
	PIString sFrom;
	PIString sTo;

	SwapFileName( const PIString &sTheFrom, const PIString &sTheTo )
		{
		DeQuote tFrom( sTheFrom );
		DeQuote tTo( sTheTo );
		sFrom = (const char *)tFrom;
		sTo = (const char *)tTo;
		};
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
\*____________________________________________________________________________*/
class DescriptionMap
{
public:
	PIString sFileName;
	PIString sDescription;

	DescriptionMap( const char *pLine )
		{
		assert( pLine );
		int iLen = strlen( pLine );
		int i=0;
		for( i=0; i<iLen && pLine[i]!='|'; i++ );
		PIString sTmp( pLine, i );
		sFileName = sTmp;
		if ( i<iLen ) { i++; };
		pLine= &( pLine[i] );
		sDescription = pLine;
		};
};

	/*___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ *
		
				WriteContext for parameters and 
			callback functions for writing the parameters

	 *___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ */
/* --- helper macro to facilitate writing --- */
inline int Internal_StrMinCpy( char *pS1, const char *pS2, int iL1, int iL2 )
{
	if ( !iL2 )
		{ return 0; };
	if ( iL1 )
		{
		assert( iL1>0 );
		assert( pS1 );
		assert( pS2 );
		strncpy( pS1, pS2, (iL1<iL2) ? iL1 : iL2 );
		return iL2;
		};
	return iL2;
};
inline void _myassert( void *pVoid )
	{ assert( pVoid ); };
#define FUNCTION(fn,record) \
static int (fn)( PIHTTP *, void *pData, char *pszBuffer, int iLength ) { \
	_myassert( pData );										\
	return Internal_StrMinCpy(								\
		pszBuffer,											\
		((WriteContext *)pData)->record.pField,				\
		iLength,											\
		((WriteContext *)pData)->record.iLength ); }
class WriteContext
{
public:
	WriteContext()
	{
	memset( this, 0, sizeof( WriteContext ) );
	};
	class Record {
	public:
		int iLength;
		const char *pField;
	};
	Record tAltName;
	Record tIsDirectory;
	Record tMedia;
	Record tDescription;
	Record tLastModifiedDate;
	Record tName;
	Record tIcon;
	Record tDirectory;
	Record tRelativePath;
	Record tSize;
	Record tTagNew;
	Record tDirSize;
	Record tDirCount;
};
FUNCTION( f_a, tAltName );
FUNCTION( f_b, tIsDirectory );
FUNCTION( f_c, tMedia );
FUNCTION( f_d, tDescription );
FUNCTION( f_i, tIcon );
FUNCTION( f_l, tLastModifiedDate );
FUNCTION( f_n, tName );
FUNCTION( f_p, tDirectory );
FUNCTION( f_r, tRelativePath );
FUNCTION( f_s, tSize );
FUNCTION( f_m, tTagNew );
FUNCTION( f_S, tDirSize );
FUNCTION( f_N, tDirCount );

	
/*____________________________________________________________________________*\
 *
 Description:
	Create a map of FnPi3Write functions for parameters to expressions
\*____________________________________________________________________________*/
static FnPi3Write aFunctions[256] =
{
/*
0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
*/
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	/* 0 .. 15 */
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	/* 16 .. 31 */
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	/* 32 .. 47 */
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	/* 48 .. 63 */
/*  A   B   C   D   E   F   G   H   I   J   K   L   M   N   O  */
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  f_N,0,/* 64 .. 79 */	
/*  Q   R   S   T   U   V   W   X   Y   Z                      */
0,  0,  0,  f_S,0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	/* 80 .. 95 */
/*  a   b   c   d   e   f   g   h   i   j   k   l   m   n   o  */
0,f_a,f_b,f_c,f_d,  0,  0,  0,  0,f_i,  0,  0,f_l,f_m,f_n,  0, 	/* 96 .. 111 */
/*  q   r   s   t   u   v   w   x   y   z   */
f_p,0,f_r,f_s,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  /* 112 .. 127 */	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 	
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 	/* .. 255 */	
};

/*____________________________________________________________________________*\
 *
 Function:
 Synopsis:
 Description:
\*____________________________________________________________________________*/
#define KEY_CONF_HEADERPATTERN		"HeaderPattern"
#define KEY_CONF_HEADERFILE			"HeaderFile"
#define KEY_CONF_LISTTOP			"ListTop"
#define KEY_CONF_FILEPATTERN		"FilePattern"
#define KEY_CONF_LISTBOTTOM			"ListBottom"
#define KEY_CONF_FOOTERFILE			"FooterFile"
#define KEY_CONF_FOOTERPATTERN		"FooterPattern"
#define KEY_CONF_LASTMODIFIEDFORMAT	"LastModifiedFormat"
#define KEY_CONF_INCLUDE			"Include"
#define KEY_CONF_EXCLUDE			"Exclude"
#define KEY_CONF_DESCRIPTIONFILE	"DescriptionFile"
#define KEY_CONF_MIMEICON			"MIMEIcon"
#define KEY_CONF_HTTPEQUIV			"HTTPEquiv"
#define KEY_CONF_SWAPFILENAME		"SwapFileName"
#define KEY_CONF_OPTIONS			"Options"
#define KEY_CONF_DESCRIPTIONFILE	"DescriptionFile"
#define KEY_CONF_NEWPATTERN			"NewPattern"
#define KEY_CONF_NEWTHRESHOLD		"NewTreshold"

/*____________________________________________________________________________*\
 *
 Flags and Options
\*____________________________________________________________________________*/
#define FLG_NONE		0x00000000
#define FLG_NAME		0x00000001
#define FLG_ALTNAME		0x00000002	
#define FLG_ICON		0x00000004
#define FLG_SIZE		0x00000008
#define FLG_MIMETYPE	0x00000010
#define FLG_RELPATH		0x00000020
#define FLG_MODDATE		0x00000040
#define FLG_ABBREVSIZE	0x00000080
#define FLG_FORMATSIZE	0x00000100
#define FLG_SORTCASE	0x00000200
#define FLG_SORTDESC	0x00000400
#define FLG_SORTTYPE	0x00000800
#define FLG_SORTNAME	0x00001000
#define FLG_SORTSIZE	0x00002000
#define FLG_SORTDATE	0x00004000
#define FLG_SORTDSCR	0x00008000
#define FLG_TAGNEW		0x00010000

	/*___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ *
		
				Map these flags to names

	 *___ +++++++++++++++++++++++++++++++++++++++++++++++++ ___ */
struct {
	const char *pName;
	int iFlag;
} aFlagMap[] =
	{
	{ "Name",					FLG_NAME },
	{ "AltName",				FLG_ALTNAME },
	{ "Icon",					FLG_ICON },
	{ "Size",					FLG_SIZE },
	{ "MIMEType",				FLG_MIMETYPE },
	{ "RelPath",				FLG_RELPATH },
	{ "AbbrevSize",				FLG_ABBREVSIZE },
	{ "FormatSize",				FLG_FORMATSIZE },
	{ "SortCase",				FLG_SORTCASE },
	{ "SortDesc",				FLG_SORTDESC },
	{ "SortType",				FLG_SORTTYPE },
	{ "SortName",				FLG_SORTNAME },
	{ "SortSize",				FLG_SORTSIZE },
	{ "SortDate",				FLG_SORTDATE },
	{ "SortDscr",				FLG_SORTDSCR },
	{ "TagNew",					FLG_TAGNEW },
	/* ---
	end of change
	--- */

	/* --- leave this last always --- */
	{ 0, 0 }
	};

#define KEY_SORT_TYPE	"SortType"
#define KEY_SORT_NAME	"SortName"
#define KEY_SORT_SIZE	"SortSize"
#define KEY_SORT_DATE	"SortDate"
#define KEY_SORT_DESC	"SortDscr"
#define SORT_KEY_LEN    8

#define SORT_NONE	0
#define SORT_TYPE	1
#define SORT_NAME	2
#define SORT_SIZE	3
#define SORT_DATE	4
#define SORT_DESC	5
#define MAX_FILESORT_ARRAY	2048
/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Helper function, compare two keys of type PIFInfo * by directory name.
	Trick: Result is emphasized by 2 --> 0 no directory | >0 compare test
\*____________________________________________________________________________*/

int cmpDirs( PIFInfo *arg1, PIFInfo *arg2 ) {
	if ( PIFInfo_isDirectory(arg1) ) {
		// the parent dir has always the lowest weight
		if ( !strcmp( PIFInfo_getName(arg1), "..\0" )) return 1;
		if ( PIFInfo_isDirectory(arg2) ) {
			// the parent dir has always the lowest weight
			// but here it's the 2nd compare parameter
			if ( !strcmp( PIFInfo_getName(arg2), "..\0" )) return 3;
			// both directories --> equal weight
			return 0;
		};
		// default case if only a1 is dir
		return 1;
	} else {
		// default case if only a2 is dir
		if ( PIFInfo_isDirectory(arg2) ) return 3;
		// both are files --> equal weight
		return 0;
	};
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Compare two keys of type PIFInfo * by name.
\*____________________________________________________________________________*/

int cmpName( PIFInfo *arg1, PIFInfo *arg2, PIDB *pDB, int bDescending, int bCaseSensitive ) {
	
	if (arg1 == arg2) return 0;

	// directories are always on top
	int result = cmpDirs( arg1, arg2 );
	if ( result ) {
		result -= 2;
	} else {
		// case sensitivity
		result = bCaseSensitive ?
			strcmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ))
		  : PIUtil_stricmp( PIFInfo_getName( arg1 ), PIFInfo_getName( arg2 ));
	}
	// sort order
	return bDescending ? -result : result;
};

/*____________________________________________________________________________*\
 *
 Class:
 Description:
	Compare two keys of type PIFInfo * by type.
\*____________________________________________________________________________*/

int cmpType( PIFInfo *arg1, PIFInfo *arg2, PIDB *pDB, int bDescending, int bCaseSensitive ) {
	
	// directories are always top level
	int result = cmpDirs( arg1, arg2 );
	if ( result ) {

⌨️ 快捷键说明

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