lstrlib_exts.c 19 KB

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