luat_lib_zbuff.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  1. /*
  2. @module zbuff
  3. @summary c内存数据操作库
  4. @version 0.1
  5. @date 2021.03.31
  6. @video https://www.bilibili.com/video/BV1gr4y1V7HN
  7. @tag LUAT_USE_ZBUFF
  8. @demo zbuff
  9. */
  10. #include "luat_base.h"
  11. #include "luat_zbuff.h"
  12. #define LUAT_LOG_TAG "zbuff"
  13. #include "luat_log.h"
  14. #ifndef LUAT_CONF_ZBUFF_DEFAULT_TYPE
  15. #ifdef LUAT_USE_PSRAM
  16. #define LUAT_CONF_ZBUFF_DEFAULT_TYPE LUAT_HEAP_PSRAM
  17. #else
  18. #define LUAT_CONF_ZBUFF_DEFAULT_TYPE LUAT_HEAP_SRAM
  19. #endif
  20. #endif
  21. //在buff对象后添加数据,返回增加的字节数
  22. static int add_bytes(luat_zbuff_t *buff, const char *source, size_t len)
  23. {
  24. if (buff->len - buff->cursor < len)
  25. len = buff->len - buff->cursor;
  26. memcpy(buff->addr + buff->cursor, source, len);
  27. buff->cursor += len;
  28. return len;
  29. }
  30. #define SET_POINT_1(buff, point, color) \
  31. if (color % 2) \
  32. buff->addr[point / 8] |= 1 << (7 - point % 8); \
  33. else \
  34. buff->addr[point / 8] &= ~(1 << (7 - point % 8))
  35. #define SET_POINT_4(buff, point, color) \
  36. buff->addr[point / 2] &= (point % 2) ? 0xf0 : 0x0f; \
  37. buff->addr[point / 2] |= (point % 2) ? color : (color * 0x10)
  38. #define SET_POINT_8(buff, point, color) buff->addr[point] = color
  39. #define SET_POINT_16(buff, point, color) \
  40. buff->addr[point * 2] = color / 0x100; \
  41. buff->addr[point * 2 + 1] = color % 0x100
  42. #define SET_POINT_24(buff, point, color) \
  43. buff->addr[point * 3] = color / 0x10000; \
  44. buff->addr[point * 3 + 1] = color % 0x10000 / 0x100; \
  45. buff->addr[point * 3 + 2] = color % 0x100
  46. #define SET_POINT_32(buff, point, color) \
  47. buff->addr[point] = color / 0x1000000; \
  48. buff->addr[point + 1] = color % 0x1000000 / 0x10000; \
  49. buff->addr[point + 2] = color % 0x10000 / 0x100; \
  50. buff->addr[point + 3] = color % 0x100
  51. #define SET_POINT_CASE(n, point, color) \
  52. case n: \
  53. SET_POINT_##n(buff, point, color); \
  54. break
  55. //更改某点的颜色
  56. #define set_framebuffer_point(buff, point, color) \
  57. switch (buff->bit) \
  58. { \
  59. SET_POINT_CASE(1, (point), (color)); \
  60. SET_POINT_CASE(4, (point), (color)); \
  61. SET_POINT_CASE(8, (point), (color)); \
  62. SET_POINT_CASE(16, (point), (color)); \
  63. SET_POINT_CASE(24, (point), (color)); \
  64. SET_POINT_CASE(32, (point), (color)); \
  65. default: \
  66. break; \
  67. }
  68. #define GET_POINT_1(buff, point) (buff->addr[point / 8] >> (7 - point % 8)) % 2
  69. #define GET_POINT_4(buff, point) (buff->addr[point / 2] >> ((point % 2) ? 0 : 4)) % 0x10
  70. #define GET_POINT_8(buff, point) buff->addr[point]
  71. #define GET_POINT_16(buff, point) buff->addr[point * 2] * 0x100 + buff->addr[point * 2 + 1]
  72. #define GET_POINT_24(buff, point) \
  73. buff->addr[point * 3] * 0x10000 + buff->addr[point * 3 + 1] * 0x100 + buff->addr[point * 3 + 2]
  74. #define GET_POINT_32(buff, point) \
  75. buff->addr[point] * 0x1000000 + buff->addr[point + 1] * 0x10000 + buff->addr[point + 2] * 0x100 + buff->addr[point + 3]
  76. #define GET_POINT_CASE(n, point) \
  77. case n: \
  78. return GET_POINT_##n(buff, point); \
  79. //获取某点的颜色
  80. static uint32_t get_framebuffer_point(luat_zbuff_t *buff,uint32_t point)
  81. {
  82. switch (buff->bit)
  83. {
  84. GET_POINT_CASE(1, point);
  85. GET_POINT_CASE(4, point);
  86. GET_POINT_CASE(8, point);
  87. GET_POINT_CASE(16, point);
  88. GET_POINT_CASE(24, point);
  89. GET_POINT_CASE(32, point);
  90. default:
  91. break;
  92. }
  93. return 0;
  94. }
  95. /**
  96. 创建zbuff
  97. @api zbuff.create(length,data,type)
  98. @int 字节数
  99. @any 可选参数,number时为填充数据,string时为填充字符串
  100. @number 可选参数,内存类型默认自动选择
  101. @return object zbuff对象,如果创建失败会返回nil
  102. @usage
  103. -- 创建zbuff
  104. local buff = zbuff.create(1024) -- 空白的
  105. local buff = zbuff.create(1024, 0x33) --创建一个初值全为0x33的内存区域
  106. local buff = zbuff.create(1024, "123321456654") -- 创建,并填充一个已有字符串的内容
  107. -- 创建framebuff用的zbuff
  108. -- zbuff.create({width,height,bit},data,type)
  109. -- table 宽度、高度、色位深度
  110. @int 可选参数,填充数据
  111. @number 可选参数,内存类型
  112. @return object zbuff对象,如果创建失败会返回nil
  113. @usage
  114. -- 创建zbuff
  115. local buff = zbuff.create({128,160,16})--创建一个128*160的framebuff
  116. local buff = zbuff.create({128,160,16},0xf800)--创建一个128*160的framebuff,初始状态红色
  117. */
  118. static int l_zbuff_create(lua_State *L)
  119. {
  120. size_t len;
  121. uint32_t width = 0,height = 0;
  122. uint8_t bit = 0;
  123. if (lua_istable(L, 1)){
  124. lua_rawgeti(L, 1, 3);
  125. lua_rawgeti(L, 1, 2);
  126. lua_rawgeti(L, 1, 1);
  127. width = luaL_checkinteger(L, -1);
  128. height = luaL_checkinteger(L, -2);
  129. bit = luaL_checkinteger(L, -3);
  130. if (bit != 1 && bit != 4 && bit != 8 && bit != 16 && bit != 24 && bit != 32) return 0;
  131. len = (width * height * bit - 1) / 8 + 1;
  132. lua_pop(L, 3);
  133. } else {
  134. len = luaL_checkinteger(L, 1);
  135. }
  136. if (len <= 0) return 0;
  137. if (len >= 64*1024) {
  138. LLOGI("create large size: %d kbyte, trigger force GC", len / 1024);
  139. lua_gc(L, LUA_GCCOLLECT, 0);
  140. lua_gc(L, LUA_GCCOLLECT, 0);
  141. }
  142. luat_zbuff_t *buff = (luat_zbuff_t *)lua_newuserdata(L, sizeof(luat_zbuff_t));
  143. if (buff == NULL) return 0;
  144. if (lua_isinteger(L, 3)){
  145. buff->type = luaL_optinteger(L, 3, LUAT_CONF_ZBUFF_DEFAULT_TYPE);
  146. } else {
  147. buff->type = LUAT_CONF_ZBUFF_DEFAULT_TYPE;
  148. }
  149. buff->addr = (uint8_t *)luat_heap_opt_malloc(buff->type,len);
  150. if (buff->addr == NULL){
  151. // 尝试垃圾回收后再分配一次
  152. LLOGI("create size: %d byte but memory not enough, trigger GC", len);
  153. lua_gc(L, LUA_GCCOLLECT, 0);
  154. lua_gc(L, LUA_GCCOLLECT, 0);
  155. buff->addr = (uint8_t *)luat_heap_opt_malloc(buff->type,len);
  156. }
  157. if (buff->addr == NULL){
  158. LLOGW("create size: %d byte but memory not enough!!!", len);
  159. lua_pushnil(L);
  160. lua_pushstring(L, "memory not enough");
  161. return 2;
  162. }
  163. buff->len = len;
  164. buff->cursor = 0;
  165. if (lua_istable(L, 1)){
  166. buff->width = width;
  167. buff->height = height;
  168. buff->bit = bit;
  169. if (lua_isinteger(L, 2)){
  170. LUA_INTEGER initial = luaL_checkinteger(L, 2);
  171. uint32_t i;
  172. for (i = 0; i < buff->width * buff->height; i++){
  173. set_framebuffer_point(buff, i, initial);
  174. }
  175. }
  176. }else{
  177. buff->width = buff->height = buff->bit = 0;
  178. if (lua_isinteger(L, 2)){
  179. memset(buff->addr, luaL_checkinteger(L, 2) % 0x100, len);
  180. }
  181. else if (lua_isstring(L, 2)){
  182. const char *data = luaL_optlstring(L, 2, "", &len);
  183. if (len > buff->len) len = buff->len; //防止越界
  184. memcpy(buff->addr, data, len);
  185. buff->cursor = len;
  186. }else{
  187. memset(buff->addr, 0, len);
  188. }
  189. }
  190. luaL_setmetatable(L, LUAT_ZBUFF_TYPE);
  191. return 1;
  192. }
  193. /**
  194. zbuff写数据(从当前指针位置开始;执行后指针会向后移动)
  195. @api buff:write(para,...)
  196. @any 写入buff的数据,string时为一个参数,number时可为多个参数
  197. @return number 数据成功写入的长度
  198. @usage
  199. -- 类file的读写操作
  200. local len = buff:write("123") -- 写入数据, 指针相应地往后移动,返回写入的数据长度
  201. local len = buff:write(0x1a,0x30,0x31,0x32,0x00,0x01) -- 按数值写入多个字节数据
  202. */
  203. static int l_zbuff_write(lua_State *L)
  204. {
  205. if (lua_isinteger(L, 2))
  206. {
  207. int len = 0;
  208. int data = 0;
  209. luat_zbuff_t *buff = tozbuff(L);
  210. while (lua_isinteger(L, 2 + len) && buff->cursor < buff->len)
  211. {
  212. data = luaL_checkinteger(L, 2 + len);
  213. *(uint8_t *)(buff->addr + buff->cursor) = data % 0x100;
  214. buff->cursor++;
  215. len++;
  216. }
  217. lua_pushinteger(L, len);
  218. return 1;
  219. }
  220. else
  221. {
  222. size_t len;
  223. const char *data = luaL_checklstring(L, 2, &len);
  224. luat_zbuff_t *buff = tozbuff(L);
  225. if (len + buff->cursor > buff->len) //防止越界
  226. {
  227. len = buff->len - buff->cursor;
  228. }
  229. memcpy(buff->addr + buff->cursor, data, len);
  230. buff->cursor = buff->cursor + len;
  231. lua_pushinteger(L, len);
  232. return 1;
  233. }
  234. }
  235. /**
  236. zbuff读数据(从当前指针位置开始;执行后指针会向后移动)
  237. @api buff:read(length)
  238. @int 读取buff中的字节数
  239. @return string 读取结果
  240. @usage
  241. -- 类file的读写操作
  242. local str = buff:read(3)
  243. */
  244. static int l_zbuff_read(lua_State *L)
  245. {
  246. luat_zbuff_t *buff = tozbuff(L);
  247. int read_num = luaL_optinteger(L, 2, 1);
  248. if (read_num > buff->len - buff->cursor) //防止越界
  249. {
  250. read_num = buff->len - buff->cursor;
  251. }
  252. if (read_num <= 0)
  253. {
  254. lua_pushlstring(L, NULL, 0);
  255. return 1;
  256. }
  257. char *return_str = (char *)luat_heap_opt_malloc(buff->type,read_num);
  258. if (return_str == NULL)
  259. {
  260. return 0;
  261. }
  262. memcpy(return_str, buff->addr + buff->cursor, read_num);
  263. lua_pushlstring(L, return_str, read_num);
  264. buff->cursor += read_num;
  265. luat_heap_opt_free(buff->type, return_str);
  266. return 1;
  267. }
  268. /**
  269. zbuff清空数据(与当前指针位置无关;执行后指针位置不变)
  270. @api buff:clear(num)
  271. @int 可选,默认为0。要设置为的值,不会改变buff指针位置
  272. @usage
  273. -- 全部初始化为0
  274. buff:clear(0)
  275. */
  276. static int l_zbuff_clear(lua_State *L)
  277. {
  278. luat_zbuff_t *buff = tozbuff(L);
  279. int num = luaL_optinteger(L, 2, 0);
  280. memset(buff->addr, num % 0x100, buff->len);
  281. return 0;
  282. }
  283. /**
  284. zbuff设置光标位置(可能与当前指针位置有关;执行后指针会被设置到指定位置)
  285. @api buff:seek(offset, base)
  286. @int 偏移长度
  287. @int where, 基点,默认zbuff.SEEK_SET。zbuff.SEEK_SET: 基点为 0 (文件开头),zbuff.SEEK_CUR: 基点为当前位置,zbuff.SEEK_END: 基点为文件尾
  288. @return int 设置光标后从buff开头计算起的光标的位置
  289. @usage
  290. buff:seek(0) -- 把光标设置到指定位置
  291. buff:seek(5,zbuff.SEEK_CUR)
  292. buff:seek(-3,zbuff.SEEK_END)
  293. */
  294. static int l_zbuff_seek(lua_State *L)
  295. {
  296. luat_zbuff_t *buff = tozbuff(L);
  297. int offset = luaL_checkinteger(L, 2);
  298. int whence = luaL_optinteger(L, 3, ZBUFF_SEEK_SET);
  299. switch (whence)
  300. {
  301. case ZBUFF_SEEK_SET:
  302. break;
  303. case ZBUFF_SEEK_CUR:
  304. offset = buff->cursor + offset;
  305. break;
  306. case ZBUFF_SEEK_END:
  307. offset = buff->len + offset;
  308. break;
  309. default:
  310. return 0;
  311. }
  312. if (offset <= 0)
  313. offset = 0;
  314. if (offset > buff->len)
  315. offset = buff->len;
  316. buff->cursor = offset;
  317. lua_pushinteger(L, buff->cursor);
  318. return 1;
  319. }
  320. //code from https://github.com/LuaDist/lpack/blob/master/lpack.c
  321. #define OP_STRING 'A'
  322. #define OP_FLOAT 'f'
  323. #define OP_DOUBLE 'd'
  324. #define OP_NUMBER 'n'
  325. #define OP_CHAR 'c'
  326. #define OP_BYTE 'b'
  327. #define OP_SHORT 'h'
  328. #define OP_USHORT 'H'
  329. #define OP_INT 'i'
  330. #define OP_UINT 'I'
  331. #define OP_LONG 'l'
  332. #define OP_ULONG 'L'
  333. #define OP_LITTLEENDIAN '<'
  334. #define OP_BIGENDIAN '>'
  335. #define OP_NATIVE '='
  336. #define isdigit(c) ((c) >= '0' && (c) <= '9')
  337. static void badcode(lua_State *L, int c)
  338. {
  339. char s[]="bad code `?'";
  340. s[sizeof(s)-3]=c;
  341. luaL_argerror(L,1,s);
  342. }
  343. static int doendian(int c)
  344. {
  345. int x=1;
  346. int e=*(char*)&x;
  347. if (c==OP_LITTLEENDIAN) return !e;
  348. if (c==OP_BIGENDIAN) return e;
  349. if (c==OP_NATIVE) return 0;
  350. return 0;
  351. }
  352. static void doswap(int swap, void *p, size_t n)
  353. {
  354. if (swap)
  355. {
  356. char *a = p;
  357. int i, j;
  358. for (i = 0, j = n - 1, n = n / 2; n--; i++, j--)
  359. {
  360. char t = a[i];
  361. a[i] = a[j];
  362. a[j] = t;
  363. }
  364. }
  365. }
  366. /**
  367. 将一系列数据按照格式字符转化,并写入(从当前指针位置开始;执行后指针会向后移动)
  368. @api buff:pack(format,val1, val2,...)
  369. @string 后面数据的格式(符号含义见下面的例子)
  370. @val 传入的数据,可以为多个数据
  371. @return int 成功写入的数据长度
  372. @usage
  373. buff:pack(">IIHA", 0x1234, 0x4567, 0x12,"abcdefg") -- 按格式写入几个数据
  374. -- A string
  375. -- f float
  376. -- d double
  377. -- n Lua number
  378. -- c char
  379. -- b byte / unsignen char
  380. -- h short
  381. -- H unsigned short
  382. -- i int
  383. -- I unsigned int
  384. -- l long
  385. -- L unsigned long
  386. -- < 小端
  387. -- > 大端
  388. -- = 默认大小端
  389. -- 例子
  390. buff:pack(
  391. ">IIHA", -- 格式字符串:大端序,依次为[4字节无符号整型, 4字节无符号整型, 2字节无符号短整型, 字符串]
  392. 0x1234, -- 参数1:整数值,写入为4字节(大端:00 00 12 34)
  393. 0x4567, -- 参数2:整数值,写入为4字节(大端:00 00 45 67)
  394. 0x12, -- 参数3:整数值,写入为2字节(大端:00 12)
  395. "abcdefg" -- 参数4:字符串,写入7字节ASCII码(61 62 63 64 65 66 67)
  396. )
  397. */
  398. #define PACKNUMBER(OP, T) \
  399. case OP: \
  400. { \
  401. T a = (T)luaL_checknumber(L, i++); \
  402. doswap(swap, &a, sizeof(a)); \
  403. write_len += add_bytes(buff, (void *)&a, sizeof(a)); \
  404. break; \
  405. }
  406. #define PACKINT(OP, T) \
  407. case OP: \
  408. { \
  409. T a = (T)luaL_checkinteger(L, i++); \
  410. doswap(swap, &a, sizeof(a)); \
  411. write_len += add_bytes(buff, (void *)&a, sizeof(a)); \
  412. break; \
  413. }
  414. static int l_zbuff_pack(lua_State *L)
  415. {
  416. luat_zbuff_t *buff = tozbuff(L);
  417. int i = 3;
  418. char *f = (char *)luaL_checkstring(L, 2);
  419. int swap = 0;
  420. int write_len = 0; //已写入长度
  421. while (*f)
  422. {
  423. if (buff->cursor == buff->len) //到头了
  424. break;
  425. int c = *f++;
  426. int N = 1;
  427. if (isdigit(*f))
  428. {
  429. N = 0;
  430. while (isdigit(*f))
  431. N = 10 * N + (*f++) - '0';
  432. }
  433. while (N--)
  434. {
  435. if (buff->cursor == buff->len) //到头了
  436. break;
  437. switch (c)
  438. {
  439. case OP_LITTLEENDIAN:
  440. case OP_BIGENDIAN:
  441. case OP_NATIVE:
  442. {
  443. swap = doendian(c);
  444. N = 0;
  445. break;
  446. }
  447. case OP_STRING:
  448. {
  449. size_t l;
  450. const char *a = luaL_checklstring(L, i++, &l);
  451. write_len += add_bytes(buff, a, l);
  452. break;
  453. }
  454. PACKNUMBER(OP_NUMBER, lua_Number)
  455. PACKNUMBER(OP_DOUBLE, double)
  456. PACKNUMBER(OP_FLOAT, float)
  457. PACKINT(OP_CHAR, char)
  458. PACKINT(OP_BYTE, unsigned char)
  459. PACKINT(OP_SHORT, short)
  460. PACKINT(OP_USHORT, unsigned short)
  461. PACKINT(OP_INT, int)
  462. PACKINT(OP_UINT, unsigned int)
  463. PACKINT(OP_LONG, long)
  464. PACKINT(OP_ULONG, unsigned long)
  465. case ' ':
  466. case ',':
  467. break;
  468. default:
  469. badcode(L, c);
  470. break;
  471. }
  472. }
  473. }
  474. lua_pushinteger(L, write_len);
  475. return 1;
  476. }
  477. #define UNPACKINT(OP, T) \
  478. case OP: \
  479. { \
  480. T a; \
  481. int m = sizeof(a); \
  482. if (i + m > len) \
  483. goto done; \
  484. memcpy(&a, s + i, m); \
  485. i += m; \
  486. doswap(swap, &a, m); \
  487. lua_pushinteger(L, (lua_Integer)a); \
  488. ++n; \
  489. break; \
  490. }
  491. #define UNPACKINT8(OP,T) \
  492. case OP: \
  493. { \
  494. T a; \
  495. int m=sizeof(a); \
  496. if (i+m>len) goto done; \
  497. memcpy(&a,s+i,m); \
  498. i+=m; \
  499. doswap(swap,&a,m); \
  500. int t = (a & 0x80)?(0xffffff00+a):a;\
  501. lua_pushinteger(L,(lua_Integer)t); \
  502. ++n; \
  503. break; \
  504. }
  505. #define UNPACKNUMBER(OP, T) \
  506. case OP: \
  507. { \
  508. T a; \
  509. int m = sizeof(a); \
  510. if (i + m > len) \
  511. goto done; \
  512. memcpy(&a, s + i, m); \
  513. i += m; \
  514. doswap(swap, &a, m); \
  515. lua_pushnumber(L, (lua_Number)a); \
  516. ++n; \
  517. break; \
  518. }
  519. /**
  520. 将一系列数据按照格式字符读取出来(从当前指针位置开始;执行后指针会向后移动)
  521. @api buff:unpack(format)
  522. @string 数据的格式(符号含义见上面pack接口的例子)
  523. @return int 成功读取的数据字节长度
  524. @return any 按格式读出来的数据
  525. @usage
  526. local cnt,a,b,c,s = buff:unpack(">IIHA10") -- 按格式读取几个数据
  527. --如果全部成功读取,cnt就是4+4+2+10=20
  528. */
  529. static int l_zbuff_unpack(lua_State *L)
  530. {
  531. luat_zbuff_t *buff = tozbuff(L);
  532. char *f = (char *)luaL_checkstring(L, 2);
  533. size_t len = buff->len - buff->cursor;
  534. const char *s = (const char*)(buff->addr + buff->cursor);
  535. int i = 0;
  536. int n = 0;
  537. int swap = 0;
  538. lua_pushnil(L); //给个数占位用的
  539. while (*f)
  540. {
  541. int c = *f++;
  542. int N = 1;
  543. if (isdigit(*f))
  544. {
  545. N = 0;
  546. while (isdigit(*f))
  547. N = 10 * N + (*f++) - '0';
  548. if (N == 0 && c == OP_STRING)
  549. {
  550. lua_pushliteral(L, "");
  551. ++n;
  552. }
  553. }
  554. while (N--){
  555. if (!lua_checkstack(L, n))
  556. return luaL_error(L, "too many results to unpack");
  557. switch (c)
  558. {
  559. case OP_LITTLEENDIAN:
  560. case OP_BIGENDIAN:
  561. case OP_NATIVE:
  562. {
  563. swap = doendian(c);
  564. N = 0;
  565. break;
  566. }
  567. case OP_STRING:
  568. {
  569. ++N;
  570. if (i + N > len)
  571. goto done;
  572. lua_pushlstring(L, s + i, N);
  573. i += N;
  574. ++n;
  575. N = 0;
  576. break;
  577. }
  578. UNPACKNUMBER(OP_NUMBER, lua_Number)
  579. UNPACKNUMBER(OP_DOUBLE, double)
  580. UNPACKNUMBER(OP_FLOAT, float)
  581. UNPACKINT8(OP_CHAR, char)
  582. UNPACKINT(OP_BYTE, unsigned char)
  583. UNPACKINT(OP_SHORT, short)
  584. UNPACKINT(OP_USHORT, unsigned short)
  585. UNPACKINT(OP_INT, int)
  586. UNPACKINT(OP_UINT, unsigned int)
  587. UNPACKINT(OP_LONG, long)
  588. UNPACKINT(OP_ULONG, unsigned long)
  589. case ' ':
  590. case ',':
  591. break;
  592. default:
  593. badcode(L, c);
  594. break;
  595. }
  596. }
  597. }
  598. done:
  599. buff->cursor += i;
  600. lua_pushinteger(L, i);
  601. lua_replace(L, -n - 2);
  602. return n + 1;
  603. }
  604. /**
  605. 读取一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动)
  606. @api buff:read类型()
  607. @注释 读取类型可为:I8、U8、I16、U16、I32、U32、I64、U64、F32、F64
  608. @return number 读取的数据,如果越界则为nil
  609. @usage
  610. local data = buff:readI8()
  611. local data = buff:readU32()
  612. */
  613. #define zread(n, t, f) \
  614. static int l_zbuff_read_##n(lua_State *L) \
  615. { \
  616. luat_zbuff_t *buff = tozbuff(L); \
  617. if (buff->len - buff->cursor < sizeof(t)) \
  618. return 0; \
  619. t tmp; \
  620. memcpy(&tmp, buff->addr + buff->cursor, sizeof(t)); \
  621. lua_push##f(L, tmp); \
  622. buff->cursor += sizeof(t); \
  623. return 1; \
  624. }
  625. zread(i8, int8_t, integer);
  626. zread(u8, uint8_t, integer);
  627. zread(i16, int16_t, integer);
  628. zread(u16, uint16_t, integer);
  629. zread(i32, int32_t, integer);
  630. zread(u32, uint32_t, integer);
  631. zread(i64, int64_t, integer);
  632. zread(u64, uint64_t, integer);
  633. zread(f32, float, number);
  634. zread(f64, double, number);
  635. /**
  636. 写入一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动)
  637. @api buff:write类型()
  638. @number 待写入的数据
  639. @注释 写入类型可为:I8、U8、I16、U16、I32、U32、I64、U64、F32、F64
  640. @return number 成功写入的长度
  641. @usage
  642. local len = buff:writeI8(10)
  643. local len = buff:writeU32(1024)
  644. */
  645. #define zwrite(n, t, f) \
  646. static int l_zbuff_write_##n(lua_State *L) \
  647. { \
  648. luat_zbuff_t *buff = tozbuff(L); \
  649. if (buff->len - buff->cursor < sizeof(t)) \
  650. { \
  651. lua_pushinteger(L, 0); \
  652. return 1; \
  653. } \
  654. t tmp = (t)luaL_check##f(L, 2); \
  655. memcpy(buff->addr + buff->cursor, &(tmp), sizeof(t)); \
  656. buff->cursor += sizeof(t); \
  657. lua_pushinteger(L, sizeof(t)); \
  658. return 1; \
  659. }
  660. zwrite(i8, int8_t, integer);
  661. zwrite(u8, uint8_t, integer);
  662. zwrite(i16, int16_t, integer);
  663. zwrite(u16, uint16_t, integer);
  664. zwrite(i32, int32_t, integer);
  665. zwrite(u32, uint32_t, integer);
  666. zwrite(i64, int64_t, integer);
  667. zwrite(u64, uint64_t, integer);
  668. zwrite(f32, float, number);
  669. zwrite(f64, double, number);
  670. /**
  671. 按起始位置和长度取出数据(与当前指针位置无关;执行后指针位置不变)
  672. @api buff:toStr(offset,length)
  673. @int 数据的起始位置(起始位置为0),默认值也是0
  674. @int 数据的长度,默认是全部数据
  675. @return string 读出来的数据
  676. @usage
  677. local s = buff:toStr(0,5)--读取开头的五个字节数据
  678. local s = buff:toStr() -- 取出整个zbuff的数据
  679. local s = buff:toStr(0, buff:used()) -- 取出已使用的部分, 与buff:query()一样
  680. */
  681. static int l_zbuff_toStr(lua_State *L)
  682. {
  683. luat_zbuff_t *buff = tozbuff(L);
  684. int start = luaL_optinteger(L, 2, 0);
  685. if (start > buff->len)
  686. start = buff->len;
  687. int len = luaL_optinteger(L, 3, buff->len);
  688. if (start + len > buff->len)
  689. len = buff->len - start;
  690. lua_pushlstring(L, (const char*)(buff->addr + start), len);
  691. return 1;
  692. }
  693. /**
  694. 获取zbuff对象的长度(与当前指针位置无关;执行后指针位置不变)
  695. @api buff:len()
  696. @return int zbuff对象的长度
  697. @usage
  698. len = buff:len()
  699. len = #buff
  700. */
  701. static int l_zbuff_len(lua_State *L)
  702. {
  703. luat_zbuff_t *buff = tozbuff(L);
  704. lua_pushinteger(L, buff->len);
  705. return 1;
  706. }
  707. /**
  708. 设置buff对象的FrameBuffer属性(与当前指针位置无关;执行后指针位置不变)
  709. @api buff:setFrameBuffer(width,height,bit,color)
  710. @int FrameBuffer的宽度
  711. @int FrameBuffer的高度
  712. @int FrameBuffer的色位深度
  713. @int FrameBuffer的初始颜色
  714. @return bool 设置成功会返回true
  715. @usage
  716. result = buff:setFrameBuffer(320,240,16,0xffff)
  717. */
  718. static int l_zbuff_set_frame_buffer(lua_State *L)
  719. {
  720. luat_zbuff_t *buff = tozbuff(L);
  721. //检查空间够不够
  722. if((luaL_checkinteger(L, 2) * luaL_checkinteger(L, 3) * luaL_checkinteger(L, 4) - 1) / 8 + 1 > buff->len)
  723. return 0;
  724. buff->width = luaL_checkinteger(L,2);
  725. buff->height = luaL_checkinteger(L,3);
  726. buff->bit = luaL_checkinteger(L,4);
  727. if (lua_isinteger(L, 5))
  728. {
  729. LUA_INTEGER color = luaL_checkinteger(L, 5);
  730. uint32_t i;
  731. for (i = 0; i < buff->width * buff->height; i++)
  732. set_framebuffer_point(buff, i, color);
  733. }
  734. lua_pushboolean(L,1);
  735. return 1;
  736. }
  737. /**
  738. 设置或获取FrameBuffer某个像素点的颜色(与当前指针位置无关;执行后指针位置不变)
  739. @api buff:pixel(x,y,color)
  740. @int 与最左边的距离,范围是0~宽度-1
  741. @int 与最上边的距离,范围是0~高度-1
  742. @int 颜色,如果留空则表示获取该位置的颜色
  743. @return any 设置颜色时,设置成功会返回true;读取颜色时,返回颜色的值,读取失败返回nil
  744. @usage
  745. rerult = buff:pixel(0,3,0)
  746. color = buff:pixel(0,3)
  747. */
  748. static int l_zbuff_pixel(lua_State *L)
  749. {
  750. luat_zbuff_t *buff = tozbuff(L);
  751. uint32_t x = luaL_checkinteger(L,2);
  752. uint32_t y = luaL_checkinteger(L,3);
  753. if(x>=buff->width||y>=buff->height)
  754. return 0;
  755. if (lua_isinteger(L, 4))
  756. {
  757. LUA_INTEGER color = luaL_checkinteger(L, 4);
  758. set_framebuffer_point(buff, x + y * buff->width, color);
  759. lua_pushboolean(L,1);
  760. return 1;
  761. }
  762. else
  763. {
  764. lua_pushinteger(L,get_framebuffer_point(buff,x + y * buff->width));
  765. return 1;
  766. }
  767. }
  768. /**
  769. 画一条线(与当前指针位置无关;执行后指针位置不变)
  770. @api buff:drawLine(x1,y1,x2,y2,color)
  771. @int 起始坐标点与最左边的距离,范围是0~宽度-1
  772. @int 起始坐标点与最上边的距离,范围是0~高度-1
  773. @int 结束坐标点与最左边的距离,范围是0~宽度-1
  774. @int 结束坐标点与最上边的距离,范围是0~高度-1
  775. @int 可选,颜色,默认为0
  776. @return bool 画成功会返回true
  777. @usage
  778. rerult = buff:drawLine(0,0,2,3,0xffff)
  779. */
  780. #define abs(n) (n>0?n:-n)
  781. static int l_zbuff_draw_line(lua_State *L)
  782. {
  783. luat_zbuff_t *buff = tozbuff(L);
  784. if(buff->width<=0) return 0;//不是framebuffer数据
  785. uint32_t x0 = luaL_checkinteger(L,2);
  786. uint32_t y0 = luaL_checkinteger(L,3);
  787. uint32_t x1 = luaL_checkinteger(L,4);
  788. uint32_t y1 = luaL_checkinteger(L,5);
  789. uint32_t color = luaL_optinteger(L,6,0);
  790. //代码参考https://blog.csdn.net/qq_43405938/article/details/102700922
  791. int x = x0, y = y0, dx = x1 - x0, dy = y1 - y0;
  792. int max = (abs(dy) > abs(dx)) ? abs(dy) : abs(dx);
  793. int min = (abs(dy) > abs(dx)) ? abs(dx) : abs(dy);
  794. float e = 2 * min - max;
  795. for (int i = 0; i < max; i++)
  796. {
  797. if(x>=0&&y>=0&&x<buff->width&&y<buff->height)
  798. set_framebuffer_point(buff,x+y*buff->width,color);
  799. if (e >= 0)
  800. {
  801. e = e - 2 * max;
  802. (abs(dy) > abs(dx)) ? (dx >= 0 ? x++ : x--) : (dy >= 0 ? y++ : y--);
  803. }
  804. e += 2 * min;
  805. (abs(dy) > abs(dx)) ? (dy >= 0 ? y++ : y--) : (dx >= 0 ? x++ : x--);
  806. }
  807. lua_pushboolean(L,1);
  808. return 1;
  809. }
  810. /**
  811. 画一个矩形(与当前指针位置无关;执行后指针位置不变)
  812. @api buff:drawRect(x1,y1,x2,y2,color,fill)
  813. @int 起始坐标点与最左边的距离,范围是0~宽度-1
  814. @int 起始坐标点与最上边的距离,范围是0~高度-1
  815. @int 结束坐标点与最左边的距离,范围是0~宽度-1
  816. @int 结束坐标点与最上边的距离,范围是0~高度-1
  817. @int 可选,颜色,默认为0
  818. @bool 可选,是否在内部填充,默认nil
  819. @return bool 画成功会返回true
  820. @usage
  821. rerult = buff:drawRect(0,0,2,3,0xffff)
  822. */
  823. #define CHECK0(n,max) if(n<0)n=0;if(n>=max)n=max-1
  824. static int l_zbuff_draw_rectangle(lua_State *L)
  825. {
  826. luat_zbuff_t *buff = tozbuff(L);
  827. if(buff->width<=0) return 0;//不是framebuffer数据
  828. int32_t x1 = (int32_t)luaL_checkinteger(L,2); CHECK0(x1,buff->width);
  829. int32_t y1 = (int32_t)luaL_checkinteger(L,3); CHECK0(y1,buff->height);
  830. int32_t x2 = (int32_t)luaL_checkinteger(L,4); CHECK0(x2,buff->width);
  831. int32_t y2 = (int32_t)luaL_checkinteger(L,5); CHECK0(y2,buff->height);
  832. int32_t color = (int32_t)luaL_optinteger(L,6,0);
  833. uint8_t fill = lua_toboolean(L,7);
  834. int x,y;
  835. int32_t xmax=x1>x2?x1:x2,xmin=x1>x2?x2:x1,ymax=y1>y2?y1:y2,ymin=y1>y2?y2:y1;
  836. if(fill){
  837. for(x=xmin;x<=xmax;x++)
  838. for(y=ymin;y<=ymax;y++)
  839. set_framebuffer_point(buff,x+y*buff->width,color);
  840. }else{
  841. for(x=xmin;x<=xmax;x++){
  842. set_framebuffer_point(buff,x+ymin*buff->width,color);
  843. set_framebuffer_point(buff,x+ymax*buff->width,color);
  844. }
  845. for(y=ymin;y<=ymax;y++){
  846. set_framebuffer_point(buff,xmin+y*buff->width,color);
  847. set_framebuffer_point(buff,xmax+y*buff->width,color);
  848. }
  849. }
  850. lua_pushboolean(L,1);
  851. return 1;
  852. }
  853. /**
  854. 画一个圆形(与当前指针位置无关;执行后指针位置不变)
  855. @api buff:drawCircle(x,y,r,color,fill)
  856. @int **圆心**与最左边的距离,范围是0~宽度-1
  857. @int **圆心**与最上边的距离,范围是0~高度-1
  858. @int 圆的半径
  859. @int 可选,圆的颜色,默认为0
  860. @bool 可选,是否在内部填充,默认nil
  861. @return bool 画成功会返回true
  862. @usage
  863. rerult = buff:drawCircle(15,5,3,0xC)
  864. rerult = buff:drawCircle(15,5,3,0xC,true)
  865. */
  866. #define DRAW_CIRCLE_ALL(buff, xc, yc, x, y, c) \
  867. { \
  868. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  869. set_framebuffer_point(buff, (xc + x) + (yc + y) * buff->width, c); \
  870. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  871. set_framebuffer_point(buff, (xc - x) + (yc + y) * buff->width, c); \
  872. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  873. set_framebuffer_point(buff, (xc + x) + (yc - y) * buff->width, c); \
  874. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  875. set_framebuffer_point(buff, (xc - x) + (yc - y) * buff->width, c); \
  876. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  877. set_framebuffer_point(buff, (xc + y) + (yc + x) * buff->width, c); \
  878. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  879. set_framebuffer_point(buff, (xc - y) + (yc + x) * buff->width, c); \
  880. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  881. set_framebuffer_point(buff, (xc + y) + (yc - x) * buff->width, c); \
  882. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  883. set_framebuffer_point(buff, (xc - y) + (yc - x) * buff->width, c); \
  884. }
  885. static int l_zbuff_draw_circle(lua_State *L)
  886. {
  887. luat_zbuff_t *buff = tozbuff(L);
  888. if(buff->width<=0) return 0;//不是framebuffer数据
  889. int32_t xc = luaL_checkinteger(L,2);
  890. int32_t yc = luaL_checkinteger(L,3);
  891. int32_t r = luaL_checkinteger(L,4);
  892. int32_t color = luaL_optinteger(L,5,0);
  893. uint8_t fill = lua_toboolean(L,6);
  894. //代码参考https://www.cnblogs.com/wlzy/p/8695226.html
  895. //圆不在可见区域
  896. if (xc + r < 0 || xc - r >= buff->width || yc + r < 0 || yc - r >= buff->height)
  897. return 0;
  898. int x = 0, y = r, yi, d;
  899. d = 3 - 2 * r;
  900. while (x <= y)
  901. {
  902. if (fill)
  903. {
  904. for (yi = x; yi <= y; yi++)
  905. DRAW_CIRCLE_ALL(buff, xc, yc, x, yi, color);
  906. }
  907. else
  908. {
  909. DRAW_CIRCLE_ALL(buff, xc, yc, x, y, color);
  910. }
  911. if (d < 0)
  912. {
  913. d = d + 4 * x + 6;
  914. }
  915. else
  916. {
  917. d = d + 4 * (x - y) + 10;
  918. y--;
  919. }
  920. x++;
  921. }
  922. lua_pushboolean(L,1);
  923. return 1;
  924. }
  925. /**
  926. 以下标形式进行数据读写(与当前指针位置无关;执行后指针位置不变)
  927. @api buff[n]
  928. @int 第几个数据,以0开始的下标(C标准)
  929. @return number 该位置的数据
  930. @usage
  931. buff[0] = 0xc8
  932. local data = buff[0]
  933. */
  934. static int l_zbuff_index(lua_State *L)
  935. {
  936. //luat_zbuff_t **pp = luaL_checkudata(L, 1, LUAT_ZBUFF_TYPE);
  937. // int i;
  938. luaL_getmetatable(L, LUAT_ZBUFF_TYPE);
  939. lua_pushvalue(L, 2);
  940. lua_rawget(L, -2);
  941. if (lua_isnil(L, -1))
  942. {
  943. /* found no method, so get value from userdata. */
  944. luat_zbuff_t *buff = tozbuff(L);
  945. int o = luaL_checkinteger(L, 2);
  946. if (o >= buff->len)
  947. return 0;
  948. lua_pushinteger(L, buff->addr[o]);
  949. return 1;
  950. };
  951. return 1;
  952. }
  953. static int l_zbuff_newindex(lua_State *L)
  954. {
  955. if (lua_isinteger(L, 2))
  956. {
  957. luat_zbuff_t *buff = tozbuff(L);
  958. if (lua_isinteger(L, 2))
  959. {
  960. int o = luaL_checkinteger(L, 2);
  961. int n = luaL_checkinteger(L, 3) % 256;
  962. if (o > buff->len)
  963. return 0;
  964. buff->addr[o] = n;
  965. }
  966. }
  967. return 0;
  968. }
  969. // __gc l_zbuff_gc为zbuff默认gc函数,gc调用时会释放申请内存并gc掉zbuff,下面为用户手动调用注释
  970. /**
  971. 释放zbuff所申请内存 注意:gc时会自动释放zbuff以及zbuff所申请内存,所以通常无需调用此函数,调用前请确认您已清楚此函数用处!调用此函数并不会释放掉zbuff,仅会释放掉zbuff所申请的内存,zbuff需等gc时自动释放!!!
  972. @api buff:free()
  973. @usage
  974. buff:free()
  975. */
  976. static int l_zbuff_gc(lua_State *L)
  977. {
  978. luat_zbuff_t *buff = tozbuff(L);
  979. if (buff->addr){
  980. luat_heap_opt_free(buff->type,buff->addr);
  981. buff->addr = NULL;
  982. buff->len = 0;
  983. buff->used = 0;
  984. }
  985. return 0;
  986. }
  987. int __zbuff_resize(luat_zbuff_t *buff, uint32_t new_size)
  988. {
  989. void *p = luat_heap_opt_realloc(buff->type, buff->addr, new_size?new_size:1);
  990. if (p)
  991. {
  992. buff->addr = p;
  993. buff->len = new_size;
  994. buff->used = (buff->len > buff->used)?buff->used:buff->len;
  995. return 0;
  996. }
  997. else
  998. {
  999. LLOGE("zbuff realloc failed %d -> %d", buff->len, new_size);
  1000. return -1;
  1001. }
  1002. }
  1003. /**
  1004. 调整zbuff实际分配空间的大小,类似于realloc的效果,new = realloc(old, n),可以扩大或者缩小(如果缩小后len小于了used,那么used=新len)
  1005. @api buff:resize(n)
  1006. @int 新空间大小
  1007. @usage
  1008. buff:resize(20)
  1009. */
  1010. static int l_zbuff_resize(lua_State *L)
  1011. {
  1012. luat_zbuff_t *buff = tozbuff(L);
  1013. if (lua_isinteger(L, 2))
  1014. {
  1015. uint32_t n = luaL_checkinteger(L, 2);
  1016. __zbuff_resize(buff, n);
  1017. }
  1018. return 0;
  1019. }
  1020. /**
  1021. zbuff动态写数据,类似于memcpy效果,当原有空间不足时动态扩大空间
  1022. @api buff:copy(start, para,...)
  1023. @int 写入buff的起始位置,如果不为数字,则为buff的used,如果小于0,则从used往前数,-1 = used - 1
  1024. @any 写入buff的数据,string或zbuff者时为一个参数,number时可为多个参数
  1025. @return number 数据成功写入的长度
  1026. @usage
  1027. local len = buff:copy(nil, "123") -- 类似于memcpy(&buff[used], "123", 3) used+= 3 从buff开始写入数据,指针相应地往后移动
  1028. local len = buff:copy(0, "123") -- 类似于memcpy(&buff[0], "123", 3) if (used < 3) used = 3 从位置0写入数据,指针有可能会移动
  1029. local len = buff:copy(2, 0x1a,0x30,0x31,0x32,0x00,0x01) -- 类似于memcpy(&buff[2], [0x1a,0x30,0x31,0x32,0x00,0x01], 6) if (used < (2+6)) used = (2+6)从位置2开始,按数值写入多个字节数据
  1030. local len = buff:copy(9, buff2) -- 类似于memcpy(&buff[9], &buff2[0], buff2的used) if (used < (9+buff2的used)) used = (9+buff2的used) 从位置9开始,合并入buff2里0~used的内容
  1031. local len = buff:copy(5, buff2, 10, 1024) -- 类似于memcpy(&buff[5], &buff2[10], 1024) if (used < (5+1024)) used = (5+1024)
  1032. */
  1033. static int l_zbuff_copy(lua_State *L)
  1034. {
  1035. luat_zbuff_t *buff = tozbuff(L);
  1036. int temp_cursor = luaL_optinteger(L, 2, buff->used);
  1037. if (temp_cursor < 0)
  1038. {
  1039. temp_cursor = buff->used + temp_cursor;
  1040. if (temp_cursor < 0)
  1041. {
  1042. lua_pushinteger(L, 0);
  1043. return 1;
  1044. }
  1045. }
  1046. if (lua_isinteger(L, 3))
  1047. {
  1048. int len = 0;
  1049. int data = 0;
  1050. while (lua_isinteger(L, 3 + len))
  1051. {
  1052. if (temp_cursor > buff->len)
  1053. {
  1054. if (__zbuff_resize(buff, temp_cursor * 2))
  1055. {
  1056. lua_pushinteger(L, len);
  1057. return 1;
  1058. }
  1059. }
  1060. data = luaL_checkinteger(L, 3 + len);
  1061. *(uint8_t *)(buff->addr + temp_cursor) = data % 0x100;
  1062. temp_cursor++;
  1063. len++;
  1064. }
  1065. buff->used = (temp_cursor > buff->used)?temp_cursor:buff->used;
  1066. lua_pushinteger(L, len);
  1067. return 1;
  1068. }
  1069. else if (lua_isstring(L, 3))
  1070. {
  1071. size_t len;
  1072. const char *data = luaL_checklstring(L, 3, &len);
  1073. if (len + temp_cursor > buff->len) //防止越界
  1074. {
  1075. if (__zbuff_resize(buff, buff->len + len + temp_cursor))
  1076. {
  1077. lua_pushinteger(L, 0);
  1078. return 1;
  1079. }
  1080. }
  1081. memcpy(buff->addr + temp_cursor, data, len);
  1082. temp_cursor = temp_cursor + len;
  1083. buff->used = (temp_cursor > buff->used)?temp_cursor:buff->used;
  1084. lua_pushinteger(L, len);
  1085. return 1;
  1086. }
  1087. else if (lua_isuserdata(L, 3))
  1088. {
  1089. luat_zbuff_t *copy_buff = ((luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE));
  1090. uint32_t start = luaL_optinteger(L, 4, 0);
  1091. uint32_t len = luaL_optinteger(L, 5, copy_buff->used);
  1092. if (len + temp_cursor > buff->len) //防止越界
  1093. {
  1094. if (__zbuff_resize(buff, buff->len + len + temp_cursor))
  1095. {
  1096. lua_pushinteger(L, 0);
  1097. return 1;
  1098. }
  1099. }
  1100. memcpy(buff->addr + temp_cursor, copy_buff->addr + start, len);
  1101. temp_cursor += len;
  1102. buff->used = (temp_cursor > buff->used)?temp_cursor:buff->used;
  1103. lua_pushinteger(L, len);
  1104. return 1;
  1105. }
  1106. lua_pushinteger(L, 0);
  1107. return 1;
  1108. }
  1109. /**
  1110. 设置/获取zbuff里最后一个数据位置指针到首地址的偏移量,来表示zbuff内已有有效数据量大小,注意这个不同于分配的空间大小,由于seek()会改变最后一个数据位置指针,因此也会影响到used()返回值。
  1111. @api buff:used()
  1112. @int 最后一个数据位置指针到首地址的偏移量,不能是负数,如果不填则不更改当前值,如果该值超过了buff总量,则自动改为buff总量
  1113. @return int 有效数据量大小
  1114. @usage
  1115. buff:used() --直接返回当前的有效数据量大小
  1116. buff:used(123) --设置当前的有效数据量为123字节,如果buff本身不到123字节,比如120字节,则会改成120,返回值是120
  1117. */
  1118. static int l_zbuff_used(lua_State *L)
  1119. {
  1120. luat_zbuff_t *buff = tozbuff(L);
  1121. if (lua_isinteger(L, 2))
  1122. {
  1123. size_t temp_cursor = luaL_optinteger(L, 2, buff->used);
  1124. if (temp_cursor > buff->len)
  1125. {
  1126. buff->used = buff->len;
  1127. }
  1128. else
  1129. {
  1130. buff->used = temp_cursor;
  1131. }
  1132. }
  1133. lua_pushinteger(L, buff->used);
  1134. return 1;
  1135. }
  1136. /**
  1137. 删除zbuff 0~used范围内的一段数据,注意只是改变了used的值,并不是真的在ram里去清除掉数据
  1138. @api buff:del(offset,length)
  1139. @int 起始位置start, 默认0,如果<0则从used往前数,比如 -1 那么start= used - 1
  1140. @int 长度del_len,默认为used,如果start + del_len数值大于used,会强制调整del_len = used - start
  1141. @usage
  1142. buff:del(1,4) --从位置1开始删除4个字节数据
  1143. buff:del(-1,4) --从位置used-1开始删除4个字节数据,但是这肯定会超过used,所以del_len会调整为1,实际上就是删掉了最后一个字节
  1144. */
  1145. static int l_zbuff_del(lua_State *L)
  1146. {
  1147. luat_zbuff_t *buff = tozbuff(L);
  1148. int start = luaL_optinteger(L, 2, 0);
  1149. if (start < 0)
  1150. {
  1151. start += buff->used;
  1152. if (start < 0)
  1153. {
  1154. return 0;
  1155. }
  1156. }
  1157. if (start >= (int)buff->used)
  1158. return 0;
  1159. uint32_t len = luaL_optinteger(L, 3, buff->used);
  1160. if (start + len > buff->used)
  1161. len = buff->used - start;
  1162. if (!len)
  1163. {
  1164. return 0;
  1165. }
  1166. if ((start + len) == buff->used)
  1167. {
  1168. buff->used = start;
  1169. }
  1170. else
  1171. {
  1172. uint32_t rest = buff->used - len;
  1173. memmove(buff->addr + start, buff->addr + start + len, rest);
  1174. buff->used = rest;
  1175. }
  1176. return 0;
  1177. }
  1178. static uint32_t BytesGetBe32(const void *ptr)
  1179. {
  1180. const uint8_t *p = (const uint8_t *)ptr;
  1181. return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
  1182. }
  1183. static uint32_t BytesGetLe32(const void *ptr)
  1184. {
  1185. const uint8_t *p = (const uint8_t *)ptr;
  1186. return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
  1187. }
  1188. /**
  1189. 按起始位置和长度0~used范围内取出数据,如果是1,2,4,8字节,且填写了isbigend参数,则根据isbigend,issigned,isfloat转换成浮点或者整形
  1190. @api buff:query(offset,length,isbigend,issigned,isfloat)
  1191. @int 数据的起始位置(起始位置为0)
  1192. @int 数据的长度
  1193. @boolean 是否是大端格式,如果为nil,则不会转换,直接字节流输出,false为小端格式,true为大端格式
  1194. @boolean 是否是有符号的,默认为false
  1195. @boolean 是否是浮点型,默认为false
  1196. @return string 读出来的数据,如果取出数据是1,2,4,8字节,且isbigend填写了true或者false,则输出浮点或者整形
  1197. @usage
  1198. local s = buff:query(0,5)--读取开头的五个字节数据
  1199. */
  1200. static int l_zbuff_query(lua_State *L)
  1201. {
  1202. luat_zbuff_t *buff = tozbuff(L);
  1203. int start = luaL_optinteger(L, 2, 0);
  1204. if (start < 0)
  1205. {
  1206. start += buff->used;
  1207. if (start < 0)
  1208. {
  1209. lua_pushnil(L);
  1210. return 1;
  1211. }
  1212. }
  1213. if (start > buff->used)
  1214. start = buff->used;
  1215. uint32_t len = luaL_optinteger(L, 3, buff->used);
  1216. if (start + len > buff->used)
  1217. len = buff->used - start;
  1218. if (!len)
  1219. {
  1220. lua_pushnil(L);
  1221. return 1;
  1222. }
  1223. if (lua_isboolean(L, 4) && (len <= 8))
  1224. {
  1225. int is_bigend = lua_toboolean(L, 4);
  1226. int is_float = 0;
  1227. int is_signed = 0;
  1228. if (lua_isboolean(L, 5))
  1229. {
  1230. is_signed = lua_toboolean(L, 5);
  1231. }
  1232. if (lua_isboolean(L, 6))
  1233. {
  1234. is_float = lua_toboolean(L, 6);
  1235. }
  1236. uint8_t *p = buff->addr + start;
  1237. uint8_t uc;
  1238. int16_t s;
  1239. uint16_t us;
  1240. int32_t i;
  1241. // uint32_t ui;
  1242. int64_t l;
  1243. float f;
  1244. double d;
  1245. switch(len)
  1246. {
  1247. case 1:
  1248. if (is_signed)
  1249. {
  1250. i = (p[0] & 0x80)?(p[0] + 0xffffff00):p[0];
  1251. lua_pushinteger(L, i);
  1252. }
  1253. else
  1254. {
  1255. uc = p[0];
  1256. lua_pushinteger(L, uc);
  1257. }
  1258. break;
  1259. case 2:
  1260. if (is_bigend)
  1261. {
  1262. us = (p[0] << 8) | p[1];
  1263. }
  1264. else
  1265. {
  1266. us = (p[1] << 8) | p[0];
  1267. }
  1268. if (is_signed)
  1269. {
  1270. s = us;
  1271. lua_pushinteger(L, s);
  1272. }
  1273. else
  1274. {
  1275. lua_pushinteger(L, us);
  1276. }
  1277. break;
  1278. case 4:
  1279. if (is_float)
  1280. {
  1281. memcpy(&f, p, len);
  1282. lua_pushnumber(L, f);
  1283. }
  1284. else
  1285. {
  1286. if (is_bigend)
  1287. {
  1288. i = BytesGetBe32(p);
  1289. }
  1290. else
  1291. {
  1292. i = BytesGetLe32(p);
  1293. }
  1294. lua_pushinteger(L, i);
  1295. }
  1296. break;
  1297. case 8:
  1298. if (is_float)
  1299. {
  1300. memcpy(&d, p, len);
  1301. lua_pushnumber(L, d);
  1302. }
  1303. else
  1304. {
  1305. if (is_bigend)
  1306. {
  1307. l = BytesGetBe32(p + 4) | ((int64_t)BytesGetBe32(p) << 32);
  1308. }
  1309. else
  1310. {
  1311. l = BytesGetLe32(p) | ((int64_t)BytesGetLe32(p + 4) << 32);
  1312. }
  1313. lua_pushinteger(L, l);
  1314. }
  1315. break;
  1316. default:
  1317. lua_pushlstring(L, (const char*)(buff->addr + start), len);
  1318. break;
  1319. }
  1320. return 1;
  1321. }
  1322. lua_pushlstring(L, (const char*)(buff->addr + start), len);
  1323. return 1;
  1324. }
  1325. /**
  1326. zbuff的类似于memset操作,类似于memset(&buff[start], num, len),当然有ram越界保护,会对len有一定的限制
  1327. @api buff:set(start, num, len)
  1328. @int 可选,开始位置,默认为0,
  1329. @int 可选,默认为0。要设置为的值
  1330. @int 可选,长度,默认为全部空间,如果超出范围了,会自动截断
  1331. @usage
  1332. -- 全部初始化为0
  1333. buff:set() --等同于 memset(buff, 0, sizeof(buff))
  1334. buff:set(8) --等同于 memset(&buff[8], 0, sizeof(buff) - 8)
  1335. buff:set(0, 0x55) --等同于 memset(buff, 0x55, sizeof(buff))
  1336. buff:set(4, 0xaa, 12) --等用于 memset(&buff[4], 0xaa, 12)
  1337. */
  1338. static int l_zbuff_set(lua_State *L)
  1339. {
  1340. luat_zbuff_t *buff = tozbuff(L);
  1341. int num = luaL_optinteger(L, 3, 0);
  1342. uint32_t start = luaL_optinteger(L, 2, 0);
  1343. uint32_t len = luaL_optinteger(L, 4, buff->len);
  1344. memset(buff->addr + start, num & 0x00ff, ((len + start) > buff->len)?(buff->len - start):len);
  1345. return 0;
  1346. }
  1347. /**
  1348. zbuff的类似于memcmp操作,类似于memcmp(&buff[start], &buff2[start2], len)
  1349. @api buff:isEqual(start, buff2, start2, len)
  1350. @int 可选,开始位置,默认为0,
  1351. @zbuff 比较的对象
  1352. @int 可选,比较的对象的开始位置,默认为0
  1353. @int 比较长度
  1354. @return boolean true相等,false不相等
  1355. @return int 相等返回0,不相等返回第一个不相等位置的序号
  1356. @usage
  1357. local result, offset = buff:isEqual(1, buff2, 2, 10) --等同于memcmp(&buff[1], &buff2[2], 10)
  1358. */
  1359. static int l_zbuff_equal(lua_State *L)
  1360. {
  1361. luat_zbuff_t *buff = tozbuff(L);
  1362. uint32_t offset1 = luaL_optinteger(L, 2, 0);
  1363. luat_zbuff_t *buff2 = ((luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE));
  1364. uint32_t offset2 = luaL_optinteger(L, 4, 0);
  1365. uint32_t len = luaL_optinteger(L, 5, 1);
  1366. uint32_t i;
  1367. uint8_t *b1 = buff->addr + offset1;
  1368. uint8_t *b2 = buff2->addr + offset2;
  1369. for(i = 0; i < len; i++) {
  1370. if (b1[i] != b2[i]) {
  1371. lua_pushboolean(L, 0);
  1372. lua_pushinteger(L, i);
  1373. return 2;
  1374. }
  1375. }
  1376. lua_pushboolean(L, 1);
  1377. lua_pushinteger(L, 0);
  1378. return 2;
  1379. }
  1380. /**
  1381. 将当前zbuff数据转base64,输出到下一个zbuff中
  1382. @api buff:toBase64(dst)
  1383. @userdata zbuff指针
  1384. @return int 转换后的实际长度
  1385. @usage
  1386. -- dst:len必须大于buff:used() * 1.35 + 3, 确保有足够空间存放base64数据
  1387. buff:toBase64(dst)
  1388. */
  1389. #include "luat_str.h"
  1390. static int l_zbuff_to_base64(lua_State *L) {
  1391. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 1, LUAT_ZBUFF_TYPE));
  1392. luat_zbuff_t *buff2 = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  1393. size_t olen = 0;
  1394. int ret = luat_str_base64_encode(buff2->addr, buff2->len, &olen, buff->addr, buff->used);
  1395. if (ret) {
  1396. LLOGE("zbuff toBase64 failed %d", ret);
  1397. lua_pushinteger(L, 0);
  1398. }
  1399. else {
  1400. buff2->used = olen;
  1401. lua_pushinteger(L, olen);
  1402. }
  1403. return 1;
  1404. };
  1405. static const luaL_Reg lib_zbuff[] = {
  1406. {"write", l_zbuff_write},
  1407. {"read", l_zbuff_read},
  1408. {"clear", l_zbuff_clear},
  1409. {"seek", l_zbuff_seek},
  1410. {"pack", l_zbuff_pack},
  1411. {"unpack", l_zbuff_unpack},
  1412. {"get", l_zbuff_index},
  1413. {"readI8", l_zbuff_read_i8},
  1414. {"readI16", l_zbuff_read_i16},
  1415. {"readI32", l_zbuff_read_i32},
  1416. {"readI64", l_zbuff_read_i64},
  1417. {"readU8", l_zbuff_read_u8},
  1418. {"readU16", l_zbuff_read_u16},
  1419. {"readU32", l_zbuff_read_u32},
  1420. {"readU64", l_zbuff_read_u64},
  1421. {"readF32", l_zbuff_read_f32},
  1422. {"readF64", l_zbuff_read_f64},
  1423. {"writeI8", l_zbuff_write_i8},
  1424. {"writeI16", l_zbuff_write_i16},
  1425. {"writeI32", l_zbuff_write_i32},
  1426. {"writeI64", l_zbuff_write_i64},
  1427. {"writeU8", l_zbuff_write_u8},
  1428. {"writeU16", l_zbuff_write_u16},
  1429. {"writeU32", l_zbuff_write_u32},
  1430. {"writeU64", l_zbuff_write_u64},
  1431. {"writeF32", l_zbuff_write_f32},
  1432. {"writeF64", l_zbuff_write_f64},
  1433. {"toStr", l_zbuff_toStr},
  1434. {"len", l_zbuff_len},
  1435. {"setFrameBuffer", l_zbuff_set_frame_buffer},
  1436. {"pixel", l_zbuff_pixel},
  1437. {"drawLine", l_zbuff_draw_line},
  1438. {"drawRect", l_zbuff_draw_rectangle},
  1439. {"drawCircle", l_zbuff_draw_circle},
  1440. //{"__index", l_zbuff_index},
  1441. //{"__len", l_zbuff_len},
  1442. //{"__newindex", l_zbuff_newindex},
  1443. {"free", l_zbuff_gc},
  1444. //以下为扩展用法,数据的增减操作尽量不要和上面的read,write一起使用,对数值指针的用法不一致
  1445. {"copy", l_zbuff_copy},
  1446. {"set", l_zbuff_set},
  1447. {"query",l_zbuff_query},
  1448. {"del", l_zbuff_del},
  1449. {"resize", l_zbuff_resize},
  1450. {"reSize", l_zbuff_resize},
  1451. {"used", l_zbuff_used},
  1452. {"isEqual", l_zbuff_equal},
  1453. {"toBase64", l_zbuff_to_base64},
  1454. {NULL, NULL}};
  1455. static int luat_zbuff_meta_index(lua_State *L) {
  1456. if (lua_isinteger(L, 2)) {
  1457. return l_zbuff_index(L);
  1458. }
  1459. if (lua_isstring(L, 2)) {
  1460. const char* keyname = luaL_checkstring(L, 2);
  1461. //printf("zbuff keyname = %s\n", keyname);
  1462. int i = 0;
  1463. while (1) {
  1464. if (lib_zbuff[i].name == NULL) break;
  1465. if (!strcmp(keyname, lib_zbuff[i].name)) {
  1466. lua_pushcfunction(L, lib_zbuff[i].func);
  1467. return 1;
  1468. }
  1469. i++;
  1470. }
  1471. }
  1472. return 0;
  1473. }
  1474. static void createmeta(lua_State *L)
  1475. {
  1476. luaL_newmetatable(L, LUAT_ZBUFF_TYPE); /* create metatable for file handles */
  1477. // lua_pushvalue(L, -1); /* push metatable */
  1478. // lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
  1479. // luaL_setfuncs(L, lib_zbuff, 0); /* add file methods to new metatable */
  1480. //luaL_setfuncs(L, lib_zbuff_metamethods, 0);
  1481. //luaL_setfuncs(L, lib_zbuff, 0);
  1482. lua_pushcfunction(L, l_zbuff_len);
  1483. lua_setfield(L, -2, "__len");
  1484. lua_pushcfunction(L, l_zbuff_gc);
  1485. lua_setfield(L, -2, "__gc");
  1486. lua_pushcfunction(L, luat_zbuff_meta_index);
  1487. lua_setfield(L, -2, "__index");
  1488. lua_pushcfunction(L, l_zbuff_newindex);
  1489. lua_setfield(L, -2, "__newindex");
  1490. lua_pop(L, 1); /* pop new metatable */
  1491. //luaL_newlib(L, lib_zbuff);
  1492. }
  1493. #include "rotable2.h"
  1494. static const rotable_Reg_t reg_zbuff[] =
  1495. {
  1496. {"create", ROREG_FUNC(l_zbuff_create)},
  1497. //@const SEEK_SET number 以头为基点
  1498. {"SEEK_SET", ROREG_INT(ZBUFF_SEEK_SET)},
  1499. //@const SEEK_CUR number 以当前位置为基点
  1500. {"SEEK_CUR", ROREG_INT(ZBUFF_SEEK_CUR)},
  1501. //@const SEEK_END number 以末尾为基点
  1502. {"SEEK_END", ROREG_INT(ZBUFF_SEEK_END)},
  1503. //@const HEAP_AUTO number 自动申请(如存在psram则在psram进行申请,如不存在或失败则在sram进行申请)
  1504. {"HEAP_AUTO", ROREG_INT(LUAT_HEAP_AUTO)},
  1505. //@const HEAP_SRAM number 在sram申请
  1506. {"HEAP_SRAM", ROREG_INT(LUAT_HEAP_SRAM)},
  1507. //@const HEAP_PSRAM number 在psram申请
  1508. {"HEAP_PSRAM", ROREG_INT(LUAT_HEAP_PSRAM)},
  1509. {NULL, ROREG_INT(0)
  1510. }
  1511. };
  1512. LUAMOD_API int luaopen_zbuff(lua_State *L)
  1513. {
  1514. luat_newlib2(L, reg_zbuff);
  1515. createmeta(L);
  1516. return 1;
  1517. }