一个资源打包工具完整代码
来源:互联网 发布:农村淘宝的规划 编辑:程序博客网 时间:2024/06/05 14:19
#include <stdio.h>#include <string.h>static char g_mem[5 * 1024 * 1024];#define MORE17#define min(a, b) ((a) < (b) ? (a) : (b))typedef struct _ResMap{ char *pName; int iPos; int iLen; int iOrgLen; char *pData; int iDstBegin;} ResMap;typedef struct _Item{ ResMap *rm; int next;} Item;int ReadFile(char *pName){ FILE *pFile = fopen(pName, "rb"); int n = 0; char *p = g_mem; while (1) { n = fread(p, 1, 10240, pFile); if (n == 0) break; p += n; } fclose(pFile); return p - g_mem;}int Hash(char *str, int n){ unsigned int val = 0; n += MORE; for (; *str; ++str) { val = val * 31 + *str; } return val % n;}static char g_hex[] = "0123456789abcdef";void ChangeHex(char *pFileName, ResMap *pMapBuf, int iIsLast, int *piFrom){ int iLen = ReadFile(pFileName); int nlen = strlen(pFileName) + 1; int iRstLen = (iLen + nlen) * 5; char *pMem = malloc(iRstLen); char *pCur = pMem; unsigned char *pSrc = (unsigned char *)g_mem; int i = 0; for (i = 0; i < nlen; i++, pCur += 5) { pCur[0] = '0'; pCur[1] = 'x'; pCur[2] = g_hex[(pFileName[i] >> 4) & 0xf]; pCur[3] = g_hex[pFileName[i] & 0xf]; pCur[4] = ','; } for (i = 0; i < iLen; i++, pCur += 5) { pCur[0] = '0'; pCur[1] = 'x'; pCur[2] = g_hex[(pSrc[i] >> 4) & 0xf]; pCur[3] = g_hex[pSrc[i] & 0xf]; pCur[4] = ','; } iLen += nlen; iRstLen -= (iIsLast ? 1 : 0); pMapBuf->pName = pFileName; pMapBuf->iLen = iRstLen; pMapBuf->pData = pMem; pMapBuf->iOrgLen = iLen; pMapBuf->iDstBegin = *piFrom; *piFrom += iLen;}void WriteHead(FILE *pC){ char *p = "#include <string.h>\n\n" "typedef struct _ResMap {\n" "int iPos;\n" "int iDatLen;\n" "short sNameLen;\n" "short sNext;\n" "} ResMap;\n\n"; fwrite(p, strlen(p), 1, pC);}void WriteFunc(FILE *pC, int n){ char *p = "static int Hash(const char *str)\n" "{\n" "unsigned int val = 0;\n" "for (; *str; ++str)\n" "val = val * 31 + *str;\n" "return val % "; fwrite(p, strlen(p), 1, pC); char buf[10]; sprintf(buf, "%d;\n", n + MORE); fwrite(buf, strlen(buf), 1, pC); p = "}\n\n" "void * LoadRes(const char* pName, int *piLen)\n" "{\n" "int i = 0;\n" "if (!pName || !piLen)\n" " return 0;\n\n" "i = Hash(pName);\n" "*piLen = 0;\n\n" " while (i != -1) {\n" "if (! g_map[i].iDatLen)\n" "return 0;\n" "char *pExName = g_dat + g_map[i].iPos;\n" " if (strcmp(pName, pExName) == 0) {\n" " *piLen = g_map[i].iDatLen;\n" " return (g_dat + g_map[i].iPos + g_map[i].sNameLen);\n" "}\n" "i = g_map[i].sNext;\n" "}\n" "return 0;\n" "}\n\n\n"; fwrite(p, strlen(p), 1, pC);}void WriteCnt(FILE *pC, ResMap *pMap, int iResNum){ int i = 0; char *p = "static char g_dat[] = {"; fwrite(p, strlen(p), 1, pC); for (; i < iResNum; i++) { int len = pMap->iLen; char *dat = pMap->pData; while (len > 0) { fwrite("\n\t", 2, 1, pC); fwrite(dat, min(len, 80), 1, pC); len -= 80;dat += 80; } ++pMap; } fwrite("\n};\n\n", 4, 1, pC);}void WriteTail(FILE *pC, Item *pIt, int iResNum){ char tmp[100]; char name[100]; int iMn = iResNum + MORE; sprintf(tmp, "static ResMap g_map[] = {"); fwrite(tmp, strlen(tmp), 1, pC); int i = 0, line = 0;fwrite("\n\t", 2, 1, pC); for (; i < iMn; i++) { char *p = (i == iMn - 1) ? "" : ","; if (pIt->rm) { int iLen = strlen(pIt->rm->pName) + 1; sprintf(tmp, "{0x%x,0x%x,0x%x,%d}%s", pIt->rm->iDstBegin, pIt->rm->iOrgLen - iLen, iLen, pIt->next, p); } else { sprintf(tmp, "{0}%s", p); } line += strlen(tmp); if (line > 80) { fwrite("\n\t", 2, 1, pC); line = strlen(tmp); } fwrite(tmp, strlen(tmp), 1, pC); ++pIt; } fwrite("\n};\n\n\n", 6, 1, pC);}static char ** GetFileName(int *pNum){ char **pList = malloc(1000 * sizeof(char *));; char buf[100]; *pNum = 0; char *p = g_mem; int len = ReadFile("r.txt"); p[len] = '\0'; while (sscanf(p, "%s\n", buf) > 0) { pList[*pNum] = malloc(strlen(buf) + 1); strcpy(pList[*pNum], buf); if (*buf == '\0') break; (*pNum)++; p += strlen(buf) + 1; } return pList;}int FindPos(Item *pIt, int start, char *name){ if (strcmp(pIt[start].rm->pName, name) == 0) return -1; int i = start, old ; while (1) { int mi = pIt[i].next; if (mi == -1) { old = i; break; } i = mi; } i = 0; while (1) { if (! pIt[i].rm) break; i++; } pIt[old].next = i; return i;}int main(){ int n = 0; int mn = 0; char **pNames = GetFileName(&n); ResMap *pMap = malloc(sizeof(ResMap) * n); mn = n + MORE; Item *pIt = malloc(sizeof(Item) * mn); memset(pIt, 0, sizeof(Item) * mn); int i = 0, from = 0; for (; i < mn; i++) pIt[i].next = -1; for (i = 0; i < n; i++) { ChangeHex(pNames[i], pMap + i, i == n - 1, &from); int v = Hash(pNames[i], n); if (! pIt[v].rm) { pIt[v].rm = pMap + i; } } for (i = 0; i < n; i++) { int v = Hash(pNames[i], n); int pos = FindPos(pIt, v, pNames[i]); if (pos != -1) { pIt[pos].rm = pMap + i; } } FILE *pC = fopen("R.c", "wb"); WriteHead(pC); WriteCnt(pC, pMap, n); WriteTail(pC, pIt, n); WriteFunc(pC, n); fclose(pC); return 0;}
本程序从r.txt中读取需要打包的资源文件名, 最终生成了一个R.c文件
将R.c与其它c文件一起编译即可。
r.txt文件格式如下所示:
abc.png
def.jpg
.....
每个文件名占一行。
生成的R.c文件内容大概是这样子的:
#include <string.h>typedef struct _ResMap {int iPos;int iDatLen;short sNameLen;short sNext;} ResMap;static char g_dat[] = {0x6d,0x61,0x69,0x6e,0x2e,0x63,0x00,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x73,0x74,0x64,0x69,0x6f,0x2e,0x68,0x3e,0x0d,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x73,0x74,0x72,0x69,0x6e,.....};static ResMap g_map[] = {{0x8b90,0x32ef,0x7,-1},{0},{0x1ab4,0x70d3,0x9,0},{0},{0},{0},{0},{0},{0},{0},{0},{0x0,0x1aad,0x7,-1},{0},{0},{0},{0xbe86,0x19,0x2,-1},.....};static int Hash(const char *str){unsigned int val = 0;for (; *str; ++str)val = val * 31 + *str;return val % 21;}void * LoadRes(const char* pName, int *piLen){int i = 0;if (!pName || !piLen) return 0;i = Hash(pName);*piLen = 0; while (i != -1) {if (! g_map[i].iDatLen)return 0;char *pExName = g_dat + g_map[i].iPos; if (strcmp(pName, pExName) == 0) { *piLen = g_map[i].iDatLen; return (g_dat + g_map[i].iPos + g_map[i].sNameLen);}i = g_map[i].sNext;}return 0;}
通过LoadRes即可得到资源的内容, 时间复杂度接近于O(1)
- 一个资源打包工具完整代码
- cocos2dx资源进行打包的工具和代码实zpack
- cocos2dx资源进行打包的工具和代码实现zpack
- 一个图片打包工具
- 注射的一个完整代码
- swift-tool 图片资源打包工具
- 微信Android资源混淆打包工具
- 使用脚本工具批量打包游戏资源
- 微信资源混淆工具打包
- 资源_代码格式化工具
- 如何打包一个bundle资源文件
- 使用NSIS打包一个客户端的完整示例
- 用gulp做一个略完整的前端打包工作~
- 一个完整的Android项目打包成第三方库
- 一个完整的代码调试页
- 一个完整的单例模式代码
- C++编写一个文件打包工具
- Inno一个程序打包安装工具
- The type Base64 is not accessible due to restriction on required library 解决办法
- 下载android4.0代码相关资料
- Java基础_增强For循环
- MYSQL远程连接,权限设定
- Invalid result location value/parameter 解决办法
- 一个资源打包工具完整代码
- 选择法排序
- 继承qstringlist ,写给自己看的
- sql 查询存储过程的定义过程
- PreparedStatement 的excute方法的返回值问题
- android 文件系统,创建单个文件大小有2G限制
- 电话投保要小心
- 道一句为爱的牵挂 曾经的温柔能回来吗
- Java 获取文件名 输入输出