www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > > 充電吧
[導讀]中午在做HTTP服務器,內(nèi)嵌了LUA引擎作為業(yè)務邏輯部分. 但考慮到LUA輸出HTML的性能不高,況且 MVC 模式開發(fā)網(wǎng)頁已經(jīng)習慣了,何不用C給lua寫個最簡單的模板引擎呢?說做就做, 項目時間很緊

中午在做HTTP服務器,內(nèi)嵌了LUA引擎作為業(yè)務邏輯部分. 但考慮到LUA輸出HTML的性能不高,況且 MVC 模式開發(fā)網(wǎng)頁已經(jīng)習慣了,何不用C給lua寫個最簡單的模板引擎呢?說做就做, 項目時間很緊張,所以必須確定目標,想了會兒。定了幾個目標:


我要的是編譯型的模板,要支持緩存。
不需要強大的模板邏輯方面的指令。將HTML模板文件編譯成LUA源代碼即可。LUA 還是比較容易擴展的,除了那棧用起來比較變態(tài)之外,經(jīng)過了幾個小時的奮斗,C+LUA代碼。算是大功告成了。

#include#include#include#include#include#include#include#include?"lib/automem.h"

#include?"lua.h"
#include?"lauxlib.h"

#include?"lua-tpl.h"

/*
	LUA?最簡單的模板引擎.
*/

const?char?LUAFMT_TPL_META[]="LUAFMT_TPL";

void?lua_cfmt_createmetatable?(lua_State?*L);
void?lua_register_class(lua_State?*?L,const?luaL_Reg?*?methods,const?char?*?name,lua_CFunction?has_index);

#if?defined(_WIN32)?||?defined(_WIN64)
	#define?open	_open
	#define?close	_close
	#define?read	_read
	#define?stat(?x?,?y?)	_stat(?x?,?y?)
#endif

static?char?*?file_get_contents(const?char?*?file,int?*?sz){
	char?*?ret?=?NULL;
	struct?stat?st;
	int?fd;
	*sz?=?0;
	if?((fd?=?open(file,?O_RDONLY|O_BINARY))?!=?-1)
	{
		if?(fstat(fd,?&st)?!=?-1)
		{
			ret?=?(char?*)malloc(st.st_size);
			if(NULL?!=?ret){
				while(?*sz?<?st.st_size){
					*sz?+=?read(fd,?ret?+?*sz,?st.st_size?-?(*sz));
					_lseek(fd,?*sz,?SEEK_SET);
				}
			}
			close(fd);
		}
	}
	return?ret;
}

int?file_put_contents(const?char*?file_name,?automem_t*?mem)
{
	FILE?*?fp?=?fopen(file_name,"wb+");
	if(NULL?!=?fp)
	{
		fwrite(mem->pdata,?mem->size,?1,?fp);
		fclose(fp);
		return?1;
	}
	return?0;
}

enum{
	tpl_state_normal,
	tpl_state_scode_1,
	tpl_state_code,
	tpl_state_ecode_1,
	tpl_state_escape,
};

#define?append_end_stringfield(a,b,c)?
	automem_append_voidp(?(a)?,?cmd,?lcmd);?
	automem_append_voidp(?(a),?(b)?,?(c));?
	automem_append_voidp(?(a)?,?ecmd,?lecmd);?
	automem_append_voidp(?(a),?")n",?2);

static?void?lua_tpl_compile_local(lua_State?*?L,?automem_t?*?mem,?const?char?*?buf,int?lbuf){
	int?state?=?tpl_state_normal,?i?=?0;
	const?char?*?sbuf;?char?c;
	size_t?lcmd?=?sizeof("request.print([[")?-1,
		lecmd?=?sizeof("]])")?-1,
		lpre?=?0;
	const?char?*?cmd?=?"request.print([[",
		*?ecmd?=?"]])",
		*pre?=?NULL;

	if(lua_isstring(L,?3))
		cmd?=luaL_checklstring(L,?3,?&lcmd);

	if(lua_isstring(L,?4))
		ecmd?=luaL_checklstring(L,?4,?&lecmd);

	if(lua_isstring(L,?5))
		pre?=luaL_checklstring(L,?5,?&lpre);

	if(NULL?!=?pre){
		automem_append_voidp(mem,?pre,?lpre);
		automem_append_byte(mem,'n');
	}
	sbuf?=?buf;
	while(i?<?lbuf){
		c?=?buf[i];
		switch?(state)
		{
		case?tpl_state_normal:
			switch(c){
			case?'{':
				state?=?tpl_state_scode_1;
				break;
			}
			break;
		case?tpl_state_scode_1:
			switch(c){
			case?'#':
				state?=tpl_state_code;
				append_end_stringfield(mem,sbuf,?&buf[i]?-?sbuf-1);
				sbuf?=?&buf[i+1];
				break;
			default:
				state?=?tpl_state_normal;
				break;
			}
			break;
		case?tpl_state_code:
			switch(c){
			case?'#':
				state?=?tpl_state_ecode_1;
				break;
			}
		case?tpl_state_ecode_1:
			switch(c){
			case?'}':
				automem_append_voidp(mem,sbuf,?&buf[i]?-?sbuf-1);
				automem_append_byte(mem,'n');
				sbuf?=?&buf[i+1];
				state?=?tpl_state_normal;
				break;
			default:
				state=tpl_state_code;
			}
		default:
			break;
		}
		i++;
	}
	if(tpl_state_normal?==?state){
		append_end_stringfield(mem,sbuf,?&buf[i]?-?sbuf);
	}
}
/*?對模板文件進行編譯.*/
static?int?lua_tpl_compile(lua_State?*?L)
{
	int?cache?=?0,i?=?0,?lbuf?=?0;
	size_t?lfile;
	const?char?*cfile?=?NULL,?*?file=?luaL_checklstring(L,?1,&lfile),*?buf;
	automem_t?mem;

	if(lua_isboolean(L,?2))
		cache?=lua_toboolean(L,?2);

	if(0?!=?cache){
		struct?stat?st1,st2;
		cfile=(char?*)malloc(lfile+5);
		memcpy((char?*)cfile,file,lfile);
		strcpy((char?*)cfile+lfile,".tpl");

		if((0?==?stat(file,&st1))?&&?(0?==?stat(cfile,?&st2)))
		{
			if(st1.st_mtime?<=?st2.st_mtime)
			{
				if(NULL?!=?(buf?=?file_get_contents(cfile,?&lbuf)))
				{
					free((void?*)cfile);
					lua_pushlstring(L,buf,?lbuf);
					goto?lua_tpl_compile_final;
				}
			}
		}
	}

	if(NULL?!=?(buf?=?file_get_contents(file,?&lbuf)))
	{
		automem_init(&mem,lbuf?+?1024);
		lua_tpl_compile_local(L,?&mem,?buf,?lbuf);
		free((void*)buf);
		lua_pushlstring(L,(char?*)mem.pdata,mem.size);
		if(0?!=?cache?&&?NULL?!=cfile)
			file_put_contents(cfile,&mem);

		automem_uninit(&mem);
	}

	if(NULL?!=?cfile)
		free((void?*)cfile);
lua_tpl_compile_final:
	return?1;
}

static?luaL_Reg?fmt_tpl_reg[]?=?{
	{"compile",lua_tpl_compile},
	{NULL,NULL}
};

int?luaopen_cfmt_tpl(lua_State?*?L)
{
	luaL_newlib(L,?fmt_tpl_reg);
	lua_cfmt_createmetatable(L);
	return?1;
}



整個LUA模塊擴展就1個函數(shù) compile()。在LUA中的原型如下:


string??compile(filePath,cached,?write,?prefix,suffix,init)


功能: 將html模板編譯為lua代碼.

參數(shù):


filePath: html源文件的路徑.cached: 是否需要緩存.writer: 內(nèi)容輸出函數(shù)名.prefix: 文件分界符前綴.init:初始代碼,用于做參數(shù)展開之類的工作.


當然,光有C的接口還不夠,為了使它變得簡單易用,還需要用LUA對其包裝一下^_^, 包裝代碼如下:


function?util.tpl(writer)
	local?t?=??require?"cfmt.tpl"
	local?tpl?=?{}
	local?args?=?{}
	local?_prefix='[=['
	local?_suffix=']=]'
	--?創(chuàng)建的時候指定?writer
	if?nil?~=?writer?then?args['_']=writer?end
	
	function?tpl:assign(name,value)
		args[name]=value
	end
	
	function?tpl:boundary(prefix,?suffix)?--修改字符串邊界符
		if?nil?~=?prefix?then?_prefix=prefix?end
		if?nil?~=?suffix?then?_suffix=suffix?end
	end
	
	function?tpl:display(tpl,cache,writer)?--?tpl?模板文件位置,?cache?是否需要緩存?writer?可選,如果創(chuàng)建對象的時候指定了的話.
		local?i=1

		if?nil~=writer?then?args['_']=writer?end
		local?init?=?{'local?args?=?...'}
		for?key,val?in?pairs(args)?do
			init[#init+1]='local?'..key..'=args["'..key..'"]'
			i=i+1
		end

		init?=?table.concat(init,'n')
		local?code?=t.compile(tpl,cache,'_('.._prefix,?_suffix,init)
		load(code)(args)
	end
	return?tpl;
end




接下來用起來就簡單多了,上測試代碼.


---外部進來的數(shù)據(jù)在這里做檢測
function?login:request(r)

	local?tpl?=?(require?"util").tpl(r.print)
	
	local?users?={
		{['ID']=1,['username']='bywayboy',['age']=31},
		{['ID']=1,['username']='liigo',['age']=31},
		{['ID']=1,['username']='sunwei',['age']=8},

	}
	local?b={['a']=12}
	
	tpl:assign('users',users);
	tpl:assign('title',"測試模板變量.")
	tpl:assign('name',"某某童鞋")
	
	tpl:display("D:\VC\CmdChannel\win32\Debug\test.html",true)
end


再來一個模板文件示例:



{#_(title)#}--方121212法ID姓名年齡{#?for?key,val?in?pairs(users)?do#}{#_(val['ID'])?#}{#_(val['username'])#}{#_(val['age'])#}{#end#}{#_(name)#}


該文件最終生成的緩存文件為:



local?args?=?...
local?_=args["_"]
local?name=args["name"]
local?users=args["users"]
local?title=args["title"]
_([=[]=])
_(title)
_([=[--方121212法ID姓名年齡]=])
?for?key,val?in?pairs(users)?do
_([=[]=])
_(val['ID'])?
_([=[]=])
_(val['username'])
_([=[]=])
_(val['age'])
_([=[]=])
end
_([=[]=])
_(name)
_([=[]=])


輸出結果如圖:


最終生成的HTML代碼如下:

測試模板變量.--方121212法ID姓名年齡1bywayboy311liigo311sunwei8某某童鞋





本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅(qū)動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅(qū)動性能的關鍵。

關鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質(zhì)量和效率直接關系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅(qū)動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關鍵字: LED 驅(qū)動電源 開關電源

LED驅(qū)動電源是把電源供應轉換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅(qū)動電源
關閉