luat_lib_zbuff.c 49 KB

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