cgicc解析(2)——头以及标签

cgicc解析(2)——头以及标签
#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&  outconst 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类中。其实现的细节暂时可不必探究。

获取输入那块上篇已讲过,此处略去。

你可能感兴趣的:(cgicc解析(2)——头以及标签)