www.pudn.com > simplec++codeforp2p.rar > html.cpp


// ------------------------------------------------
// File : html.cpp
// Date: 4-apr-2002
// Author: giles
// Desc: 
//		HTML protocol handling
//
// (c) 2002 peercast.org
// ------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// ------------------------------------------------


#include 
#include  
#include "html.h"
#include "http.h"
#include "stream.h"
#include "gnutella.h"
#include "servmgr.h"
#include "channel.h"
#include "stats.h" 
#include "version2.h" 


// --------------------------------------
HTML::HTML(const char *t, Stream &o)
{
	out = &o;
	out->writeCRLF = false;

	title.set(t);
	tagLevel = 0;
	refresh = 0;
}

// --------------------------------------
void HTML::writeOK(const char *content)
{
	out->writeLine(HTTP_SC_OK);
	out->writeLineF("%s %s",HTTP_HS_SERVER,PCX_AGENT);
	//out->writeLine("%s %s",HTTP_HS_CACHE,"no-cache");
	out->writeLineF("%s %s",HTTP_HS_CONNECTION,"close");
    out->writeLineF("%s %s",HTTP_HS_CONTENT,content); 
	out->writeLine("");
}
// --------------------------------------
void HTML::writeVariable(Stream &s,const String &varName, int loop)
{
	bool r=false;
	if (varName.startsWith("servMgr."))
		r=servMgr->writeVariable(s,varName+8);
	else if (varName.startsWith("chanMgr."))
		r=chanMgr->writeVariable(s,varName+8,loop);
	else if (varName.startsWith("stats."))
		r=stats.writeVariable(s,varName+6); 
	else if (varName.startsWith("sys.")) 
	{ 
		if (varName == "sys.log.dumpHTML") 
		{ 
			sys->logBuf->dumpHTML(s); 
			r=true; 
		} 
	} 
	else if (varName.startsWith("loop.")) 
	{ 
		if (varName.startsWith("loop.channel.")) 
		{ 
			Channel *ch = chanMgr->findChannelByIndex(loop); 
			if (ch) 
				r = ch->writeVariable(s,varName+13,loop); 
		}else if (varName.startsWith("loop.servent.")) 
		{ 
			Servent *sv = servMgr->findServentByIndex(loop); 
			if (sv) 
				r = sv->writeVariable(s,varName+13); 
		}else if (varName.startsWith("loop.filter.")) 
		{ 
			ServFilter *sf = &servMgr->filters[loop]; 
			r = sf->writeVariable(s,varName+12); 
 
		}else if (varName.startsWith("loop.bcid.")) 
		{ 
			BCID *bcid = servMgr->findValidBCID(loop); 
			if (bcid) 
				r = bcid->writeVariable(s,varName+10); 
		 
		}else if (varName == "loop.indexEven") 
		{ 
			s.writeStringF("%d",(loop&1)==0); 
			r = true; 
		}else if (varName == "loop.index") 
		{ 
			s.writeStringF("%d",loop); 
			r = true; 
		}else if (varName.startsWith("loop.hit.")) 
		{ 
			char *idstr = getCGIarg(tmplArgs,"id="); 
			if (idstr) 
			{ 
				GnuID id; 
				id.fromStr(idstr); 
				ChanHitList *chl = chanMgr->findHitListByID(id); 
				if (chl) 
				{ 
					int cnt=0; 
					ChanHit *ch = chl->hit; 
					while (ch) 
					{ 
						if (ch->host.ip && !ch->dead) 
						{ 
							if (cnt == loop) 
							{ 
								r = ch->writeVariable(s,varName+9); 
								break; 
							} 
							cnt++; 
						} 
						ch=ch->next; 
					} 
 
				} 
			} 
		} 
 
	} 
	else if (varName.startsWith("page.")) 
	{ 
		if (varName.startsWith("page.channel.")) 
		{ 
			char *idstr = getCGIarg(tmplArgs,"id="); 
			if (idstr) 
			{ 
				GnuID id; 
				id.fromStr(idstr); 
				Channel *ch = chanMgr->findChannelByID(id); 
				if (ch) 
					r = ch->writeVariable(s,varName+13,loop); 
			} 
		}else 
		{ 
 
			String v = varName+5; 
			v.append('='); 
			char *a = getCGIarg(tmplArgs,v); 
			if (a) 
			{ 
				s.writeString(a);		 
				r=true; 
			} 
		} 
	} 


	if (!r)
		s.writeString(varName);
}
// -------------------------------------- 
int HTML::getIntVariable(const String &varName,int loop) 
{ 
	String val; 
	MemoryStream mem(val.cstr(),String::MAX_LEN); 
 
	writeVariable(mem,varName,loop); 
 
	return atoi(val.cstr()); 
} 
// -------------------------------------- 
bool HTML::getBoolVariable(const String &varName,int loop) 
{ 
	String val; 
	MemoryStream mem(val.cstr(),String::MAX_LEN); 
 
	writeVariable(mem,varName,loop); 
 
	// integer 
	if ((val[0] >= '0') && (val[0] <= '9')) 
		return atoi(val.cstr()) != 0;	 
 
	// string 
	if (val[0]!=0) 
		return true;	 
 
	return false; 
} 
 
// -------------------------------------- 
void	HTML::readIf(Stream &in,Stream *outp,int loop) 
{ 
	String var; 
	bool varCond=true; 
 
	while (!in.eof()) 
	{ 
		char c = in.readChar(); 
 
		if (c == '}') 
		{ 
			if (getBoolVariable(var,loop)==varCond) 
			{ 
				if (readTemplate(in,outp,loop)) 
					readTemplate(in,NULL,loop); 
			}else{ 
				if (readTemplate(in,NULL,loop)) 
					readTemplate(in,outp,loop); 
			} 
			return; 
		}else if (c == '!') 
		{ 
			varCond = !varCond; 
		}else 
		{ 
			var.append(c); 
		} 
	} 
 
} 
 
// -------------------------------------- 
void	HTML::readLoop(Stream &in,Stream *outp,int loop) 
{ 
	String var; 
	while (!in.eof()) 
	{ 
		char c = in.readChar(); 
 
		if (c == '}') 
		{ 
			int cnt = getIntVariable(var,loop); 
 
			if (cnt) 
			{ 
				int spos = in.getPosition(); 
				for(int i=0; iwriteChar(c); 
		} 
	} 
	return false; 
} 
 
// --------------------------------------
void HTML::writeTemplate(const char *fileName, const char *args)
{ 
	FileStream file;
	try
	{
		file.openReadOnly(fileName);
 
		tmplArgs = args; 
		readTemplate(file,out,0); 

	}catch(StreamException &e)
	{
		out->writeString(e.msg);
		out->writeString(" : ");
		out->writeString(fileName); 
	}

	file.close();
}
// -------------------------------------- 
void HTML::writeRawFile(const char *fileName) 
{ 
	FileStream file; 
	try 
	{ 
		file.openReadOnly(fileName); 
 
		file.writeTo(*out,file.length()); 
 
	}catch(StreamException &) 
	{ 
	} 
 
	file.close(); 
} 

// --------------------------------------
void HTML::locateTo(const char *url)
{
	out->writeLine(HTTP_SC_FOUND);
	out->writeLineF("Location: %s",url);
	out->writeLine("");
}
// --------------------------------------
void HTML::startHTML()
{
	startNode("html");
}
// --------------------------------------
void HTML::startBody()
{
	startNode("body");
}
// --------------------------------------
void HTML::addHead()
{
	char buf[512];
		startNode("head");
			startTagEnd("title",title.cstr());
			startTagEnd("meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"");

			if (!refreshURL.isEmpty())
			{
				sprintf(buf,"meta http-equiv=\"refresh\" content=\"%d;URL=%s\"",refresh,refreshURL.cstr());
				startTagEnd(buf);
			}else if (refresh)
			{
				sprintf(buf,"meta http-equiv=\"refresh\" content=\"%d\"",refresh);
				startTagEnd(buf);
			}


		end();
}
// --------------------------------------
void HTML::addContent(const char *s)
{
	out->writeString(s);
}
// --------------------------------------
void HTML::startNode(const char *tag, const char *data)
{
	const char *p = tag;
	char *o = &currTag[tagLevel][0];

	int i;
	for(i=0; iwriteString("<");
	out->writeString(tag);
	out->writeString(">");
	if (data)
		out->writeString(data);

	tagLevel++;
	if (tagLevel >= MAX_TAGLEVEL)
		throw StreamException("HTML too deep!");
}
// --------------------------------------
void HTML::end()
{
	tagLevel--;
	if (tagLevel < 0)
		throw StreamException("HTML premature end!");

	out->writeString("writeString(&currTag[tagLevel][0]);
	out->writeString(">");
}
// --------------------------------------
void HTML::addLink(const char *url, const char *text, bool toblank)
{
	char buf[1024];

	sprintf(buf,"a href=\"%s\" %s",url,toblank?"target=\"_blank\"":"");
	startNode(buf,text);
	end();
}
// --------------------------------------
void HTML::startTag(const char *tag, const char *fmt,...)
{
	if (fmt)
	{

		va_list ap;
  		va_start(ap, fmt);

		char tmp[512];
		vsprintf(tmp,fmt,ap);
		startNode(tag,tmp);

	   	va_end(ap);	
	}else{
		startNode(tag,NULL);
	}
}
// --------------------------------------
void HTML::startTagEnd(const char *tag, const char *fmt,...)
{
	if (fmt)
	{

		va_list ap;
  		va_start(ap, fmt);

		char tmp[512];
		vsprintf(tmp,fmt,ap);
		startNode(tag,tmp);

	   	va_end(ap);	
	}else{
		startNode(tag,NULL);
	}
	end();
}
// --------------------------------------
void HTML::startSingleTagEnd(const char *fmt,...)
{
	va_list ap;
	va_start(ap, fmt);

	char tmp[512];
	vsprintf(tmp,fmt,ap);
	startNode(tmp);

	va_end(ap);	
	end();
}

// --------------------------------------
void HTML::startTableRow(int i)
{
	if (i & 1)
		startTag("tr bgcolor=\"#dddddd\" align=\"left\"");
	else
		startTag("tr bgcolor=\"#eeeeee\" align=\"left\"");
}