中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
html template
作者:未知 时间:2005-07-27 23:31 出处:CSDN 责编:chinaitpower
              摘要:html template
花了一天时间,模仿 php btemplate做了一个 c++版本,还不是很完善,请大家试用
 
不过在制作的过程中,发现效率有些问题,可能会导致用户感不足,在下一个版本中会做一些调整吧
/* Copyright (C) 2005 Hunter(whywhathow at hotmail.com)
   The LRU Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.
 */
 /*!
 * \file        mytemplate.h
 * \brief       模板引擎
 * \author      HunterLiu
 * \date        2005-7-10
*/
#ifndef TEMPLATE_H
#define TEMPLATE_H
#include "boost/shared_ptr.hpp"
#include <string>
#include <map>
//#include <execinfo.h>
#include <cassert>
#include <cstdlib>
#include <cstdio>
class CTemplateException : public std::exception
{
public:
 const char *what() {return m_sErrMsg;};
 CTemplateException(const char *psErrMsg, const char *sFunc = 0, int iLineNumber = -1)
 {
  assert(psErrMsg);
  m_sErrMsg[0] = 0;
  if (sFunc && iLineNumber > -1)
  {
   //a.out: test_assert.cpp:5: void test(): Assertion `0 > 1' failed.
   snprintf(m_sErrMsg, sizeof(m_sErrMsg), "line %3d: %s: %s", iLineNumber, sFunc, psErrMsg);
  }
  else
  {
   snprintf(m_sErrMsg, sizeof(m_sErrMsg), "%s", psErrMsg);
  }
 };
 virtual ~CTemplateException() throw ()  {};
protected:
 char m_sErrMsg[512];
};
class CDuplicateException: public CTemplateException
{
public:
 CDuplicateException(const char *psErrMsg, const char *sFunc, int iLineNumber):CTemplateException(psErrMsg, sFunc, iLineNumber)
    {};
};
class CFileException: public CTemplateException
{
public:
 CFileException(const char *psErrMsg, const char *sFunc, int iLineNumber):CTemplateException(psErrMsg, sFunc, iLineNumber)
    {};
};

class CTemplateArray
{
public:
 CTemplateArray();
 void       addElement(const std::string &strName, const std::string &strValue);
 u_int32_t  getElementCount();
 const std::map<std::string, std::string> &getElementArray();
private:
 std::map<std::string, std::string> m_cElementArray;
};
class CTemplate
{
public:
 CTemplate();
 //! gobal variable
 void setVar(const std::string &strName, const std::string &strValue);
 //! loop  variable
 void setLoopVar(const std::string &strLoopName, const std::string &strValue);
 //! 由CTemplate托管该内存块
 void setLoopVar(const std::string &strLoopName, boost::shared_ptr<CTemplateArray> &cArray);
 void loadTemplateFile(const std::string &strFileName, bool bOutputDirect, bool bStore);
 void loadTemplateStr(const std::string &strTemplate, bool bOutputDirect, bool bStore);
 std::string getOutput();
private:
 bool isDuplicate(const std::string &strName);
 void loadIncludeFile(std::string &sTemplateContent, std::string::size_type iIncBegin,
        std::string::size_type iIncEnd);
 void replaceVariable(std::string &sContent, const std::string &sToken, const std::string &sValue,
         std::string::size_type iBeginPos, std::string::size_type iEndPos);
 std::map<std::string, std::string> m_cGobalVariable;
 std::map<std::string, std::string> m_cLoopVariable;
 std::map<std::string, boost::shared_ptr<CTemplateArray> > m_cLoopArray;
 std::string m_sTemplateContent;
  
 char m_sFilePath[255];
 char m_sFileName[255];
};
#endif
/* Copyright (C) 2005 Hunter(whywhathow at hotmail.com)
   The LRU Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.
 */
#include "mytemplate.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

using namespace std;
using namespace boost;
CTemplateArray::CTemplateArray():m_cElementArray()
{
}
void CTemplateArray::addElement(const std::string &strName, const std::string &strValue)
{
 //map<std::string, std::string>::iterator end =
 if (m_cElementArray.find(strName) != m_cElementArray.end())
  throw CDuplicateException("duplicate element ", __func__, __LINE__);
 m_cElementArray[strName] = strValue;
 
}
u_int32_t  CTemplateArray::getElementCount()
{
 return m_cElementArray.size();
}
const std::map<std::string, std::string> &CTemplateArray::getElementArray()
{
 return m_cElementArray;
}
CTemplate::CTemplate():m_cGobalVariable(), m_cLoopVariable(), m_cLoopArray(),m_sTemplateContent()
{
}
bool CTemplate::isDuplicate(const std::string &strName)
{
 if (m_cGobalVariable.find(strName) != m_cGobalVariable.end())
  return true;
 if (m_cLoopVariable.find(strName) != m_cLoopVariable.end())
  return true;
 if (m_cLoopArray.find(strName) != m_cLoopArray.end())
  return true;
 return false;
}
void CTemplate::setVar(const std::string &strName, const std::string &strValue)
{
 if (isDuplicate(strName))
  throw CDuplicateException("duplicate element ", __func__, __LINE__);
 m_cGobalVariable[strName] = strValue;
}
//! loop  variable
void CTemplate::setLoopVar(const std::string &strLoopName, const std::string &strValue)
{
 if (isDuplicate(strLoopName))
  throw CDuplicateException("duplicate element ", __func__, __LINE__);
 m_cLoopVariable[strLoopName] = strValue;
}
//! 由CTemplate托管该内存块
void CTemplate::setLoopVar(const std::string &strLoopName, shared_ptr<CTemplateArray> &cArray)
{
 if (isDuplicate(strLoopName))
  throw CDuplicateException("duplicate element ", __func__, __LINE__);
 m_cLoopArray[strLoopName] = cArray;
}
class CFileManager
{
 ifstream &m_ifs;
public:
 CFileManager(ifstream &ifs):m_ifs(ifs)
 {};
 ~CFileManager()
 { m_ifs.close(); };
};
int GetFileSize(const std::string &strFileName)
{
 struct stat stFileStat;
 
 if (stat(strFileName.c_str(),&stFileStat)==0)
  return stFileStat.st_size;
 return -1;
}
void OpenFile(const std::string &strFileName, string &sFileContent)
{
 int iFileSize = GetFileSize(strFileName);
 //cout << strFileName << endl;
 if (iFileSize < 0)
  throw CFileException("file not found", __func__, __LINE__);
 if (iFileSize > 102400 - 512)
  throw CFileException("template too large", __func__, __LINE__);
 
 ifstream cFile(strFileName.c_str(), ios::in);
 if (cFile.fail())
  throw CFileException("file not found2", __func__, __LINE__);
 CFileManager cFileManager(cFile);
 char sTempBuffer[iFileSize+10];
 cFile.read(sTempBuffer, iFileSize);
 if (cFile.fail())
  throw CFileException("read fail", __func__, __LINE__);
 sFileContent.assign(sTempBuffer, iFileSize);
}
void CTemplate::loadTemplateFile(const std::string &strFileName, bool bOutputDirect, bool bStore)
{
 if (strFileName.length() > 250)
  throw CTemplateException("file path too long ", __func__, __LINE__);
 if (strFileName[0] != '/')
  throw CTemplateException("file path must lead by '/'", __func__, __LINE__);
#ifndef __CYGWIN__ 
 snprintf(m_sFilePath, sizeof(m_sFilePath), "%s", strFileName.c_str());
 snprintf(m_sFileName, sizeof(m_sFileName), "%s", strFileName.c_str());
 dirname(m_sFilePath);
 basename(m_sFileName);
#else
 char sTmpFile[255];
 snprintf(sTmpFile, sizeof(sTmpFile), "%s", strFileName.c_str());
 
 // have memory leak? I don't know if there is memory malloc in the new dirname()
 snprintf(m_sFilePath, sizeof(m_sFilePath), "%s", dirname(sTmpFile));
 snprintf(m_sFileName, sizeof(m_sFileName), "%s", basename(sTmpFile));
#endif
 OpenFile(strFileName, m_sTemplateContent);
 if (strFileName.find(".shtml") != string::npos)
 {
  string::size_type iFirstIncBegin, iFirstIncEnd;
  iFirstIncBegin = m_sTemplateContent.find("<!--#include");
  if(iFirstIncBegin == string::npos) return;
  iFirstIncEnd   = m_sTemplateContent.find("-->",iFirstIncBegin);
  if(iFirstIncEnd   == string::npos) return;
  loadIncludeFile(m_sTemplateContent, iFirstIncBegin, iFirstIncEnd+3);
 }
}
void CTemplate::replaceVariable(string &sContent, const string &sToken, const string &sValue,
         string::size_type iBeginPos, string::size_type iEndPos)
{
 string::size_type iCurrPos;
 while((iCurrPos = sContent.find(sToken, iBeginPos))!= string::npos)
 {
  if (iEndPos != string::npos && iCurrPos >= iEndPos)
   return;
  sContent.replace(iCurrPos, sToken.length(), sValue);
  iBeginPos = iCurrPos + sValue.length();
 }
}
string CTemplate::getOutput()
{
 if (m_cGobalVariable.size() == 0 && m_cLoopVariable.size() == 0 && m_cLoopArray.size() == 0)
  return m_sTemplateContent;
 std::map<std::string, std::string>::iterator iter;
 for (iter = m_cGobalVariable.begin(); iter != m_cGobalVariable.end(); ++iter)
 {
  string sToken("<% ");
  sToken += iter->first;
  sToken += " %>";
  replaceVariable(m_sTemplateContent, sToken, iter->second, 0, string::npos);
 }
 std::map<std::string, boost::shared_ptr<CTemplateArray> >::iterator iter2;
 for (iter2 = m_cLoopArray.begin(); iter2 != m_cLoopArray.end(); ++iter2)
 {
  string sTokenBegin("<% BLOCK ");
  sTokenBegin += iter2->first;
  sTokenBegin += " BEGIN %>";
  string sTokenEnd("<% BLOCK ");
  sTokenEnd += iter2->first;
  sTokenEnd += " END %>";
  string::size_type iBeginPos = 0, iCurrPos, iEndPos;
  while((iCurrPos = m_sTemplateContent.find(sTokenBegin, iBeginPos))!= string::npos)
  {
   iEndPos   = m_sTemplateContent.find(sTokenEnd, iCurrPos);
   if (iEndPos == string::npos)
    break;
   iEndPos += sTokenEnd.length();
   string sTmpContent = m_sTemplateContent.substr(iCurrPos, iEndPos);
   std::map<std::string, std::string>::const_iterator iter3 = iter2->second->getElementArray().begin();
   for (; iter3 != iter2->second->getElementArray().end(); ++iter3)
   {
    string sToken("<% ");
    sToken += iter3->first;
    sToken += " %>";
    replaceVariable(sTmpContent, sToken, iter3->second, 0, string::npos);
   }
   m_sTemplateContent.replace(iCurrPos, iEndPos - iCurrPos, sTmpContent);
   iBeginPos = iEndPos;
  }
 }
 return m_sTemplateContent;
}
void CTemplate::loadIncludeFile(string &m_sTemplateContent, string::size_type iIncBegin,
        string::size_type iIncEnd)
{
 std::string::size_type iBegin, iEnd;
 do
 {
  iBegin = m_sTemplateContent.find("\"", iIncBegin);
  if (iBegin == std::string::npos || iBegin > iIncEnd)
   throw CTemplateException("include syntax error", __func__, __LINE__);
  iEnd   = m_sTemplateContent.find("\"",iBegin + 1);
  if(iEnd == std::string::npos || iEnd > iIncEnd)
   throw CTemplateException("include syntax error2", __func__, __LINE__);
  std::string sFilePath = m_sTemplateContent.substr(iBegin + 1, iEnd - iBegin - 1);
  if (sFilePath.find("..") != std::string::npos)
   throw CTemplateException("include path must not use '..' ", __func__, __LINE__);
  std::string sTempPath = string(m_sFilePath) + "/" + sFilePath;
  string strTmpFileContent;
  OpenFile(sTempPath, strTmpFileContent);
  
  //cout << m_sTemplateContent.length() << endl;
  //cout << strTmpFileContent.length() << endl;
  m_sTemplateContent.replace(iIncBegin, iIncEnd - iIncBegin, strTmpFileContent);
  //cout << m_sTemplateContent.length() << endl;
  iIncBegin = m_sTemplateContent.find("<!--#include", iIncEnd);
  if (iIncBegin == string::npos) return;
  iIncEnd   = m_sTemplateContent.find("-->", iIncBegin);
  if (iIncEnd   == string::npos) return;
  iIncEnd += 3;
 }
 while(true);
}
void CTemplate::loadTemplateStr(const std::string &strTemplate, bool bOutputDirect, bool bStore)
{
}

#ifdef TEST
int main()
{
 try
 {
  shared_ptr<CTemplateArray> array(new CTemplateArray);
  array->addElement("hehe", "123456");
  array->addElement("hehe1", "1234567");
  array->addElement("hehe2", "1234568");
  shared_ptr<CTemplateArray> array(new CTemplateArray);
  array->addElement("hehe", "123456");
  array->addElement("hehe1", "1234567");
  array->addElement("hehe2", "1234568");
  
  CTemplate mytemplate;
  mytemplate.setLoopVar("xixi", array);
  mytemplate.setVar("kk", "123456");
  mytemplate.loadTemplateFile("/usr/local/html_template/xxx.shtml", false, false);
  cout << mytemplate.getOutput() << endl;
 }
 catch(CDuplicateException &err)
 {
  cout << err.what() << endl;
 }
 catch(CTemplateException &err)
 {
  cout << err.what() << endl;
 }
 cerr << "done" << endl;
 return 0;
}
#endif

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有