lstrlib_exts.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. /*
  2. @module string
  3. @summary 字符串操作函数
  4. @tag LUAT_USE_GPIO
  5. @demo string
  6. */
  7. #include "luat_base.h"
  8. #include "luat_mem.h"
  9. #include "lua.h"
  10. #include "lauxlib.h"
  11. #define LUAT_LOG_TAG "str"
  12. #include "luat_log.h"
  13. /* }====================================================== */
  14. #define IsHex(c) (((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')))
  15. #define IsDigit(c) ((c >= '0') && (c <= '9'))
  16. static const unsigned char hexchars[] = "0123456789ABCDEF";
  17. void luat_str_tohexwithsep(const char* str, size_t len, const char* separator, size_t len_j, char* buff) {
  18. for (size_t i = 0; i < len; i++)
  19. {
  20. char ch = *(str+i);
  21. buff[i*(2+len_j)] = hexchars[(unsigned char)ch >> 4];
  22. buff[i*(2+len_j)+1] = hexchars[(unsigned char)ch & 0xF];
  23. for (size_t j = 0; j < len_j; j++){
  24. buff[i*(2+len_j)+2+j] = separator[j];
  25. }
  26. }
  27. }
  28. void luat_str_tohex(const char* str, size_t len, char* buff) {
  29. luat_str_tohexwithsep(str, len, NULL, 0, buff);
  30. }
  31. void luat_str_fromhex(const char* str, size_t len, char* buff) {
  32. for (size_t i = 0; i < len/2; i++)
  33. {
  34. char a = *(str + i*2);
  35. char b = *(str + i*2 + 1);
  36. //printf("%d %c %c\r\n", i, a, b);
  37. a = (a <= '9') ? a - '0' : (a & 0x7) + 9;
  38. b = (b <= '9') ? b - '0' : (b & 0x7) + 9;
  39. buff[i] = (a << 4) + b;
  40. }
  41. }
  42. size_t luat_str_fromhex_ex(const char* str, size_t len, char* buff) {
  43. size_t out_len = 0;
  44. uint8_t temp = 0;
  45. uint8_t is_full = 0;
  46. uint8_t a;
  47. for(size_t i = 0; i < len; i++)
  48. {
  49. a = str[i];
  50. if (IsDigit(a)||IsHex(a))
  51. {
  52. if (is_full)
  53. {
  54. temp = (temp << 4) + ((a <= '9') ? a - '0' : (a & 0x7) + 9);
  55. buff[out_len] = (char)temp;
  56. out_len++;
  57. temp = 0;
  58. is_full = 0;
  59. }
  60. else
  61. {
  62. temp = ((a <= '9') ? a - '0' : (a & 0x7) + 9);
  63. is_full = 1;
  64. }
  65. }
  66. else
  67. {
  68. temp = 0;
  69. is_full = 0;
  70. }
  71. }
  72. return out_len;
  73. }
  74. void luat_str_ucs2_to_char(char* source, size_t size, char* dst2, size_t* outlen) {
  75. char *buff = (char *)luat_heap_malloc(size + 2);
  76. memset(buff, 0, size + 2);
  77. luat_str_fromhex(source, size, buff);
  78. uint16_t* tmp = (uint16_t*)buff;
  79. char* dst = dst2;
  80. uint16_t unicode = 0;
  81. size_t dstlen = 0;
  82. while (1) {
  83. unicode = *tmp ++;
  84. unicode = ((unicode >> 8) & 0xFF) + ((unicode & 0xFF) << 8);
  85. if (unicode == 0)
  86. break; // 终止了
  87. if (unicode <= 0x0000007F) {
  88. dst[dstlen++] = (unicode & 0x7F);
  89. continue;
  90. }
  91. if (unicode <= 0x000007FF) {
  92. dst[dstlen++] = ((unicode >> 6) & 0x1F) | 0xC0;
  93. dst[dstlen++] = (unicode & 0x3F) | 0x80;
  94. continue;
  95. }
  96. if (unicode <= 0x0000FFFF) {
  97. dst[dstlen++] = ((unicode >> 12) & 0x0F) | 0xE0;
  98. dst[dstlen++] = ((unicode >> 6) & 0x3F) | 0x80;
  99. dst[dstlen++] = (unicode & 0x3F) | 0x80;
  100. continue;
  101. }
  102. break;
  103. }
  104. *outlen = dstlen;
  105. luat_heap_free(buff);
  106. }
  107. int luat_str_utf8_to_ucs2(char* source, size_t source_len, char* dst, size_t dstlen, size_t* outlen) {
  108. uint16_t unicode = 0;
  109. size_t tmplen = 0;
  110. for (size_t i = 0; i < source_len; i++)
  111. {
  112. if(tmplen >= dstlen) {
  113. return -1;
  114. }
  115. // 首先是不是单字节
  116. if (source[i] & 0x80) {
  117. // 非ASCII编码
  118. if (source[i] & 0xE0) { // 1110xxxx 10xxxxxx 10xxxxxx
  119. unicode = ((source[i] & 0x0F) << 12) + ((source[i+1] & 0x3F) << 6) + (source[i+2] & 0x3F);
  120. dst[tmplen++] = (unicode >> 8) & 0xFF;
  121. dst[tmplen++] = unicode & 0xFF;
  122. i+=2;
  123. continue;
  124. }
  125. if (source[i] & 0xC0) { // 110xxxxx 10xxxxxx
  126. unicode = ((source[i] & 0x1F) << 6) + (source[i+1] & 0x3F);
  127. dst[tmplen++] = (unicode >> 8) & 0xFF;
  128. dst[tmplen++] = unicode & 0xFF;
  129. i++;
  130. continue;
  131. }
  132. return -1;
  133. }
  134. // 单个ASCII字符, 但需要扩展到2位
  135. else {
  136. // ASCII编码
  137. dst[tmplen++] = 0x00;
  138. dst[tmplen++] = source[i];
  139. continue;
  140. }
  141. }
  142. *outlen = tmplen;
  143. return 0;
  144. }
  145. /*
  146. 将字符串转成HEX
  147. @api string.toHex(str, separator)
  148. @string 需要转换的字符串
  149. @string 分隔符, 默认为""
  150. @return string HEX字符串
  151. @return number HEX字符串的长度
  152. @usage
  153. string.toHex("\1\2\3") --> "010203" 6
  154. string.toHex("123abc") --> "313233616263" 12
  155. string.toHex("123abc", " ") --> "31 32 33 61 62 63 " 12
  156. */
  157. int l_str_toHex (lua_State *L) {
  158. size_t len;
  159. const char *str = luaL_checklstring(L, 1, &len);
  160. size_t len_j;
  161. const char *separator = luaL_optlstring(L, 2, "", &len_j);
  162. luaL_Buffer buff;
  163. luaL_buffinitsize(L, &buff, (2+len_j)*len);
  164. luat_str_tohexwithsep(str, len, separator, len_j, buff.b);
  165. buff.n = len * (2 + len_j);
  166. luaL_pushresult(&buff);
  167. lua_pushinteger(L, len*2);
  168. return 2;
  169. }
  170. /*
  171. 将HEX转成字符串
  172. @api string.fromHex(hex)
  173. @string hex,16进制组成的串
  174. @return string 字符串
  175. @usage
  176. string.fromHex("010203") --> "\1\2\3"
  177. string.fromHex("313233616263") --> "123abc"
  178. */
  179. int l_str_fromHex (lua_State *L) {
  180. size_t len;
  181. const char *str = luaL_checklstring(L, 1, &len);
  182. luaL_Buffer buff;
  183. luaL_buffinitsize(L, &buff, len / 2);
  184. // luat_str_fromhex((char*)str, len, buff.b);
  185. // buff.n = len / 2;
  186. buff.n = luat_str_fromhex_ex(str, len, buff.b);
  187. luaL_pushresult(&buff);
  188. return 1;
  189. }
  190. /*
  191. 按照指定分隔符分割字符串
  192. @api string.split(str, delimiter, keepEmtry)
  193. @string 输入字符串
  194. @string 分隔符,可选,默认 ","
  195. @bool 是否保留空白片段,默认为false,不保留. 2023.4.11之后的固件可用
  196. @return table 分割后的字符串表
  197. @usage
  198. local tmp = string.split("123,233333,122")
  199. log.info("tmp", json.encode(tmp))
  200. local tmp = ("123,456,789"):split(',') --> {'123','456','789'}
  201. log.info("tmp", json.encode(tmp))
  202. -- 保留空片段, 2023.4.11之后的固件可用
  203. local str = "/tmp//def/1234/"
  204. local tmp = str:split("/", true)
  205. log.info("str.split", #tmp, json.encode(tmp))
  206. */
  207. int l_str_split (lua_State *L) {
  208. size_t len = 0;
  209. int keepEmtry = 0;
  210. const char *str = luaL_checklstring(L, 1, &len);
  211. if (len == 0) {
  212. lua_newtable(L);
  213. return 1;
  214. }
  215. size_t dlen = 0;
  216. const char *delimiters = luaL_optlstring(L, 2, ",", &dlen);
  217. if (dlen < 1) {
  218. delimiters = ",";
  219. dlen = 1;
  220. }
  221. if (lua_isboolean(L, 3) && lua_toboolean(L, 3)) {
  222. keepEmtry = 1;
  223. }
  224. lua_newtable(L);
  225. int prev = -1;
  226. size_t count = 1;
  227. for (size_t i = 0; i < len; i++)
  228. {
  229. // LLOGD("d[%s] [%.*s] %d", delimiters, dlen, str+i, dlen);
  230. if (!memcmp(delimiters, str+i, dlen)) {
  231. // LLOGD("match %d %i %d",prev, i, keepEmtry);
  232. if ((prev+1) != i || (keepEmtry)) {
  233. lua_pushinteger(L, count);
  234. lua_pushlstring(L, str + prev + 1, i - prev - 1);
  235. // LLOGD("add %d [%.*s]", count, i - prev, str+prev);
  236. lua_settable(L, -3);
  237. count += 1;
  238. }
  239. i += (dlen - 1);
  240. prev = i;
  241. if (i == len - 1 && keepEmtry) {
  242. lua_pushinteger(L, count);
  243. lua_pushlstring(L, "", 0);
  244. lua_settable(L, -3);
  245. break;
  246. }
  247. }
  248. else {
  249. if (i == len - 1) {
  250. // 最后一个字符了
  251. lua_pushinteger(L, count);
  252. lua_pushlstring(L, str + prev + 1, len - prev - 1);
  253. lua_settable(L, -3);
  254. }
  255. }
  256. }
  257. return 1;
  258. }
  259. /*
  260. 返回字符串tonumber的转义字符串(用来支持超过31位整数的转换)
  261. @api string.toValue(str)
  262. @string 输入字符串
  263. @return string 转换后的二进制字符串
  264. @return number 转换了多少个字符
  265. @usage
  266. string.toValue("123456") --> "\1\2\3\4\5\6" 6
  267. string.toValue("123abc") --> "\1\2\3\a\b\c" 6
  268. */
  269. int l_str_toValue (lua_State *L) {
  270. size_t len = 0,i;
  271. const char *s = luaL_checklstring(L, 1, &len);
  272. if(len == 0)//没字符串
  273. {
  274. lua_pushlstring(L,NULL,0);
  275. lua_pushinteger(L,0);
  276. return 2;
  277. }
  278. luaL_Buffer buff;
  279. luaL_buffinitsize(L, &buff, len);
  280. char * stemp;
  281. for(i=0;i<len;i++)
  282. {
  283. stemp = (char *)s + i;
  284. luaL_addchar(&buff, (*stemp>'9'? *stemp+9 : *stemp) & 0x0f);
  285. }
  286. luaL_pushresult(&buff);
  287. lua_pushinteger(L,len);
  288. return 2;
  289. }
  290. /*
  291. 将字符串进行url编码转换
  292. @api string.urlEncode("123 abc")
  293. @string 需要转换的字符串
  294. @int mode:url编码的转换标准,
  295. -1:自定义标准.为-1时,才会有后面的space和str_check
  296. 0:默认标准php
  297. 1:RFC3986标准,和默认的相比就是' '的转换方式不一样
  298. 这个参数不存在,按0:默认标准php处理
  299. @int space:' '空格的处理方式
  300. 0:' '转化为'+'
  301. 1:' '转换为"%20"
  302. @string str_check:不需要转换的字符,组成的字符串
  303. @return string 返回转换后的字符串
  304. @usage
  305. -- 将字符串进行url编码转换
  306. log.info(string.urlEncode("123 abc+/")) -->> "123+abc%2B%2F"
  307. log.info(string.urlEncode("123 abc+/",1)) -->> "123%20abc%2B%2F"
  308. log.info(string.urlEncode("123 abc+/",-1,1,"/")) -->> "123%20abc%2B/"
  309. log.info(string.urlEncode("123 abc+/",-1,0,"/")) -->> "123+abc%2B/"
  310. log.info(string.urlEncode("123 abc+/",-1,0,"/ ")) -->> "123 abc%2B/"
  311. */
  312. int l_str_urlEncode (lua_State *L) {
  313. int argc = lua_gettop(L);
  314. int mode = 0; //转换模式,-1:自定义标准,0:默认标准php,1:RFC3986标准,和默认的相比就是' '的转换方式不一样
  315. int space = 0; //0:' '转化为'+', 1:' '转换为"%20"
  316. size_t len_check = 0;
  317. const char *str_check = NULL; //不需要转换的字符
  318. size_t len = 0;
  319. const char *str = luaL_checklstring(L, 1, &len);
  320. if(argc == 1)
  321. {
  322. mode = 0;
  323. }
  324. else{
  325. mode = luaL_checkinteger(L, 2);
  326. }
  327. if(mode == -1)
  328. {
  329. /* 自定义模式 */
  330. space = luaL_checkinteger(L, 3);
  331. str_check = luaL_checklstring(L, 4, &len_check);
  332. }
  333. if(mode == 1)
  334. {
  335. /* RFC3986 */
  336. space = 1;
  337. str_check = ".-_";
  338. len_check = 3;
  339. }
  340. luaL_Buffer buff;
  341. luaL_buffinitsize(L, &buff, len + 16);
  342. if(str_check == NULL)
  343. {
  344. str_check = ".-*_";
  345. len_check = 4;
  346. }
  347. for (size_t i = 0; i < len; i++)
  348. {
  349. char ch = *(str+i);
  350. if((ch >= 'A' && ch <= 'Z') ||
  351. (ch >= 'a' && ch <= 'z') ||
  352. (ch >= '0' && ch <= '9')) {
  353. luaL_addchar(&buff, ch);
  354. }
  355. else {
  356. char result = 0;
  357. for(size_t j = 0; j < len_check; j++)
  358. {
  359. if(ch == str_check[j])
  360. {
  361. result = 1;
  362. break;
  363. }
  364. }
  365. if(result == 1)
  366. {
  367. luaL_addchar(&buff, str[i]);
  368. }
  369. else
  370. {
  371. if(ch == ' ')
  372. {
  373. if(space == 0)
  374. {
  375. luaL_addchar(&buff, '+');
  376. continue;
  377. }
  378. }
  379. luaL_addchar(&buff, '%');
  380. luaL_addchar(&buff, hexchars[(unsigned char)str[i] >> 4]);
  381. luaL_addchar(&buff, hexchars[(unsigned char)str[i] & 0x0F]);
  382. }
  383. }
  384. }
  385. luaL_pushresult(&buff);
  386. return 1;
  387. }
  388. // ----------------------------------------------------------
  389. // Base64
  390. //-----------------------------------------------------------
  391. static const unsigned char base64_enc_map[64] =
  392. {
  393. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  394. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  395. 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  396. 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  397. 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  398. 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
  399. '8', '9', '+', '/'
  400. };
  401. static const unsigned char base64_dec_map[128] =
  402. {
  403. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  404. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  405. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  406. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  407. 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
  408. 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
  409. 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
  410. 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  411. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  412. 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
  413. 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
  414. 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  415. 49, 50, 51, 127, 127, 127, 127, 127
  416. };
  417. #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
  418. /*
  419. * Encode a buffer into base64 format
  420. */
  421. int luat_str_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
  422. const unsigned char *src, size_t slen )
  423. {
  424. size_t i, n;
  425. int C1, C2, C3;
  426. unsigned char *p;
  427. if( slen == 0 )
  428. {
  429. *olen = 0;
  430. return( 0 );
  431. }
  432. n = slen / 3 + ( slen % 3 != 0 );
  433. if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
  434. {
  435. *olen = BASE64_SIZE_T_MAX;
  436. return( -1 );
  437. }
  438. n *= 4;
  439. if( ( dlen < n + 1 ) || ( NULL == dst ) )
  440. {
  441. *olen = n + 1;
  442. return( -1 );
  443. }
  444. n = ( slen / 3 ) * 3;
  445. for( i = 0, p = dst; i < n; i += 3 )
  446. {
  447. C1 = *src++;
  448. C2 = *src++;
  449. C3 = *src++;
  450. *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
  451. *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
  452. *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
  453. *p++ = base64_enc_map[C3 & 0x3F];
  454. }
  455. if( i < slen )
  456. {
  457. C1 = *src++;
  458. C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
  459. *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
  460. *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
  461. if( ( i + 1 ) < slen )
  462. *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
  463. else *p++ = '=';
  464. *p++ = '=';
  465. }
  466. *olen = p - dst;
  467. *p = 0;
  468. return( 0 );
  469. }
  470. /*
  471. * Decode a base64-formatted buffer
  472. */
  473. #ifndef uint32_t
  474. #define uint32_t unsigned int
  475. #endif
  476. int luat_str_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
  477. const unsigned char *src, size_t slen )
  478. {
  479. size_t i, n;
  480. uint32_t j, x;
  481. unsigned char *p;
  482. /* First pass: check for validity and get output length */
  483. for( i = n = j = 0; i < slen; i++ )
  484. {
  485. /* Skip spaces before checking for EOL */
  486. x = 0;
  487. while( i < slen && src[i] == ' ' )
  488. {
  489. ++i;
  490. ++x;
  491. }
  492. /* Spaces at end of buffer are OK */
  493. if( i == slen )
  494. break;
  495. if( ( slen - i ) >= 2 &&
  496. src[i] == '\r' && src[i + 1] == '\n' )
  497. continue;
  498. if( src[i] == '\n' )
  499. continue;
  500. /* Space inside a line is an error */
  501. if( x != 0 )
  502. return( -2 );
  503. if( src[i] == '=' && ++j > 2 )
  504. return( -2 );
  505. if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
  506. return( -2 );
  507. if( base64_dec_map[src[i]] < 64 && j != 0 )
  508. return( -2 );
  509. n++;
  510. }
  511. if( n == 0 )
  512. {
  513. *olen = 0;
  514. return( 0 );
  515. }
  516. /* The following expression is to calculate the following formula without
  517. * risk of integer overflow in n:
  518. * n = ( ( n * 6 ) + 7 ) >> 3;
  519. */
  520. n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
  521. n -= j;
  522. if( dst == NULL || dlen < n )
  523. {
  524. *olen = n;
  525. return( -1 );
  526. }
  527. for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
  528. {
  529. if( *src == '\r' || *src == '\n' || *src == ' ' )
  530. continue;
  531. j -= ( base64_dec_map[*src] == 64 );
  532. x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
  533. if( ++n == 4 )
  534. {
  535. n = 0;
  536. if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
  537. if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
  538. if( j > 2 ) *p++ = (unsigned char)( x );
  539. }
  540. }
  541. *olen = p - dst;
  542. return( 0 );
  543. }
  544. /*
  545. 将字符串进行base64编码
  546. @api string.toBase64(str)
  547. @string 需要转换的字符串
  548. @return string 解码后的字符串,如果解码失败会返回空字符串
  549. */
  550. int l_str_toBase64(lua_State *L) {
  551. size_t len = 0;
  552. const char* str = luaL_checklstring(L, 1, &len);
  553. if (len == 0) {
  554. lua_pushstring(L, "");
  555. return 1;
  556. }
  557. luaL_Buffer buff = {0};
  558. luaL_buffinitsize(L, &buff, len * 1.5 + 1);
  559. size_t olen = 0;
  560. int re = luat_str_base64_encode((unsigned char *)buff.b, buff.size, &olen, (const unsigned char * )str, len);
  561. if (re == 0) {
  562. luaL_pushresultsize(&buff, olen);
  563. return 1;
  564. }
  565. // 编码失败,返回空字符串, 可能性应该是0吧
  566. lua_pushstring(L, "");
  567. return 1;
  568. }
  569. /*
  570. 将字符串进行base64解码
  571. @api string.fromBase64(str)
  572. @string 需要转换的字符串
  573. @return string 解码后的字符串,如果解码失败会返回空字符串
  574. */
  575. int l_str_fromBase64(lua_State *L) {
  576. size_t len = 0;
  577. const char* str = luaL_checklstring(L, 1, &len);
  578. if (len == 0) {
  579. lua_pushstring(L, "");
  580. return 1;
  581. }
  582. luaL_Buffer buff = {0};
  583. luaL_buffinitsize(L, &buff, len + 1);
  584. size_t olen = 0;
  585. int re = luat_str_base64_decode((unsigned char *)buff.b, buff.size, &olen, (const unsigned char * )str, len);
  586. if (re == 0) {
  587. luaL_pushresultsize(&buff, olen);
  588. return 1;
  589. }
  590. // 编码失败,返回空字符串, 可能性应该是0吧
  591. lua_pushstring(L, "");
  592. return 1;
  593. }
  594. ////////////////////////////////////////////
  595. //// BASE32 /////
  596. ////////////////////////////////////////////
  597. // Copyright 2010 Google Inc.
  598. // Author: Markus Gutschke
  599. // Licensed under the Apache License, Version 2.0 (the "License");
  600. // you may not use this file except in compliance with the License.
  601. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  602. int luat_str_base32_decode(const uint8_t *encoded, uint8_t *result, int bufSize) {
  603. int buffer = 0;
  604. int bitsLeft = 0;
  605. int count = 0;
  606. for (const uint8_t *ptr = encoded; count < bufSize && *ptr; ++ptr) {
  607. uint8_t ch = *ptr;
  608. if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') {
  609. continue;
  610. }
  611. buffer <<= 5;
  612. // Deal with commonly mistyped characters
  613. if (ch == '0') {
  614. ch = 'O';
  615. } else if (ch == '1') {
  616. ch = 'L';
  617. } else if (ch == '8') {
  618. ch = 'B';
  619. }
  620. // Look up one base32 digit
  621. if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
  622. ch = (ch & 0x1F) - 1;
  623. } else if (ch >= '2' && ch <= '7') {
  624. ch -= '2' - 26;
  625. } else {
  626. return -1;
  627. }
  628. buffer |= ch;
  629. bitsLeft += 5;
  630. if (bitsLeft >= 8) {
  631. result[count++] = buffer >> (bitsLeft - 8);
  632. bitsLeft -= 8;
  633. }
  634. }
  635. if (count < bufSize) {
  636. result[count] = '\000';
  637. }
  638. return count;
  639. }
  640. int luat_str_base32_encode(const uint8_t *data, int length, uint8_t *result,
  641. int bufSize) {
  642. if (length < 0 || length > (1 << 28)) {
  643. return -1;
  644. }
  645. int count = 0;
  646. if (length > 0) {
  647. int buffer = data[0];
  648. int next = 1;
  649. int bitsLeft = 8;
  650. while (count < bufSize && (bitsLeft > 0 || next < length)) {
  651. if (bitsLeft < 5) {
  652. if (next < length) {
  653. buffer <<= 8;
  654. buffer |= data[next++] & 0xFF;
  655. bitsLeft += 8;
  656. } else {
  657. int pad = 5 - bitsLeft;
  658. buffer <<= pad;
  659. bitsLeft += pad;
  660. }
  661. }
  662. int index = 0x1F & (buffer >> (bitsLeft - 5));
  663. bitsLeft -= 5;
  664. result[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index];
  665. }
  666. }
  667. if (count < bufSize) {
  668. result[count] = '\000';
  669. }
  670. return count;
  671. }
  672. /*
  673. 将字符串进行base32编码
  674. @api string.toBase32(str)
  675. @string 需要转换的字符串
  676. @return string 解码后的字符串,如果解码失败会返回0长度字符串
  677. */
  678. int l_str_toBase32(lua_State *L) {
  679. size_t len = 0;
  680. const char* str = luaL_checklstring(L, 1, &len);
  681. if (len == 0) {
  682. lua_pushstring(L, "");
  683. return 1;
  684. }
  685. luaL_Buffer buff = {0};
  686. luaL_buffinitsize(L, &buff, len * 2);
  687. int rl = luat_str_base32_encode((const uint8_t * )str,len,(uint8_t *)buff.b,buff.size);
  688. luaL_pushresultsize(&buff, rl);
  689. return 1;
  690. }
  691. /*
  692. 将字符串进行base32解码
  693. @api string.fromBase32(str)
  694. @string 需要转换的字符串
  695. @return string 解码后的字符串,如果解码失败会返回0长度字符串
  696. */
  697. int l_str_fromBase32(lua_State *L) {
  698. size_t len = 0;
  699. const char* str = luaL_checklstring(L, 1, &len);
  700. if (len == 0) {
  701. lua_pushstring(L, "");
  702. return 1;
  703. }
  704. luaL_Buffer buff = {0};
  705. luaL_buffinitsize(L, &buff, len + 1);
  706. int rl = luat_str_base32_decode((const uint8_t * )str,(uint8_t *)buff.b,buff.size);
  707. if (rl > 0 && rl <= len + 1) {
  708. luaL_pushresultsize(&buff, rl);
  709. }
  710. else {
  711. lua_pushstring(L, "");
  712. }
  713. return 1;
  714. }
  715. /*
  716. 判断字符串前缀
  717. @api string.startsWith(str, prefix)
  718. @string 需要检查的字符串
  719. @string 前缀字符串
  720. @return bool 真为true, 假为false
  721. @usage
  722. local str = "abc"
  723. log.info("str", str:startsWith("a"))
  724. log.info("str", str:startsWith("b"))
  725. */
  726. int l_str_startsWith(lua_State *L) {
  727. size_t str_len = 0;
  728. size_t prefix_len = 0;
  729. const char* str = luaL_checklstring(L, 1, &str_len);
  730. const char* prefix = luaL_checklstring(L, 2, &prefix_len);
  731. if (str_len < prefix_len) {
  732. lua_pushboolean(L, 0);
  733. }
  734. else if (memcmp(str, prefix, prefix_len) == 0) {
  735. lua_pushboolean(L, 1);
  736. }
  737. else {
  738. lua_pushboolean(L, 0);
  739. }
  740. return 1;
  741. }
  742. /*
  743. 判断字符串后缀
  744. @api string.endsWith(str, suffix)
  745. @string 需要检查的字符串
  746. @string 后缀字符串
  747. @return bool 真为true, 假为false
  748. @usage
  749. local str = "abc"
  750. log.info("str", str:endsWith("c"))
  751. log.info("str", str:endsWith("b"))
  752. */
  753. int l_str_endsWith(lua_State *L) {
  754. size_t str_len = 0;
  755. size_t suffix_len = 0;
  756. const char* str = luaL_checklstring(L, 1, &str_len);
  757. const char* suffix = luaL_checklstring(L, 2, &suffix_len);
  758. // LLOGD("%s %d : %s %d", str, str_len, suffix, suffix_len);
  759. if (str_len < suffix_len) {
  760. lua_pushboolean(L, 0);
  761. }
  762. else if (memcmp(str + (str_len - suffix_len), suffix, suffix_len) == 0) {
  763. lua_pushboolean(L, 1);
  764. }
  765. else {
  766. lua_pushboolean(L, 0);
  767. }
  768. return 1;
  769. }
  770. #include "lstate.h"
  771. int l_str_strs(lua_State *L) {
  772. for (size_t i = 0; i < STRCACHE_N; i++)
  773. {
  774. TString **p = G(L)->strcache[i];
  775. for (size_t j = 0; j < STRCACHE_M; j++) {
  776. if (p[j]->tt == LUA_TSHRSTR)
  777. LLOGD(">> %s", getstr(p[j]));
  778. }
  779. }
  780. return 0;
  781. }
  782. int l_str_trim_impl(lua_State *L, int ltrim, int rtrim) {
  783. size_t str_len = 0;
  784. const char* str = luaL_checklstring(L, 1, &str_len);
  785. if (str_len == 0) {
  786. lua_pushvalue(L, 1);
  787. return 1;
  788. }
  789. int begin = 0;
  790. int end = str_len;
  791. if (ltrim) {
  792. for (; begin <= end; begin++)
  793. {
  794. //LLOGD("ltrim %02X %d %d", str[begin], begin, end);
  795. if(str[begin] != ' ' &&
  796. str[begin] != '\t' &&
  797. str[begin] != '\n' &&
  798. str[begin] != '\r')
  799. {
  800. break;
  801. }
  802. }
  803. }
  804. if (rtrim) {
  805. for (; begin < end; end--)
  806. {
  807. //LLOGD("rtrim %02X %d %d", str[end], begin, end);
  808. if(str[end - 1] != ' ' &&
  809. str[end - 1] != '\t' &&
  810. str[end - 1] != '\n' &&
  811. str[end - 1] != '\r')
  812. {
  813. break;
  814. }
  815. }
  816. }
  817. if (begin == end) {
  818. lua_pushliteral(L, "");
  819. }
  820. else {
  821. lua_pushlstring(L, str + begin, end - begin);
  822. }
  823. return 1;
  824. }
  825. /*
  826. 裁剪字符串,去除头尾的空格
  827. @api string.trim(str, ltrim, rtrim)
  828. @string 需要处理的字符串
  829. @bool 清理前缀,默认为true
  830. @bool 清理后缀,默认为true
  831. @return string 清理后的字符串
  832. @usage
  833. local str = "\r\nabc\r\n"
  834. log.info("str", string.trim(str)) -- 打印 "abc"
  835. log.info("str", str:trim()) -- 打印 "abc"
  836. log.info("str", #string.trim(str, false, true)) -- 仅裁剪后缀,所以长度是5
  837. */
  838. int l_str_trim(lua_State *L) {
  839. int ltrim = 1;
  840. int rtrim = 1;
  841. if (lua_isboolean(L, 2))
  842. ltrim = lua_toboolean(L, 2);
  843. if (lua_isboolean(L, 3))
  844. rtrim = lua_toboolean(L, 3);
  845. return l_str_trim_impl(L, ltrim, rtrim);
  846. }