バイナリテンプレート読み込み
バイナリテンプレートを読み込むプログラムを書いてみた。
できるのはプレーンテキストの読み込みと変数の置き換えのみ。
perlから読み出せるようにもなっていないし、
ハッシュでテンプレートの変数を渡すようにもなっていない。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> //---------------------------------------------------------------------------- #define TPL_PLAIN 1 #define TPL_REPLACE 2 #define TPL_LB 253 #define TPL_RB 254 #define TPL_END 255 #define O_ENCODE 1 #define O_HSCHRS 2 #define O_HL2BR 4 #define ushort unsigned short #define uint unsigned int typedef struct { uint type; } TPL_DESC; typedef struct { uint type; uint ofsText; } TPL_DESC_PLAIN; typedef struct { uint type; uint ofsKey; uint opt; } TPL_DESC_REPLACE; typedef struct { uint type; } TPL_DESC_LB; typedef struct { uint type; } TPL_DESC_RB; typedef struct { uint type; } TPL_DESC_END; typedef struct { char* key; char* value; } REPLACE_MAP; static REPLACE_MAP replace_map[] = { { "message1", "test1" }, { "message2", "test2" }, { 0, NULL }, }; //---------------------------------------------------------------------------- char* template_insert(char file[]); void template_process(char* svHtml, void* pLines, void* pString, void* ptr); char* process_replace(TPL_DESC_REPLACE *pDesc, char *svHtml, char *pString); char* read_text(char* dst, char* r_pos); char* read_hash(char* svHtml, char* pStr, int len); //---------------------------------------------------------------------------- char* template_insert(char file[]) { char *svHtml; void *pMem, *pLines; char *pString; int len; svHtml = (char*)malloc(sizeof(char)*1000); len = mmap_file(file, (char**) &pMem); if (len == 0) exit; // ポインタを進めるときに使う pLines = pMem + sizeof(int); // 文字列を読み込むときに使う pString = (char*) (pLines + *((int*) pMem)); template_process(svHtml, pLines, pString, pLines); munmap(pMem, len); return(svHtml); } void template_process(char* svHtml, void* pLines, void* pString, void* ptr) { int lastCond; lastCond = 0; while (1) { switch( ((TPL_DESC*)ptr)->type ) { case TPL_PLAIN: svHtml = read_text(svHtml, pString + ((TPL_DESC_PLAIN*)ptr)->ofsText); ptr += sizeof(TPL_DESC_PLAIN); lastCond = 1; break; case TPL_REPLACE: svHtml = process_replace((TPL_DESC_REPLACE*)ptr, svHtml, pString); ptr += sizeof(TPL_DESC_REPLACE); lastCond = 1; break; case TPL_LB: ptr += sizeof(TPL_DESC_LB); break; case TPL_RB: ptr += sizeof(TPL_DESC_RB); break; case TPL_END: lastCond = 1; return; } } } char* process_replace(TPL_DESC_REPLACE *pDesc, char *svHtml, char *pString) { char *pStr; int len; pStr = pString + pDesc->ofsKey; len = strlen(pStr); pStr = read_hash(svHtml, pStr, len); svHtml = read_text(svHtml, pStr); return svHtml; } char* read_text(char* dst, char* r_pos) { while (*r_pos != '\0') { *(dst++) = *(r_pos++); } return dst; } char* read_hash(char* svHtml, char* pStr, int len) { REPLACE_MAP *p; char *key, *value; key = (char*)malloc(sizeof(char)*len); value = (char*)malloc(sizeof(char)*100); strcpy(key,pStr); for (p = replace_map; p->value != 0; p++) { if (strcmp(p->key,key)==0) { strcpy(value,p->value); break; } } return(value); } int mmap_file(char* file, char** buf) { int len; size_t l; FILE* fd; fd = fopen(file, "rb"); if (fd == NULL) return(0); fseek(fd, 0, SEEK_END); len = ftell(fd); fseek(fd, 0, SEEK_SET); *buf = (char*) mmap(0, len, PROT_READ, MAP_SHARED, fileno(fd), 0); fclose(fd); return(len); } int main() { char* result; char file[] = "bin.html"; result = template_insert(file); printf("%s",result); return 0; }
以下のHTMLテンプレートをコンパイルしたものを読み込んでみる。
<html> <head> <title>test</title> </head> <body> $=h:message1$ $=h:message2$ </body> </html>
出力結果は、
<html> <head> <title>test</title> </head> <body> test1 test2 </body> </html>
とりあえず置き換えられた。