#include <iostream>
#include <vector>
#include <string>
#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"
using namespace std;
using namespace cgicc;
int
main(int argc,
char **argv)
{
try {
Cgicc cgi;
// Send HTTP header
cout << HTTPHTMLHeader() << endl;
// Set up the HTML document
cout << html() << head(title("cgicc example")) << endl;
cout << body() << endl;
// Print out the submitted element
form_iterator name = cgi.getElement("name");
if(name != cgi.getElements().end()) {
cout << "Your name: " << **name << endl;
}
// Close the HTML document
cout << body() << html();
}
catch(exception& e) {
// handle any errors - omitted for brevity
}
}
这是官方教程中的一个例子,我想从这个例子的分析中弄明白cigcc库工作的一些基本原理。这个例子中包括了对接收
数据的处理以及对浏览器的输出。
首先输出http header。HTTPHTMLHeader是一个类,它的继承体系是MStreamable->HTTPHeader->
HTTPContentHeader->(HTTPHTMLHeader,HTTPPlainHeader,HTTPXHTMLHeader).从名字上可以看出,因为继承自MStreamable,HTTPHTMLHeader应该是重载了cout操作符。
MStreamable中的提供了一个纯虚函数:
virtual void
render(STDNS ostream& out) const = 0;
还有一个右元函数:
friend CGICC_API STDNS ostream&
operator<<(STDNS ostream& out, const MStreamable& obj);
这就是其中实现重载的函数。其实现就是调用obj.reader(out);基类想要实现相应的功能,只需实现reader函数即可.HTTPHeader是一个抽象基类,不需要实现此函数。HTTPContentHeader实现了这个函数。
CGICCNS HTTPContentHeader::render(STDNS ostream& out) const
{
out << "Content-Type: " << getData() << STDNS endl;
STDNS vector<HTTPCookie>::const_iterator iter;
for(iter = getCookies().begin(); iter != getCookies().end(); ++iter)
out << *iter << STDNS endl;
out << STDNS endl;
}
HTTPContentHeader创建时,将“text/html"传给HTTPContentHeader的构造函数即可,HTTPContentHeader会继续将此参数往上传至HTTPHeader,然后通过getData调用取出。
CIGCC中将每一个标签都定义为一个类。比如以下几个
BOOLEAN_ELEMENT (html, "html"); // HTML document
BOOLEAN_ELEMENT (head, "head"); // document head
BOOLEAN_ELEMENT (title, "title"); // document title
ATOMIC_ELEMENT (meta, "meta"); // meta data
BOOLEAN_ELEMENT (style, "style"); // style sheet
BOOLEAN_ELEMENT (body, "body"); // document body
BOOLEAN_ELEMENT是一个宏
#define BOOLEAN_ELEMENT(name, tag) \
TAG(name, tag); typedef HTMLBooleanElement<name##Tag> name
TAG也是一个宏
#define TAG(name, tag) \
class name##Tag \
{ public: inline static const char* getName() { return tag; } }
这个宏展开就是一个类。
以“html"为例,其相应的类为
class htmlTag
{
public:
inline static const char* getName()
{return "html";}
};
而后面的typedef则导致
html=
HTMLBooleanElement<htmlTag>.
HTMLBooleanElement是一个模板类,用相应的标签实例化后,
html()=HTMLBooleanElemnt<htmlTag>()-------->构造函数。而HTMLBooleanElement
的继承体系则是MStreamable-->HTMLElement-->HTMLBooleanELemnt<Tag>,依然是可输出的。
这一次reader的函数实现是在HTMLELement类中。其实现的细节暂时可不必探究。
获取输入那块上篇已讲过,此处略去。