#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
}
}
這是官方教程中的一個(gè)例子,我想從這個(gè)例子的分析中弄明白cigcc庫工作的一些基本原理。這個(gè)例子中包括了對(duì)接收
數(shù)據(jù)的處理以及對(duì)瀏覽器的輸出。
首先輸出http header。HTTPHTMLHeader是一個(gè)類,它的繼承體系是MStreamable->HTTPHeader->
HTTPContentHeader->(HTTPHTMLHeader,HTTPPlainHeader,HTTPXHTMLHeader).從名字上可以看出,因?yàn)槔^承自MStreamable,HTTPHTMLHeader應(yīng)該是重載了cout操作符。
MStreamable中的提供了一個(gè)純虛函數(shù):
virtual void
render(STDNS ostream& out) const = 0;
還有一個(gè)右元函數(shù):
friend CGICC_API STDNS ostream&
operator<<(STDNS ostream& out, const MStreamable& obj);
這就是其中實(shí)現(xiàn)重載的函數(shù)。其實(shí)現(xiàn)就是調(diào)用obj.reader(out);基類想要實(shí)現(xiàn)相應(yīng)的功能,只需實(shí)現(xiàn)reader函數(shù)即可.HTTPHeader是一個(gè)抽象基類,不需要實(shí)現(xiàn)此函數(shù)。HTTPContentHeader實(shí)現(xiàn)了這個(gè)函數(shù)。
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創(chuàng)建時(shí),將“text/html"傳給HTTPContentHeader的構(gòu)造函數(shù)即可,HTTPContentHeader會(huì)繼續(xù)將此參數(shù)往上傳至HTTPHeader,然后通過getData調(diào)用取出。
CIGCC中將每一個(gè)標(biāo)簽都定義為一個(gè)類。比如以下幾個(gè)
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是一個(gè)宏
#define BOOLEAN_ELEMENT(name, tag) \
TAG(name, tag); typedef HTMLBooleanElement<name##Tag> name
TAG也是一個(gè)宏
#define TAG(name, tag) \
class name##Tag \
{ public: inline static const char* getName() { return tag; } }
這個(gè)宏展開就是一個(gè)類。
以“html"為例,其相應(yīng)的類為
class htmlTag
{
public:
inline static const char* getName()
{return "html";}
};
而后面的typedef則導(dǎo)致
html=
HTMLBooleanElement<htmlTag>.
HTMLBooleanElement是一個(gè)模板類,用相應(yīng)的標(biāo)簽實(shí)例化后,
html()=HTMLBooleanElemnt<htmlTag>()-------->構(gòu)造函數(shù)。而HTMLBooleanElement
的繼承體系則是MStreamable-->HTMLElement-->HTMLBooleanELemnt<Tag>,依然是可輸出的。
這一次reader的函數(shù)實(shí)現(xiàn)是在HTMLELement類中。其實(shí)現(xiàn)的細(xì)節(jié)暫時(shí)可不必探究。
獲取輸入那塊上篇已講過,此處略去。