西城

指尖代码,手上年华

联系 聚合 管理
  20 Posts :: 0 Stories :: 62 Comments :: 0 Trackbacks
#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类中。其实现的细节暂时可不必探究。

获取输入那块上篇已讲过,此处略去。
posted on 2012-03-26 22:24 西城 阅读(1267) 评论(1)  编辑 收藏 引用 所属分类: Cgicc

Feedback

# re: cgicc解析(2)——头以及标签 2012-03-27 09:41 tb
很好啊   回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理