luat_lib_zbuff.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  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)
  91. @int 字节数
  92. @any 可选参数,number时为填充数据,string时为填充字符串
  93. @number 可选参数,内存类型,可选:zbuff.SRAM(内部sram,默认) zbuff.PSRAM(外部psram) 注意:此项与硬件支持有关
  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. */
  101. /**
  102. 创建framebuff用的zbuff
  103. @api zbuff.create({width,height,bit},data)
  104. @table 宽度、高度、色位深度
  105. @int 可选参数,填充数据
  106. @return object zbuff对象,如果创建失败会返回nil
  107. @usage
  108. -- 创建zbuff
  109. local buff = zbuff.create({128,160,16})--创建一个128*160的framebuff
  110. local buff = zbuff.create({128,160,16},0xf800)--创建一个128*160的framebuff,初始状态红色
  111. */
  112. static int l_zbuff_create(lua_State *L)
  113. {
  114. size_t len;
  115. if (lua_istable(L, 1))
  116. {
  117. lua_rawgeti(L, 1, 3);
  118. lua_rawgeti(L, 1, 2);
  119. lua_rawgeti(L, 1, 1);
  120. uint8_t bit = luaL_checkinteger(L, -3);
  121. if (bit != 1 && bit != 4 && bit != 8 && bit != 16 && bit != 24 && bit != 32)
  122. return 0;
  123. len = (luaL_checkinteger(L, -1) * luaL_checkinteger(L, -2) * bit - 1) / 8 + 1;
  124. }
  125. else
  126. {
  127. len = luaL_checkinteger(L, 1);
  128. }
  129. if (len <= 0)
  130. return 0;
  131. luat_zbuff_t *buff = (luat_zbuff_t *)lua_newuserdata(L, sizeof(luat_zbuff_t));
  132. if (buff == NULL)
  133. {
  134. return 0;
  135. }
  136. buff->type = luaL_optinteger(L, 3, LUAT_HEAP_SRAM);
  137. buff->addr = (uint8_t *)luat_heap_opt_malloc(buff->type,len);
  138. if (buff->addr == NULL)
  139. {
  140. lua_pushnil(L);
  141. lua_pushstring(L, "memory not enough");
  142. return 2;
  143. }
  144. buff->len = len;
  145. buff->cursor = 0;
  146. if (lua_istable(L, 1))
  147. {
  148. buff->width = luaL_checkinteger(L, -2);
  149. buff->height = luaL_checkinteger(L, -3);
  150. buff->bit = luaL_checkinteger(L, -4);
  151. if (lua_isinteger(L, 2))
  152. {
  153. LUA_INTEGER initial = luaL_checkinteger(L, 2);
  154. uint32_t i;
  155. for (i = 0; i < buff->width * buff->height; i++)
  156. {
  157. set_framebuffer_point(buff, i, initial);
  158. }
  159. }
  160. }
  161. else
  162. {
  163. buff->width = buff->height = buff->bit = 0;
  164. if (lua_isinteger(L, 2))
  165. {
  166. memset(buff->addr, luaL_checkinteger(L, 2) % 0x100, len);
  167. }
  168. else if (lua_isstring(L, 2))
  169. {
  170. const char *data = luaL_optlstring(L, 2, "", &len);
  171. if (len > buff->len) //防止越界
  172. {
  173. len = buff->len;
  174. }
  175. memcpy(buff->addr, data, len);
  176. buff->cursor = len;
  177. }
  178. else
  179. {
  180. memset(buff->addr, 0, len);
  181. }
  182. }
  183. luaL_setmetatable(L, LUAT_ZBUFF_TYPE);
  184. return 1;
  185. }
  186. /**
  187. zbuff写数据(从当前指针位置开始;执行后指针会向后移动)
  188. @api buff:write(para,...)
  189. @any 写入buff的数据,string时为一个参数,number时可为多个参数
  190. @return number 数据成功写入的长度
  191. @usage
  192. -- 类file的读写操作
  193. local len = buff:write("123") -- 写入数据, 指针相应地往后移动,返回写入的数据长度
  194. local len = buff:write(0x1a,0x30,0x31,0x32,0x00,0x01) -- 按数值写入多个字节数据
  195. */
  196. static int l_zbuff_write(lua_State *L)
  197. {
  198. if (lua_isinteger(L, 2))
  199. {
  200. int len = 0;
  201. int data = 0;
  202. luat_zbuff_t *buff = tozbuff(L);
  203. while (lua_isinteger(L, 2 + len) && buff->cursor < buff->len)
  204. {
  205. data = luaL_checkinteger(L, 2 + len);
  206. *(uint8_t *)(buff->addr + buff->cursor) = data % 0x100;
  207. buff->cursor++;
  208. len++;
  209. }
  210. lua_pushinteger(L, len);
  211. return 1;
  212. }
  213. else
  214. {
  215. size_t len;
  216. const char *data = luaL_checklstring(L, 2, &len);
  217. luat_zbuff_t *buff = tozbuff(L);
  218. if (len + buff->cursor > buff->len) //防止越界
  219. {
  220. len = buff->len - buff->cursor;
  221. }
  222. memcpy(buff->addr + buff->cursor, data, len);
  223. buff->cursor = buff->cursor + len;
  224. lua_pushinteger(L, len);
  225. return 1;
  226. }
  227. }
  228. /**
  229. zbuff读数据(从当前指针位置开始;执行后指针会向后移动)
  230. @api buff:read(length)
  231. @int 读取buff中的字节数
  232. @return string 读取结果
  233. @usage
  234. -- 类file的读写操作
  235. local str = buff:read(3)
  236. */
  237. static int l_zbuff_read(lua_State *L)
  238. {
  239. luat_zbuff_t *buff = tozbuff(L);
  240. int read_num = luaL_optinteger(L, 2, 1);
  241. if (read_num > buff->len - buff->cursor) //防止越界
  242. {
  243. read_num = buff->len - buff->cursor;
  244. }
  245. if (read_num <= 0)
  246. {
  247. lua_pushlstring(L, NULL, 0);
  248. return 1;
  249. }
  250. char *return_str = (char *)luat_heap_opt_malloc(buff->type,read_num);
  251. if (return_str == NULL)
  252. {
  253. return 0;
  254. }
  255. memcpy(return_str, buff->addr + buff->cursor, read_num);
  256. lua_pushlstring(L, return_str, read_num);
  257. buff->cursor += read_num;
  258. luat_heap_opt_free(buff->type, return_str);
  259. return 1;
  260. }
  261. /**
  262. zbuff清空数据(与当前指针位置无关;执行后指针位置不变)
  263. @api buff:clear(num)
  264. @int 可选,默认为0。要设置为的值,不会改变buff指针位置
  265. @usage
  266. -- 全部初始化为0
  267. buff:clear(0)
  268. */
  269. static int l_zbuff_clear(lua_State *L)
  270. {
  271. luat_zbuff_t *buff = tozbuff(L);
  272. int num = luaL_optinteger(L, 2, 0);
  273. memset(buff->addr, num % 0x100, buff->len);
  274. return 0;
  275. }
  276. /**
  277. zbuff设置光标位置(可能与当前指针位置有关;执行后指针会被设置到指定位置)
  278. @api buff:seek(base,offset)
  279. @int 偏移长度
  280. @int where, 基点,默认zbuff.SEEK_SET。zbuff.SEEK_SET: 基点为 0 (文件开头),zbuff.SEEK_CUR: 基点为当前位置,zbuff.SEEK_END: 基点为文件尾
  281. @return int 设置光标后从buff开头计算起的光标的位置
  282. @usage
  283. buff:seek(0) -- 把光标设置到指定位置
  284. buff:seek(5,zbuff.SEEK_CUR)
  285. buff:seek(-3,zbuff.SEEK_END)
  286. */
  287. static int l_zbuff_seek(lua_State *L)
  288. {
  289. luat_zbuff_t *buff = tozbuff(L);
  290. int offset = luaL_checkinteger(L, 2);
  291. int whence = luaL_optinteger(L, 3, ZBUFF_SEEK_SET);
  292. switch (whence)
  293. {
  294. case ZBUFF_SEEK_SET:
  295. break;
  296. case ZBUFF_SEEK_CUR:
  297. offset = buff->cursor + offset;
  298. break;
  299. case ZBUFF_SEEK_END:
  300. offset = buff->len + offset;
  301. break;
  302. default:
  303. return 0;
  304. }
  305. if (offset <= 0)
  306. offset = 0;
  307. if (offset > buff->len)
  308. offset = buff->len;
  309. buff->cursor = offset;
  310. lua_pushinteger(L, buff->cursor);
  311. return 1;
  312. }
  313. //code from https://github.com/LuaDist/lpack/blob/master/lpack.c
  314. #define OP_STRING 'A'
  315. #define OP_FLOAT 'f'
  316. #define OP_DOUBLE 'd'
  317. #define OP_NUMBER 'n'
  318. #define OP_CHAR 'c'
  319. #define OP_BYTE 'b'
  320. #define OP_SHORT 'h'
  321. #define OP_USHORT 'H'
  322. #define OP_INT 'i'
  323. #define OP_UINT 'I'
  324. #define OP_LONG 'l'
  325. #define OP_ULONG 'L'
  326. #define OP_LITTLEENDIAN '<'
  327. #define OP_BIGENDIAN '>'
  328. #define OP_NATIVE '='
  329. #define isdigit(c) ((c) >= '0' && (c) <= '9')
  330. static void badcode(lua_State *L, int c)
  331. {
  332. char s[]="bad code `?'";
  333. s[sizeof(s)-3]=c;
  334. luaL_argerror(L,1,s);
  335. }
  336. static int doendian(int c)
  337. {
  338. int x=1;
  339. int e=*(char*)&x;
  340. if (c==OP_LITTLEENDIAN) return !e;
  341. if (c==OP_BIGENDIAN) return e;
  342. if (c==OP_NATIVE) return 0;
  343. return 0;
  344. }
  345. static void doswap(int swap, void *p, size_t n)
  346. {
  347. if (swap)
  348. {
  349. char *a = p;
  350. int i, j;
  351. for (i = 0, j = n - 1, n = n / 2; n--; i++, j--)
  352. {
  353. char t = a[i];
  354. a[i] = a[j];
  355. a[j] = t;
  356. }
  357. }
  358. }
  359. /**
  360. 将一系列数据按照格式字符转化,并写入(从当前指针位置开始;执行后指针会向后移动)
  361. @api buff:pack(format,val1, val2,...)
  362. @string 后面数据的格式(符号含义见下面的例子)
  363. @val 传入的数据,可以为多个数据
  364. @return int 成功写入的数据长度
  365. @usage
  366. buff:pack(">IIHA", 0x1234, 0x4567, 0x12,"abcdefg") -- 按格式写入几个数据
  367. -- A string
  368. -- f float
  369. -- d double
  370. -- n Lua number
  371. -- c char
  372. -- b byte / unsignen char
  373. -- h short
  374. -- H unsigned short
  375. -- i int
  376. -- I unsigned int
  377. -- l long
  378. -- L unsigned long
  379. -- < 小端
  380. -- > 大端
  381. -- = 默认大小端
  382. */
  383. #define PACKNUMBER(OP, T) \
  384. case OP: \
  385. { \
  386. T a = (T)luaL_checknumber(L, i++); \
  387. doswap(swap, &a, sizeof(a)); \
  388. write_len += add_bytes(buff, (void *)&a, sizeof(a)); \
  389. break; \
  390. }
  391. #define PACKINT(OP, T) \
  392. case OP: \
  393. { \
  394. T a = (T)luaL_checkinteger(L, i++); \
  395. doswap(swap, &a, sizeof(a)); \
  396. write_len += add_bytes(buff, (void *)&a, sizeof(a)); \
  397. break; \
  398. }
  399. static int l_zbuff_pack(lua_State *L)
  400. {
  401. luat_zbuff_t *buff = tozbuff(L);
  402. int i = 3;
  403. char *f = (char *)luaL_checkstring(L, 2);
  404. int swap = 0;
  405. int write_len = 0; //已写入长度
  406. while (*f)
  407. {
  408. if (buff->cursor == buff->len) //到头了
  409. break;
  410. int c = *f++;
  411. int N = 1;
  412. if (isdigit(*f))
  413. {
  414. N = 0;
  415. while (isdigit(*f))
  416. N = 10 * N + (*f++) - '0';
  417. }
  418. while (N--)
  419. {
  420. if (buff->cursor == buff->len) //到头了
  421. break;
  422. switch (c)
  423. {
  424. case OP_LITTLEENDIAN:
  425. case OP_BIGENDIAN:
  426. case OP_NATIVE:
  427. {
  428. swap = doendian(c);
  429. N = 0;
  430. break;
  431. }
  432. case OP_STRING:
  433. {
  434. size_t l;
  435. const char *a = luaL_checklstring(L, i++, &l);
  436. write_len += add_bytes(buff, a, l);
  437. break;
  438. }
  439. PACKNUMBER(OP_NUMBER, lua_Number)
  440. PACKNUMBER(OP_DOUBLE, double)
  441. PACKNUMBER(OP_FLOAT, float)
  442. PACKINT(OP_CHAR, char)
  443. PACKINT(OP_BYTE, unsigned char)
  444. PACKINT(OP_SHORT, short)
  445. PACKINT(OP_USHORT, unsigned short)
  446. PACKINT(OP_INT, int)
  447. PACKINT(OP_UINT, unsigned int)
  448. PACKINT(OP_LONG, long)
  449. PACKINT(OP_ULONG, unsigned long)
  450. case ' ':
  451. case ',':
  452. break;
  453. default:
  454. badcode(L, c);
  455. break;
  456. }
  457. }
  458. }
  459. lua_pushinteger(L, write_len);
  460. return 1;
  461. }
  462. #define UNPACKINT(OP, T) \
  463. case OP: \
  464. { \
  465. T a; \
  466. int m = sizeof(a); \
  467. if (i + m > len) \
  468. goto done; \
  469. memcpy(&a, s + i, m); \
  470. i += m; \
  471. doswap(swap, &a, m); \
  472. lua_pushinteger(L, (lua_Integer)a); \
  473. ++n; \
  474. break; \
  475. }
  476. #define UNPACKINT8(OP,T) \
  477. case OP: \
  478. { \
  479. T a; \
  480. int m=sizeof(a); \
  481. if (i+m>len) goto done; \
  482. memcpy(&a,s+i,m); \
  483. i+=m; \
  484. doswap(swap,&a,m); \
  485. int t = (a & 0x80)?(0xffffff00+a):a;\
  486. lua_pushinteger(L,(lua_Integer)t); \
  487. ++n; \
  488. break; \
  489. }
  490. #define UNPACKNUMBER(OP, T) \
  491. case OP: \
  492. { \
  493. T a; \
  494. int m = sizeof(a); \
  495. if (i + m > len) \
  496. goto done; \
  497. memcpy(&a, s + i, m); \
  498. i += m; \
  499. doswap(swap, &a, m); \
  500. lua_pushnumber(L, (lua_Number)a); \
  501. ++n; \
  502. break; \
  503. }
  504. /**
  505. 将一系列数据按照格式字符读取出来(从当前指针位置开始;执行后指针会向后移动)
  506. @api buff:unpack(format)
  507. @string 数据的格式(符号含义见上面pack接口的例子)
  508. @return int 成功读取的数据字节长度
  509. @return any 按格式读出来的数据
  510. @usage
  511. local cnt,a,b,c,s = buff:unpack(">IIHA10") -- 按格式读取几个数据
  512. --如果全部成功读取,cnt就是4+4+2+10=20
  513. */
  514. static int l_zbuff_unpack(lua_State *L)
  515. {
  516. luat_zbuff_t *buff = tozbuff(L);
  517. char *f = (char *)luaL_checkstring(L, 2);
  518. size_t len = buff->len - buff->cursor;
  519. const char *s = (const char*)(buff->addr + buff->cursor);
  520. int i = 0;
  521. int n = 0;
  522. int swap = 0;
  523. lua_pushnil(L); //给个数占位用的
  524. while (*f)
  525. {
  526. int c = *f++;
  527. int N = 1;
  528. if (isdigit(*f))
  529. {
  530. N = 0;
  531. while (isdigit(*f))
  532. N = 10 * N + (*f++) - '0';
  533. if (N == 0 && c == OP_STRING)
  534. {
  535. lua_pushliteral(L, "");
  536. ++n;
  537. }
  538. }
  539. while (N--){
  540. if (!lua_checkstack(L, n))
  541. return luaL_error(L, "too many results to unpack");
  542. switch (c)
  543. {
  544. case OP_LITTLEENDIAN:
  545. case OP_BIGENDIAN:
  546. case OP_NATIVE:
  547. {
  548. swap = doendian(c);
  549. N = 0;
  550. break;
  551. }
  552. case OP_STRING:
  553. {
  554. ++N;
  555. if (i + N > len)
  556. goto done;
  557. lua_pushlstring(L, s + i, N);
  558. i += N;
  559. ++n;
  560. N = 0;
  561. break;
  562. }
  563. UNPACKNUMBER(OP_NUMBER, lua_Number)
  564. UNPACKNUMBER(OP_DOUBLE, double)
  565. UNPACKNUMBER(OP_FLOAT, float)
  566. UNPACKINT8(OP_CHAR, char)
  567. UNPACKINT(OP_BYTE, unsigned char)
  568. UNPACKINT(OP_SHORT, short)
  569. UNPACKINT(OP_USHORT, unsigned short)
  570. UNPACKINT(OP_INT, int)
  571. UNPACKINT(OP_UINT, unsigned int)
  572. UNPACKINT(OP_LONG, long)
  573. UNPACKINT(OP_ULONG, unsigned long)
  574. case ' ':
  575. case ',':
  576. break;
  577. default:
  578. badcode(L, c);
  579. break;
  580. }
  581. }
  582. }
  583. done:
  584. buff->cursor += i;
  585. lua_pushinteger(L, i);
  586. lua_replace(L, -n - 2);
  587. return n + 1;
  588. }
  589. /**
  590. 读取一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动)
  591. @api buff:read类型()
  592. @注释 读取类型可为:I8、U8、I16、U16、I32、U32、I64、U64、F32、F64
  593. @return number 读取的数据,如果越界则为nil
  594. @usage
  595. local data = buff:readI8()
  596. local data = buff:readU32()
  597. */
  598. #define zread(n, t, f) \
  599. static int l_zbuff_read_##n(lua_State *L) \
  600. { \
  601. luat_zbuff_t *buff = tozbuff(L); \
  602. if (buff->len - buff->cursor < sizeof(t)) \
  603. return 0; \
  604. t tmp; \
  605. memcpy(&tmp, buff->addr + buff->cursor, sizeof(t)); \
  606. lua_push##f(L, tmp); \
  607. buff->cursor += sizeof(t); \
  608. return 1; \
  609. }
  610. zread(i8, int8_t, integer);
  611. zread(u8, uint8_t, integer);
  612. zread(i16, int16_t, integer);
  613. zread(u16, uint16_t, integer);
  614. zread(i32, int32_t, integer);
  615. zread(u32, uint32_t, integer);
  616. zread(i64, int64_t, integer);
  617. zread(u64, uint64_t, integer);
  618. zread(f32, float, number);
  619. zread(f64, double, number);
  620. /**
  621. 写入一个指定类型的数据(从当前指针位置开始;执行后指针会向后移动)
  622. @api buff:write类型()
  623. @number 待写入的数据
  624. @注释 写入类型可为:I8、U8、I16、U16、I32、U32、I64、U64、F32、F64
  625. @return number 成功写入的长度
  626. @usage
  627. local len = buff:writeI8(10)
  628. local len = buff:writeU32(1024)
  629. */
  630. #define zwrite(n, t, f) \
  631. static int l_zbuff_write_##n(lua_State *L) \
  632. { \
  633. luat_zbuff_t *buff = tozbuff(L); \
  634. if (buff->len - buff->cursor < sizeof(t)) \
  635. { \
  636. lua_pushinteger(L, 0); \
  637. return 1; \
  638. } \
  639. t tmp = (t)luaL_check##f(L, 2); \
  640. memcpy(buff->addr + buff->cursor, &(tmp), sizeof(t)); \
  641. buff->cursor += sizeof(t); \
  642. lua_pushinteger(L, sizeof(t)); \
  643. return 1; \
  644. }
  645. zwrite(i8, int8_t, integer);
  646. zwrite(u8, uint8_t, integer);
  647. zwrite(i16, int16_t, integer);
  648. zwrite(u16, uint16_t, integer);
  649. zwrite(i32, int32_t, integer);
  650. zwrite(u32, uint32_t, integer);
  651. zwrite(i64, int64_t, integer);
  652. zwrite(u64, uint64_t, integer);
  653. zwrite(f32, float, number);
  654. zwrite(f64, double, number);
  655. /**
  656. 按起始位置和长度取出数据(与当前指针位置无关;执行后指针位置不变)
  657. @api buff:toStr(offset,length)
  658. @int 数据的起始位置(起始位置为0),默认值也是0
  659. @int 数据的长度,默认是全部数据
  660. @return string 读出来的数据
  661. @usage
  662. local s = buff:toStr(0,5)--读取开头的五个字节数据
  663. local s = buff:toStr() -- 取出整个zbuff的数据
  664. local s = buff:toStr(0, buff:used()) -- 取出已使用的部分, 与buff:query()一样
  665. */
  666. static int l_zbuff_toStr(lua_State *L)
  667. {
  668. luat_zbuff_t *buff = tozbuff(L);
  669. int start = luaL_optinteger(L, 2, 0);
  670. if (start > buff->len)
  671. start = buff->len;
  672. int len = luaL_optinteger(L, 3, buff->len);
  673. if (start + len > buff->len)
  674. len = buff->len - start;
  675. lua_pushlstring(L, (const char*)(buff->addr + start), len);
  676. return 1;
  677. }
  678. /**
  679. 获取zbuff对象的长度(与当前指针位置无关;执行后指针位置不变)
  680. @api buff:len()
  681. @return int zbuff对象的长度
  682. @usage
  683. len = buff:len()
  684. len = #buff
  685. */
  686. static int l_zbuff_len(lua_State *L)
  687. {
  688. luat_zbuff_t *buff = tozbuff(L);
  689. lua_pushinteger(L, buff->len);
  690. return 1;
  691. }
  692. /**
  693. 设置buff对象的FrameBuffer属性(与当前指针位置无关;执行后指针位置不变)
  694. @api buff:setFrameBuffer(width,height,bit,color)
  695. @int FrameBuffer的宽度
  696. @int FrameBuffer的高度
  697. @int FrameBuffer的色位深度
  698. @int FrameBuffer的初始颜色
  699. @return bool 设置成功会返回true
  700. @usage
  701. result = buff:setFrameBuffer(320,240,16,0xffff)
  702. */
  703. static int l_zbuff_set_frame_buffer(lua_State *L)
  704. {
  705. luat_zbuff_t *buff = tozbuff(L);
  706. //检查空间够不够
  707. if((luaL_checkinteger(L, 2) * luaL_checkinteger(L, 3) * luaL_checkinteger(L, 4) - 1) / 8 + 1 > buff->len)
  708. return 0;
  709. buff->width = luaL_checkinteger(L,2);
  710. buff->height = luaL_checkinteger(L,3);
  711. buff->bit = luaL_checkinteger(L,4);
  712. if (lua_isinteger(L, 5))
  713. {
  714. LUA_INTEGER color = luaL_checkinteger(L, 5);
  715. uint32_t i;
  716. for (i = 0; i < buff->width * buff->height; i++)
  717. set_framebuffer_point(buff, i, color);
  718. }
  719. lua_pushboolean(L,1);
  720. return 1;
  721. }
  722. /**
  723. 设置或获取FrameBuffer某个像素点的颜色(与当前指针位置无关;执行后指针位置不变)
  724. @api buff:pixel(x,y,color)
  725. @int 与最左边的距离,范围是0~宽度-1
  726. @int 与最上边的距离,范围是0~高度-1
  727. @int 颜色,如果留空则表示获取该位置的颜色
  728. @return any 设置颜色时,设置成功会返回true;读取颜色时,返回颜色的值,读取失败返回nil
  729. @usage
  730. rerult = buff:pixel(0,3,0)
  731. color = buff:pixel(0,3)
  732. */
  733. static int l_zbuff_pixel(lua_State *L)
  734. {
  735. luat_zbuff_t *buff = tozbuff(L);
  736. uint32_t x = luaL_checkinteger(L,2);
  737. uint32_t y = luaL_checkinteger(L,3);
  738. if(x>=buff->width||y>=buff->height)
  739. return 0;
  740. if (lua_isinteger(L, 4))
  741. {
  742. LUA_INTEGER color = luaL_checkinteger(L, 4);
  743. set_framebuffer_point(buff, x + y * buff->width, color);
  744. lua_pushboolean(L,1);
  745. return 1;
  746. }
  747. else
  748. {
  749. lua_pushinteger(L,get_framebuffer_point(buff,x + y * buff->width));
  750. return 1;
  751. }
  752. }
  753. /**
  754. 画一条线(与当前指针位置无关;执行后指针位置不变)
  755. @api buff:drawLine(x1,y1,x2,y2,color)
  756. @int 起始坐标点与最左边的距离,范围是0~宽度-1
  757. @int 起始坐标点与最上边的距离,范围是0~高度-1
  758. @int 结束坐标点与最左边的距离,范围是0~宽度-1
  759. @int 结束坐标点与最上边的距离,范围是0~高度-1
  760. @int 可选,颜色,默认为0
  761. @return bool 画成功会返回true
  762. @usage
  763. rerult = buff:drawLine(0,0,2,3,0xffff)
  764. */
  765. #define abs(n) (n>0?n:-n)
  766. static int l_zbuff_draw_line(lua_State *L)
  767. {
  768. luat_zbuff_t *buff = tozbuff(L);
  769. if(buff->width<=0) return 0;//不是framebuffer数据
  770. uint32_t x0 = luaL_checkinteger(L,2);
  771. uint32_t y0 = luaL_checkinteger(L,3);
  772. uint32_t x1 = luaL_checkinteger(L,4);
  773. uint32_t y1 = luaL_checkinteger(L,5);
  774. uint32_t color = luaL_optinteger(L,6,0);
  775. //代码参考https://blog.csdn.net/qq_43405938/article/details/102700922
  776. int x = x0, y = y0, dx = x1 - x0, dy = y1 - y0;
  777. int max = (abs(dy) > abs(dx)) ? abs(dy) : abs(dx);
  778. int min = (abs(dy) > abs(dx)) ? abs(dx) : abs(dy);
  779. float e = 2 * min - max;
  780. for (int i = 0; i < max; i++)
  781. {
  782. if(x>=0&&y>=0&&x<buff->width&&y<buff->height)
  783. set_framebuffer_point(buff,x+y*buff->width,color);
  784. if (e >= 0)
  785. {
  786. e = e - 2 * max;
  787. (abs(dy) > abs(dx)) ? (dx >= 0 ? x++ : x--) : (dy >= 0 ? y++ : y--);
  788. }
  789. e += 2 * min;
  790. (abs(dy) > abs(dx)) ? (dy >= 0 ? y++ : y--) : (dx >= 0 ? x++ : x--);
  791. }
  792. lua_pushboolean(L,1);
  793. return 1;
  794. }
  795. /**
  796. 画一个矩形(与当前指针位置无关;执行后指针位置不变)
  797. @api buff:drawRect(x1,y1,x2,y2,color,fill)
  798. @int 起始坐标点与最左边的距离,范围是0~宽度-1
  799. @int 起始坐标点与最上边的距离,范围是0~高度-1
  800. @int 结束坐标点与最左边的距离,范围是0~宽度-1
  801. @int 结束坐标点与最上边的距离,范围是0~高度-1
  802. @int 可选,颜色,默认为0
  803. @bool 可选,是否在内部填充,默认nil
  804. @return bool 画成功会返回true
  805. @usage
  806. rerult = buff:drawRect(0,0,2,3,0xffff)
  807. */
  808. #define CHECK0(n,max) if(n<0)n=0;if(n>=max)n=max-1
  809. static int l_zbuff_draw_rectangle(lua_State *L)
  810. {
  811. luat_zbuff_t *buff = tozbuff(L);
  812. if(buff->width<=0) return 0;//不是framebuffer数据
  813. int32_t x1 = (int32_t)luaL_checkinteger(L,2); CHECK0(x1,buff->width);
  814. int32_t y1 = (int32_t)luaL_checkinteger(L,3); CHECK0(y1,buff->height);
  815. int32_t x2 = (int32_t)luaL_checkinteger(L,4); CHECK0(x2,buff->width);
  816. int32_t y2 = (int32_t)luaL_checkinteger(L,5); CHECK0(y2,buff->height);
  817. int32_t color = (int32_t)luaL_optinteger(L,6,0);
  818. uint8_t fill = lua_toboolean(L,7);
  819. int x,y;
  820. int32_t xmax=x1>x2?x1:x2,xmin=x1>x2?x2:x1,ymax=y1>y2?y1:y2,ymin=y1>y2?y2:y1;
  821. if(fill){
  822. for(x=xmin;x<=xmax;x++)
  823. for(y=ymin;y<=ymax;y++)
  824. set_framebuffer_point(buff,x+y*buff->width,color);
  825. }else{
  826. for(x=xmin;x<=xmax;x++){
  827. set_framebuffer_point(buff,x+ymin*buff->width,color);
  828. set_framebuffer_point(buff,x+ymax*buff->width,color);
  829. }
  830. for(y=ymin;y<=ymax;y++){
  831. set_framebuffer_point(buff,xmin+y*buff->width,color);
  832. set_framebuffer_point(buff,xmax+y*buff->width,color);
  833. }
  834. }
  835. lua_pushboolean(L,1);
  836. return 1;
  837. }
  838. /**
  839. 画一个圆形(与当前指针位置无关;执行后指针位置不变)
  840. @api buff:drawCircle(x,y,r,color,fill)
  841. @int **圆心**与最左边的距离,范围是0~宽度-1
  842. @int **圆心**与最上边的距离,范围是0~高度-1
  843. @int 圆的半径
  844. @int 可选,圆的颜色,默认为0
  845. @bool 可选,是否在内部填充,默认nil
  846. @return bool 画成功会返回true
  847. @usage
  848. rerult = buff:drawCircle(15,5,3,0xC)
  849. rerult = buff:drawCircle(15,5,3,0xC,true)
  850. */
  851. #define DRAW_CIRCLE_ALL(buff, xc, yc, x, y, c) \
  852. { \
  853. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  854. set_framebuffer_point(buff, (xc + x) + (yc + y) * buff->width, c); \
  855. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  856. set_framebuffer_point(buff, (xc - x) + (yc + y) * buff->width, c); \
  857. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  858. set_framebuffer_point(buff, (xc + x) + (yc - y) * buff->width, c); \
  859. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  860. set_framebuffer_point(buff, (xc - x) + (yc - y) * buff->width, c); \
  861. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  862. set_framebuffer_point(buff, (xc + y) + (yc + x) * buff->width, c); \
  863. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  864. set_framebuffer_point(buff, (xc - y) + (yc + x) * buff->width, c); \
  865. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  866. set_framebuffer_point(buff, (xc + y) + (yc - x) * buff->width, c); \
  867. if (x >= 0 && y >= 0 && x < buff->width && y < buff->height) \
  868. set_framebuffer_point(buff, (xc - y) + (yc - x) * buff->width, c); \
  869. }
  870. static int l_zbuff_draw_circle(lua_State *L)
  871. {
  872. luat_zbuff_t *buff = tozbuff(L);
  873. if(buff->width<=0) return 0;//不是framebuffer数据
  874. int32_t xc = luaL_checkinteger(L,2);
  875. int32_t yc = luaL_checkinteger(L,3);
  876. int32_t r = luaL_checkinteger(L,4);
  877. int32_t color = luaL_optinteger(L,5,0);
  878. uint8_t fill = lua_toboolean(L,6);
  879. //代码参考https://www.cnblogs.com/wlzy/p/8695226.html
  880. //圆不在可见区域
  881. if (xc + r < 0 || xc - r >= buff->width || yc + r < 0 || yc - r >= buff->height)
  882. return 0;
  883. int x = 0, y = r, yi, d;
  884. d = 3 - 2 * r;
  885. while (x <= y)
  886. {
  887. if (fill)
  888. {
  889. for (yi = x; yi <= y; yi++)
  890. DRAW_CIRCLE_ALL(buff, xc, yc, x, yi, color);
  891. }
  892. else
  893. {
  894. DRAW_CIRCLE_ALL(buff, xc, yc, x, y, color);
  895. }
  896. if (d < 0)
  897. {
  898. d = d + 4 * x + 6;
  899. }
  900. else
  901. {
  902. d = d + 4 * (x - y) + 10;
  903. y--;
  904. }
  905. x++;
  906. }
  907. lua_pushboolean(L,1);
  908. return 1;
  909. }
  910. /**
  911. 以下标形式进行数据读写(与当前指针位置无关;执行后指针位置不变)
  912. @api buff[n]
  913. @int 第几个数据,以0开始的下标(C标准)
  914. @return number 该位置的数据
  915. @usage
  916. buff[0] = 0xc8
  917. local data = buff[0]
  918. */
  919. static int l_zbuff_index(lua_State *L)
  920. {
  921. //luat_zbuff_t **pp = luaL_checkudata(L, 1, LUAT_ZBUFF_TYPE);
  922. // int i;
  923. luaL_getmetatable(L, LUAT_ZBUFF_TYPE);
  924. lua_pushvalue(L, 2);
  925. lua_rawget(L, -2);
  926. if (lua_isnil(L, -1))
  927. {
  928. /* found no method, so get value from userdata. */
  929. luat_zbuff_t *buff = tozbuff(L);
  930. int o = luaL_checkinteger(L, 2);
  931. if (o >= buff->len)
  932. return 0;
  933. lua_pushinteger(L, buff->addr[o]);
  934. return 1;
  935. };
  936. return 1;
  937. }
  938. static int l_zbuff_newindex(lua_State *L)
  939. {
  940. if (lua_isinteger(L, 2))
  941. {
  942. luat_zbuff_t *buff = tozbuff(L);
  943. if (lua_isinteger(L, 2))
  944. {
  945. int o = luaL_checkinteger(L, 2);
  946. int n = luaL_checkinteger(L, 3) % 256;
  947. if (o > buff->len)
  948. return 0;
  949. buff->addr[o] = n;
  950. }
  951. }
  952. return 0;
  953. }
  954. // __gc l_zbuff_gc为zbuff默认gc函数,gc调用时会释放申请内存并gc掉zbuff,下面为用户手动调用注释
  955. /**
  956. 释放zbuff所申请内存 注意:gc时会自动释放zbuff以及zbuff所申请内存,所以通常无需调用此函数,调用前请确认您已清楚此函数用处!调用此函数并不会释放掉zbuff,仅会释放掉zbuff所申请的内存,zbuff需等gc时自动释放!!!
  957. @api buff:free()
  958. @usage
  959. buff:free()
  960. */
  961. static int l_zbuff_gc(lua_State *L)
  962. {
  963. luat_zbuff_t *buff = tozbuff(L);
  964. if (buff->addr){
  965. luat_heap_opt_free(buff->type,buff->addr);
  966. buff->addr = NULL;
  967. buff->len = 0;
  968. buff->used = 0;
  969. }
  970. return 0;
  971. }
  972. int __zbuff_resize(luat_zbuff_t *buff, uint32_t new_size)
  973. {
  974. void *p = luat_heap_opt_malloc(buff->type,new_size);
  975. if (p)
  976. {
  977. memcpy(p, buff->addr, (new_size > buff->used)?buff->used:new_size);
  978. luat_heap_opt_free(buff->type,buff->addr);
  979. buff->addr = p;
  980. buff->len = new_size;
  981. buff->used = (buff->len > buff->used)?buff->used:buff->len;
  982. return 0;
  983. }
  984. else
  985. {
  986. return -1;
  987. }
  988. }
  989. /**
  990. 调整zbuff实际分配空间的大小,类似于realloc的效果,new = realloc(old, n),可以扩大或者缩小(如果缩小后len小于了used,那么used=新len)
  991. @api buff:resize(n)
  992. @int 新空间大小
  993. @usage
  994. buff:resize(20)
  995. */
  996. static int l_zbuff_resize(lua_State *L)
  997. {
  998. luat_zbuff_t *buff = tozbuff(L);
  999. if (lua_isinteger(L, 2))
  1000. {
  1001. uint32_t n = luaL_checkinteger(L, 2);
  1002. __zbuff_resize(buff, n);
  1003. }
  1004. return 0;
  1005. }
  1006. /**
  1007. zbuff动态写数据,类似于memcpy效果,当原有空间不足时动态扩大空间
  1008. @api buff:copy(start, para,...)
  1009. @int 写入buff的起始位置,如果不为数字,则为buff的used,如果小于0,则从used往前数,-1 = used - 1
  1010. @any 写入buff的数据,string或zbuff者时为一个参数,number时可为多个参数
  1011. @return number 数据成功写入的长度
  1012. @usage
  1013. local len = buff:copy(nil, "123") -- 类似于memcpy(&buff[used], "123", 3) used+= 3 从buff开始写入数据,指针相应地往后移动
  1014. local len = buff:copy(0, "123") -- 类似于memcpy(&buff[0], "123", 3) if (used < 3) used = 3 从位置0写入数据,指针有可能会移动
  1015. 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开始,按数值写入多个字节数据
  1016. 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的内容
  1017. local len = buff:copy(5, buff2, 10, 1024) -- 类似于memcpy(&buff[5], &buff2[10], 1024) if (used < (5+1024)) used = (5+1024)
  1018. */
  1019. static int l_zbuff_copy(lua_State *L)
  1020. {
  1021. luat_zbuff_t *buff = tozbuff(L);
  1022. int temp_cursor = luaL_optinteger(L, 2, buff->used);
  1023. if (temp_cursor < 0)
  1024. {
  1025. temp_cursor = buff->used + temp_cursor;
  1026. if (temp_cursor < 0)
  1027. {
  1028. lua_pushinteger(L, 0);
  1029. return 1;
  1030. }
  1031. }
  1032. if (lua_isinteger(L, 3))
  1033. {
  1034. int len = 0;
  1035. int data = 0;
  1036. while (lua_isinteger(L, 3 + len))
  1037. {
  1038. if (temp_cursor > buff->len)
  1039. {
  1040. if (__zbuff_resize(buff, temp_cursor * 2))
  1041. {
  1042. lua_pushinteger(L, len);
  1043. return 1;
  1044. }
  1045. }
  1046. data = luaL_checkinteger(L, 3 + len);
  1047. *(uint8_t *)(buff->addr + temp_cursor) = data % 0x100;
  1048. temp_cursor++;
  1049. len++;
  1050. }
  1051. buff->used = (temp_cursor > buff->used)?temp_cursor:buff->used;
  1052. lua_pushinteger(L, len);
  1053. return 1;
  1054. }
  1055. else if (lua_isstring(L, 3))
  1056. {
  1057. size_t len;
  1058. const char *data = luaL_checklstring(L, 3, &len);
  1059. if (len + temp_cursor > buff->len) //防止越界
  1060. {
  1061. if (__zbuff_resize(buff, buff->len + len + temp_cursor))
  1062. {
  1063. lua_pushinteger(L, 0);
  1064. return 1;
  1065. }
  1066. }
  1067. memcpy(buff->addr + temp_cursor, data, len);
  1068. temp_cursor = temp_cursor + len;
  1069. buff->used = (temp_cursor > buff->used)?temp_cursor:buff->used;
  1070. lua_pushinteger(L, len);
  1071. return 1;
  1072. }
  1073. else if (lua_isuserdata(L, 3))
  1074. {
  1075. luat_zbuff_t *copy_buff = ((luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE));
  1076. uint32_t start = luaL_optinteger(L, 4, 0);
  1077. uint32_t len = luaL_optinteger(L, 5, copy_buff->used);
  1078. if (len + temp_cursor > buff->len) //防止越界
  1079. {
  1080. if (__zbuff_resize(buff, buff->len + len + temp_cursor))
  1081. {
  1082. lua_pushinteger(L, 0);
  1083. return 1;
  1084. }
  1085. }
  1086. memcpy(buff->addr + temp_cursor, copy_buff->addr + start, len);
  1087. temp_cursor += len;
  1088. buff->used = (temp_cursor > buff->used)?temp_cursor:buff->used;
  1089. lua_pushinteger(L, len);
  1090. return 1;
  1091. }
  1092. lua_pushinteger(L, 0);
  1093. return 1;
  1094. }
  1095. /**
  1096. 获取zbuff里最后一个数据位置指针到首地址的偏移量,来表示zbuff内已有有效数据量大小,注意这个不同于分配的空间大小,由于seek()会改变最后一个数据位置指针,因此也会影响到used()返回值。
  1097. @api buff:used()
  1098. @return int 有效数据量大小
  1099. @usage
  1100. buff:used()
  1101. */
  1102. static int l_zbuff_used(lua_State *L)
  1103. {
  1104. luat_zbuff_t *buff = tozbuff(L);
  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. static const luaL_Reg lib_zbuff[] = {
  1352. {"write", l_zbuff_write},
  1353. {"read", l_zbuff_read},
  1354. {"clear", l_zbuff_clear},
  1355. {"seek", l_zbuff_seek},
  1356. {"pack", l_zbuff_pack},
  1357. {"unpack", l_zbuff_unpack},
  1358. {"get", l_zbuff_index},
  1359. {"readI8", l_zbuff_read_i8},
  1360. {"readI16", l_zbuff_read_i16},
  1361. {"readI32", l_zbuff_read_i32},
  1362. {"readI64", l_zbuff_read_i64},
  1363. {"readU8", l_zbuff_read_u8},
  1364. {"readU16", l_zbuff_read_u16},
  1365. {"readU32", l_zbuff_read_u32},
  1366. {"readU64", l_zbuff_read_u64},
  1367. {"readF32", l_zbuff_read_f32},
  1368. {"readF64", l_zbuff_read_f64},
  1369. {"writeI8", l_zbuff_write_i8},
  1370. {"writeI16", l_zbuff_write_i16},
  1371. {"writeI32", l_zbuff_write_i32},
  1372. {"writeI64", l_zbuff_write_i64},
  1373. {"writeU8", l_zbuff_write_u8},
  1374. {"writeU16", l_zbuff_write_u16},
  1375. {"writeU32", l_zbuff_write_u32},
  1376. {"writeU64", l_zbuff_write_u64},
  1377. {"writeF32", l_zbuff_write_f32},
  1378. {"writeF64", l_zbuff_write_f64},
  1379. {"toStr", l_zbuff_toStr},
  1380. {"len", l_zbuff_len},
  1381. {"setFrameBuffer", l_zbuff_set_frame_buffer},
  1382. {"pixel", l_zbuff_pixel},
  1383. {"drawLine", l_zbuff_draw_line},
  1384. {"drawRect", l_zbuff_draw_rectangle},
  1385. {"drawCircle", l_zbuff_draw_circle},
  1386. //{"__index", l_zbuff_index},
  1387. //{"__len", l_zbuff_len},
  1388. //{"__newindex", l_zbuff_newindex},
  1389. {"free", l_zbuff_gc},
  1390. //以下为扩展用法,数据的增减操作尽量不要和上面的read,write一起使用,对数值指针的用法不一致
  1391. {"copy", l_zbuff_copy},
  1392. {"set", l_zbuff_set},
  1393. {"query",l_zbuff_query},
  1394. {"del", l_zbuff_del},
  1395. {"resize", l_zbuff_resize},
  1396. {"reSize", l_zbuff_resize},
  1397. {"used", l_zbuff_used},
  1398. {"isEqual", l_zbuff_equal},
  1399. {NULL, NULL}};
  1400. static int luat_zbuff_meta_index(lua_State *L) {
  1401. if (lua_isinteger(L, 2)) {
  1402. return l_zbuff_index(L);
  1403. }
  1404. if (lua_isstring(L, 2)) {
  1405. const char* keyname = luaL_checkstring(L, 2);
  1406. //printf("zbuff keyname = %s\n", keyname);
  1407. int i = 0;
  1408. while (1) {
  1409. if (lib_zbuff[i].name == NULL) break;
  1410. if (!strcmp(keyname, lib_zbuff[i].name)) {
  1411. lua_pushcfunction(L, lib_zbuff[i].func);
  1412. return 1;
  1413. }
  1414. i++;
  1415. }
  1416. }
  1417. return 0;
  1418. }
  1419. static void createmeta(lua_State *L)
  1420. {
  1421. luaL_newmetatable(L, LUAT_ZBUFF_TYPE); /* create metatable for file handles */
  1422. // lua_pushvalue(L, -1); /* push metatable */
  1423. // lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
  1424. // luaL_setfuncs(L, lib_zbuff, 0); /* add file methods to new metatable */
  1425. //luaL_setfuncs(L, lib_zbuff_metamethods, 0);
  1426. //luaL_setfuncs(L, lib_zbuff, 0);
  1427. lua_pushcfunction(L, l_zbuff_len);
  1428. lua_setfield(L, -2, "__len");
  1429. lua_pushcfunction(L, l_zbuff_gc);
  1430. lua_setfield(L, -2, "__gc");
  1431. lua_pushcfunction(L, luat_zbuff_meta_index);
  1432. lua_setfield(L, -2, "__index");
  1433. lua_pushcfunction(L, l_zbuff_newindex);
  1434. lua_setfield(L, -2, "__newindex");
  1435. lua_pop(L, 1); /* pop new metatable */
  1436. //luaL_newlib(L, lib_zbuff);
  1437. }
  1438. #include "rotable2.h"
  1439. static const rotable_Reg_t reg_zbuff[] =
  1440. {
  1441. {"create", ROREG_FUNC(l_zbuff_create)},
  1442. //@const SEEK_SET number 以头为基点
  1443. {"SEEK_SET", ROREG_INT(ZBUFF_SEEK_SET)},
  1444. //@const SEEK_CUR number 以当前位置为基点
  1445. {"SEEK_CUR", ROREG_INT(ZBUFF_SEEK_CUR)},
  1446. //@const SEEK_END number 以末尾为基点
  1447. {"SEEK_END", ROREG_INT(ZBUFF_SEEK_END)},
  1448. {"SRAM", ROREG_INT(LUAT_HEAP_SRAM)},
  1449. {"PSRAM", ROREG_INT(LUAT_HEAP_PSRAM)},
  1450. {NULL, ROREG_INT(0)
  1451. }
  1452. };
  1453. LUAMOD_API int luaopen_zbuff(lua_State *L)
  1454. {
  1455. luat_newlib2(L, reg_zbuff);
  1456. createmeta(L);
  1457. return 1;
  1458. }