luat_fs_luadb.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. #include "luat_base.h"
  2. #include "luat_luadb.h"
  3. #include "luat_mem.h"
  4. #include "luat_fs.h"
  5. #define LUAT_LOG_TAG "luadb"
  6. #include "luat_log.h"
  7. #undef LLOGD
  8. #define LLOGD(...)
  9. #ifndef LUAT_CONF_LUADB_CUSTOM_READ
  10. void luat_luadb_read_bytes(char* dst, const char* ptr, size_t len) {
  11. memcpy(dst, ptr, len);
  12. }
  13. static uint8_t readU8(const char* ptr, int *index) {
  14. int val = ptr[*index];
  15. *index = (*index) + 1;
  16. return val & 0xFF;
  17. }
  18. #else
  19. extern void luat_luadb_read_bytes(char* dst, const char* ptr, size_t len);
  20. static uint8_t readU8(const char* ptr, int *index) {
  21. char val = 0;
  22. luat_luadb_read_bytes(&val, ptr + (*index), 1);
  23. *index = (*index) + 1;
  24. return val & 0xFF;
  25. }
  26. #endif
  27. static uint16_t readU16(const char* ptr, int *index) {
  28. return readU8(ptr,index) + (readU8(ptr,index) << 8);
  29. }
  30. static uint32_t readU32(const char* ptr, int *index) {
  31. return readU16(ptr,index) + (readU16(ptr,index) << 16);
  32. }
  33. //---
  34. int luat_luadb_umount(luadb_fs_t *fs) {
  35. if (fs)
  36. luat_heap_free(fs);
  37. return 0;
  38. }
  39. int luat_luadb_remount(luadb_fs_t *fs, unsigned flags) {
  40. (void)flags;
  41. memset(fs->fds, 0, sizeof(luadb_fd_t)*LUAT_LUADB_MAX_OPENFILE);
  42. return 0;
  43. }
  44. static luadb_file_t* find_by_name(luadb_fs_t *fs, const char *path) {
  45. for (size_t i = 0; i < fs->filecount; i++)
  46. {
  47. if (!strcmp(path, fs->files[i].name)) {
  48. return &(fs->files[i]);
  49. }
  50. }
  51. // luadb_file_t *ext = fs->inlines;
  52. // while (ext->ptr != NULL)
  53. // {
  54. // if (!strcmp(path, ext->name)) {
  55. // return ext;
  56. // }
  57. // ext += 1;
  58. // }
  59. return NULL;
  60. }
  61. int luat_luadb_open(luadb_fs_t *fs, const char *path, int flags, int /*mode_t*/ mode) {
  62. (void)flags;
  63. (void)mode;
  64. LLOGD("open luadb path = %s flags=%d", path, flags);
  65. int fd = -1;
  66. for (size_t j = 1; j < LUAT_LUADB_MAX_OPENFILE; j++)
  67. {
  68. if (fs->fds[j].file == NULL) {
  69. fd = j;
  70. break;
  71. }
  72. }
  73. if (fd == -1) {
  74. LLOGD("too many open files for luadb");
  75. return 0;
  76. }
  77. luadb_file_t* f = find_by_name(fs, path);
  78. if (f != NULL) {
  79. fs->fds[fd].fd_pos = 0;
  80. fs->fds[fd].file = f;
  81. LLOGD("open luadb path = %s fd=%d", path, fd);
  82. return fd;
  83. }
  84. return 0;
  85. }
  86. int luat_luadb_close(luadb_fs_t *fs, int fd) {
  87. if (fd < 0 || fd >= LUAT_LUADB_MAX_OPENFILE)
  88. return -1;
  89. if (fs->fds[fd].file != NULL) {
  90. fs->fds[fd].file = NULL;
  91. fs->fds[fd].fd_pos = 0;
  92. return 0;
  93. }
  94. return -1;
  95. }
  96. size_t luat_luadb_read(luadb_fs_t *fs, int fd, void *dst, size_t size) {
  97. if (fd < 0 || fd >= LUAT_LUADB_MAX_OPENFILE || fs->fds[fd].file == NULL)
  98. return 0;
  99. luadb_fd_t *fdt = &fs->fds[fd];
  100. int re = size;
  101. if (fdt->fd_pos + size > fdt->file->size) {
  102. re = fdt->file->size - fdt->fd_pos;
  103. }
  104. if (re > 0) {
  105. #ifndef LUAT_CONF_LUADB_CUSTOM_READ
  106. memcpy(dst, fdt->file->ptr + fdt->fd_pos, re);
  107. #else
  108. luat_luadb_read_bytes(dst, fdt->file->ptr + fdt->fd_pos, re);
  109. #endif
  110. fdt->fd_pos += re;
  111. }
  112. //LLOGD("luadb read name %s offset %d size %d ret %d", fdt->file->name, fdt->fd_pos, size, re);
  113. return re;
  114. }
  115. long luat_luadb_lseek(luadb_fs_t *fs, int fd, long /*off_t*/ offset, int mode) {
  116. if (fd < 0 || fd >= LUAT_LUADB_MAX_OPENFILE || fs->fds[fd].file == NULL)
  117. return -1;
  118. if (mode == SEEK_END) {
  119. fs->fds[fd].fd_pos = fs->fds[fd].file->size;
  120. }
  121. else if (mode == SEEK_CUR) {
  122. fs->fds[fd].fd_pos += offset;
  123. }
  124. else {
  125. fs->fds[fd].fd_pos = offset;
  126. }
  127. return fs->fds[fd].fd_pos;
  128. }
  129. luadb_file_t * luat_luadb_stat(luadb_fs_t *fs, const char *path) {
  130. return find_by_name(fs, path);
  131. }
  132. luadb_fs_t* luat_luadb_mount(const char* _ptr) {
  133. int index = 0;
  134. int headok = 0;
  135. int dbver = 0;
  136. int headsize = 0;
  137. size_t filecount = 0;
  138. const char * ptr = (const char *)_ptr;
  139. //LLOGD("LuaDB ptr = %p", ptr);
  140. uint16_t magic1 = 0;
  141. uint16_t magic2 = 0;
  142. for (size_t i = 0; i < 128; i++)
  143. {
  144. int type = readU8(ptr, &index);
  145. int len = readU8(ptr, &index);
  146. //LLOGD("PTR: %d %d %d", type, len, index);
  147. switch (type) {
  148. case 1: {// Magic, 肯定是4个字节
  149. if (len != 4) {
  150. LLOGD("Magic len != 4");
  151. goto _after_head;
  152. }
  153. magic1 = readU16(ptr, &index);
  154. magic2 = readU16(ptr, &index);
  155. if (magic1 != magic2 || magic1 != 0xA55A) {
  156. LLOGD("Magic not match 0x%04X%04X", magic1, magic2);
  157. goto _after_head;
  158. }
  159. break;
  160. }
  161. case 2: {
  162. if (len != 2) {
  163. LLOGD("Version len != 2");
  164. goto _after_head;
  165. }
  166. dbver = readU16(ptr, &index);
  167. LLOGD("LuaDB version = %d", dbver);
  168. break;
  169. }
  170. case 3: {
  171. if (len != 4) {
  172. LLOGD("Header full len != 4");
  173. goto _after_head;
  174. }
  175. headsize = readU32(ptr, &index);
  176. break;
  177. }
  178. case 4 : {
  179. if (len != 2) {
  180. LLOGD("Lua File Count len != 4");
  181. goto _after_head;
  182. }
  183. filecount = readU16(ptr, &index);
  184. LLOGD("LuaDB file count %d", filecount);
  185. break;
  186. }
  187. case 0xFE : {
  188. if (len != 2) {
  189. LLOGD("CRC len != 4");
  190. goto _after_head;
  191. }
  192. index += len;
  193. headok = 1;
  194. goto _after_head;
  195. }
  196. default: {
  197. index += len;
  198. LLOGD("skip unkown type %d", type);
  199. break;
  200. }
  201. }
  202. }
  203. _after_head:
  204. if (headok == 0) {
  205. LLOGW("Bad LuaDB");
  206. return NULL;
  207. }
  208. if (dbver == 0) {
  209. LLOGW("miss DB version");
  210. return NULL;
  211. }
  212. if (headsize == 0) {
  213. LLOGW("miss DB headsize");
  214. return NULL;
  215. }
  216. if (filecount == 0) {
  217. LLOGW("miss DB filecount");
  218. return NULL;
  219. }
  220. if (filecount > 1024) {
  221. LLOGW("too many file in LuaDB");
  222. return NULL;
  223. }
  224. LLOGD("LuaDB head seem ok");
  225. // 由于luadb_fs_t带了一个luadb_file_t元素的
  226. size_t msize = sizeof(luadb_fs_t) + (filecount - 1)*sizeof(luadb_file_t);
  227. LLOGD("malloc fo luadb fs size=%d", msize);
  228. luadb_fs_t *fs = (luadb_fs_t*)luat_heap_malloc(msize);
  229. if (fs == NULL) {
  230. LLOGD("malloc for luadb fail!!!");
  231. return NULL;
  232. }
  233. memset(fs, 0, msize);
  234. LLOGD("LuaDB check files ....");
  235. fs->version = dbver;
  236. fs->filecount = filecount;
  237. //fs->ptrpos = initpos;
  238. int fail = 0;
  239. uint8_t type = 0;
  240. uint32_t len = 0;
  241. // int hasSys = 0;
  242. // 读取每个文件的头部
  243. for (size_t i = 0; i < filecount; i++)
  244. {
  245. LLOGD("LuaDB check files .... %d", i+1);
  246. type = readU8(ptr, &index);
  247. len = readU8(ptr, &index);
  248. if (type != 1 || len != 4) {
  249. LLOGD("bad file data 1 : %d %d %d", type, len, index);
  250. fail = 1;
  251. break;
  252. }
  253. // skip magic
  254. index += 4;
  255. // 2. 然后是名字
  256. type = readU8(ptr, &index);
  257. len = readU8(ptr, &index);
  258. if (type != 2) {
  259. LLOGD("bad file data 2 : %d %d %d", type, len, index);
  260. fail = 1;
  261. break;
  262. }
  263. // 拷贝文件名
  264. LLOGD("LuaDB file name len = %d", len);
  265. #ifndef LUAT_CONF_LUADB_CUSTOM_READ
  266. memcpy(fs->files[i].name, &(ptr[index]), len);
  267. #else
  268. luat_luadb_read_bytes(fs->files[i].name, ptr + index, len);
  269. #endif
  270. fs->files[i].name[len] = 0x00;
  271. index += len;
  272. LLOGD("LuaDB file name %.*s", len, fs->files[i].name);
  273. // 3. 文件大小
  274. type = readU8(ptr, &index);
  275. len = readU8(ptr, &index);
  276. if (type != 3 || len != 4) {
  277. LLOGD("bad file data 3 : %d %d %d", type, len, index);
  278. fail = 1;
  279. break;
  280. }
  281. fs->files[i].size = readU32(ptr, &index);
  282. // 0xFE校验码
  283. type = readU8(ptr, &index);
  284. len = readU8(ptr, &index);
  285. if (type != 0xFE || len != 2) {
  286. LLOGD("bad file data 4 : %d %d %d", type, len, index);
  287. fail = 1;
  288. break;
  289. }
  290. // 校验码就跳过吧
  291. index += len;
  292. fs->files[i].ptr = (const char*)(index + ptr); // 绝对地址
  293. index += fs->files[i].size;
  294. LLOGD("LuaDB: %s %d", fs->files[i].name, fs->files[i].size);
  295. }
  296. if (fail == 0) {
  297. LLOGD("LuaDB check files .... ok");
  298. // #ifdef LUAT_CONF_VM_64bit
  299. // //#if (sizeof(size_t) == 8)
  300. // //fs->inlines = (luadb_file_t *)luat_inline2_libs_64bit_size64;
  301. // //#else
  302. // fs->inlines = (luadb_file_t *)luat_inline2_libs_64bit_size32;
  303. // //#endif
  304. // #else
  305. // fs->inlines = (luadb_file_t *)luat_inline2_libs;
  306. // #endif
  307. return fs;
  308. }
  309. else {
  310. LLOGD("LuaDB check files .... fail");
  311. luat_heap_free(fs);
  312. return NULL;
  313. }
  314. }
  315. #ifdef LUAT_USE_FS_VFS
  316. FILE* luat_vfs_luadb_fopen(void* userdata, const char *filename, const char *mode) {
  317. if (!strcmp("r", mode) || !strcmp("rb", mode) || !strcmp("r+", mode) || !strcmp("rb+", mode)) {
  318. }
  319. else {
  320. LLOGW("/luadb is readonly %s %s", filename, mode);
  321. return (FILE*)NULL;
  322. }
  323. return (FILE*)luat_luadb_open((luadb_fs_t*)userdata, filename, 0, 0);
  324. }
  325. int luat_vfs_luadb_fseek(void* userdata, FILE* stream, long int offset, int origin) {
  326. int ret = luat_luadb_lseek((luadb_fs_t*)userdata, (int)stream, offset, origin);
  327. if (ret < 0)
  328. return -1;
  329. return 0;
  330. }
  331. int luat_vfs_luadb_ftell(void* userdata, FILE* stream) {
  332. return luat_luadb_lseek((luadb_fs_t*)userdata, (int)stream, 0, SEEK_CUR);
  333. }
  334. int luat_vfs_luadb_fclose(void* userdata, FILE* stream) {
  335. return luat_luadb_close((luadb_fs_t*)userdata, (int)stream);
  336. }
  337. int luat_vfs_luadb_feof(void* userdata, FILE* stream) {
  338. int cur = luat_luadb_lseek((luadb_fs_t*)userdata, (int)stream, 0, SEEK_CUR);
  339. int end = luat_luadb_lseek((luadb_fs_t*)userdata, (int)stream, 0, SEEK_END);
  340. luat_luadb_lseek((luadb_fs_t*)userdata, (int)stream, cur, SEEK_SET);
  341. return cur >= end ? 1 : 0;
  342. }
  343. int luat_vfs_luadb_ferror(void* userdata, FILE *stream) {
  344. (void)userdata;
  345. (void)stream;
  346. return 0;
  347. }
  348. size_t luat_vfs_luadb_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
  349. return luat_luadb_read((luadb_fs_t*)userdata, (int)stream, ptr, size * nmemb);
  350. }
  351. int luat_vfs_luadb_getc(void* userdata, FILE* stream) {
  352. char c = 0;
  353. size_t ret = luat_vfs_luadb_fread((luadb_fs_t*)userdata, &c, 1, 1, stream);
  354. if (ret > 0) {
  355. return (int)c;
  356. }
  357. return -1;
  358. }
  359. size_t luat_vfs_luadb_fwrite(void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
  360. (void)userdata;
  361. (void)stream;
  362. (void)ptr;
  363. (void)size;
  364. (void)nmemb;
  365. return 0;
  366. }
  367. int luat_vfs_luadb_remove(void* userdata, const char *filename) {
  368. (void)userdata;
  369. (void)filename;
  370. LLOGW("/luadb is readonly %s", filename);
  371. return -1;
  372. }
  373. int luat_vfs_luadb_rename(void* userdata, const char *old_filename, const char *new_filename) {
  374. (void)userdata;
  375. (void)old_filename;
  376. (void)new_filename;
  377. LLOGW("/luadb is readonly %s", old_filename);
  378. return -1;
  379. }
  380. int luat_vfs_luadb_fexist(void* userdata, const char *filename) {
  381. FILE* fd = luat_vfs_luadb_fopen(userdata, filename, "rb");
  382. if (fd) {
  383. luat_vfs_luadb_fclose(userdata, fd);
  384. return 1;
  385. }
  386. return 0;
  387. }
  388. size_t luat_vfs_luadb_fsize(void* userdata, const char *filename) {
  389. FILE *fd;
  390. size_t size = 0;
  391. fd = luat_vfs_luadb_fopen(userdata, filename, "rb");
  392. if (fd) {
  393. luat_vfs_luadb_fseek(userdata, fd, 0, SEEK_END);
  394. size = luat_vfs_luadb_ftell(userdata, fd);
  395. luat_vfs_luadb_fclose(userdata, fd);
  396. }
  397. return size;
  398. }
  399. int luat_vfs_luadb_mkfs(void* userdata, luat_fs_conf_t *conf) {
  400. //LLOGE("not support yet : mkfs");
  401. (void)userdata;
  402. (void)conf;
  403. return -1;
  404. }
  405. int luat_vfs_luadb_mount(void** userdata, luat_fs_conf_t *conf) {
  406. luadb_fs_t* fs = luat_luadb_mount((const char*)conf->busname);
  407. if (fs == NULL)
  408. return -1;
  409. *userdata = fs;
  410. return 0;
  411. }
  412. int luat_vfs_luadb_umount(void* userdata, luat_fs_conf_t *conf) {
  413. //LLOGE("not support yet : umount");
  414. (void)userdata;
  415. (void)conf;
  416. return 0;
  417. }
  418. int luat_vfs_luadb_mkdir(void* userdata, char const* _DirName) {
  419. //LLOGE("not support yet : mkdir");
  420. (void)userdata;
  421. (void)_DirName;
  422. return -1;
  423. }
  424. int luat_vfs_luadb_rmdir(void* userdata, char const* _DirName) {
  425. //LLOGE("not support yet : rmdir");
  426. (void)userdata;
  427. (void)_DirName;
  428. return -1;
  429. }
  430. int luat_vfs_luadb_lsdir(void* userdata, char const* _DirName, luat_fs_dirent_t* ents, size_t offset, size_t len) {
  431. (void)_DirName;
  432. luadb_fs_t* fs = (luadb_fs_t*)userdata;
  433. if (fs->filecount > offset) {
  434. if (offset + len > fs->filecount)
  435. len = fs->filecount - offset;
  436. for (size_t i = 0; i < len; i++)
  437. {
  438. ents[i].d_type = 0;
  439. strcpy(ents[i].d_name, fs->files[i+offset].name);
  440. }
  441. return len;
  442. }
  443. return 0;
  444. }
  445. // 这个全局变量是给bsp自行设置的,名字不要动
  446. size_t luat_luadb_act_size;
  447. int luat_vfs_luadb_info(void* userdata, const char* path, luat_fs_info_t *conf) {
  448. (void)path;
  449. memcpy(conf->filesystem, "luadb", strlen("luadb")+1);
  450. // 把luadb的第一个文件的偏移量估算为起始位置
  451. // 最后一个文件的偏移量+文件大小, 作为结束位置
  452. // 从而估算出luadb的实际用量
  453. size_t used = 0;
  454. luadb_fs_t* fs = (luadb_fs_t*)userdata;
  455. if (fs != NULL && fs->filecount > 0) {
  456. size_t begin = (size_t)fs->files[0].ptr;
  457. size_t end = (size_t)(fs->files[fs->filecount - 1].ptr) + fs->files[fs->filecount - 1].size;
  458. used = end - begin + 512;
  459. }
  460. conf->type = 0;
  461. conf->total_block = luat_luadb_act_size / 512;
  462. conf->block_used = (used / 512) + 1;
  463. conf->block_size = 512;
  464. return 0;
  465. }
  466. void* luat_vfs_luadb_mmap(void* userdata, FILE* f) {
  467. luadb_fs_t* fs = (luadb_fs_t*)userdata;
  468. int fd = (int)f;
  469. if (fd < 0 || fd >= LUAT_LUADB_MAX_OPENFILE || fs->fds[(int)fd].file == NULL)
  470. return 0;
  471. luadb_fd_t *fdt = &fs->fds[(int)fd];
  472. if (fdt != NULL) {
  473. return (void*)fdt->file->ptr;
  474. }
  475. return NULL;
  476. }
  477. #define T(name) .name = luat_vfs_luadb_##name
  478. const struct luat_vfs_filesystem vfs_fs_luadb = {
  479. .name = "luadb",
  480. .opts = {
  481. .mkfs = NULL,
  482. T(mount),
  483. T(umount),
  484. .mkdir = NULL,
  485. .rmdir = NULL,
  486. T(lsdir),
  487. .remove = NULL,
  488. .rename = NULL,
  489. T(fsize),
  490. T(fexist),
  491. T(info)
  492. },
  493. .fopts = {
  494. T(fopen),
  495. T(getc),
  496. T(fseek),
  497. T(ftell),
  498. T(fclose),
  499. T(feof),
  500. T(ferror),
  501. T(fread),
  502. #ifndef LUAT_CONF_LUADB_CUSTOM_READ
  503. T(mmap),
  504. #endif
  505. .fwrite = NULL
  506. }
  507. };
  508. #endif