luat_lib_zbuff.c 45 KB

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