/** * @param: the string (at stack -1) * @return: the quoted string (push to stack -1) */ static int l_repr_string(lua_State *L) { size_t size; const char *src = lua_tolstring(L, -1, &size); /* calculate the single-quote vs. double-quote */ size_t single_quote=0, double_quote=0; for (size_t i=0; i<size; i++) { if (src[i] == '"') ++double_quote; if (src[i] == '\'') ++single_quote; } char quote = (double_quote > single_quote) ? '\'' : '"'; wchar_t wstr[size+1]; size_t retsize = mbstowcs(wstr, src, size+1); /* start of luaL_Buffer */ luaL_Buffer b; luaL_buffinit(L, &b); luaL_addchar(&b, quote); /* if not a valid utf-8 string we use isprint() to check printable char */ if (retsize == (size_t)-1) { for (; size--; src++) { switch (*src) { case '\\': luaL_addlstring(&b, "\\\\", 2); break; case '\r': luaL_addlstring(&b, "\\r", 2); break; case '\n': luaL_addlstring(&b, "\\n", 2); break; default: if (*src == quote) { luaL_addchar(&b, '\\'); luaL_addchar(&b, quote); } else if (isprint(*src)) { luaL_addchar(&b, *src); } else { char repr_char[5]; /* forget to cast unsigned leads to segmentation fault */ sprintf(repr_char, "\\%03u", (unsigned char)(*src)); luaL_addlstring(&b, repr_char, 4); } break; } } } else { /* for utf-8 string we use iswprint() */ for (size_t i = 0; i < retsize; i++) { switch (wstr[i]) { case L'\\': luaL_addlstring(&b, "\\\\", 2); break; case L'\r': luaL_addlstring(&b, "\\r", 2); break; case L'\n': luaL_addlstring(&b, "\\n", 2); break; default: if (wstr[i] == (wchar_t)quote) { luaL_addchar(&b, '\\'); luaL_addchar(&b, quote); } else { char utf8str[MB_CUR_MAX]; int wssize = wctomb(utf8str, wstr[i]); /* most utf-8 character should be printable */ if (iswprint(wstr[i])) { luaL_addlstring(&b, utf8str, wssize); } else { char repr_char[wssize*4+1]; for (int j=0; j<wssize; j++) { /* forget to cast unsigned leads to segmentation fault */ sprintf(repr_char, "\\%03u", (unsigned char)utf8str[j]); luaL_addlstring(&b, repr_char, 4); } } } break; } } size_t zs = strlen(src); if (zs != size) { for (; zs<size; zs++) { switch (src[zs]) { case '\\': luaL_addlstring(&b, "\\\\", 2); break; case '\r': luaL_addlstring(&b, "\\r", 2); break; case '\n': luaL_addlstring(&b, "\\n", 2); break; default: if (src[zs] == quote) { luaL_addchar(&b, '\\'); luaL_addchar(&b, quote); } else if (isprint(src[zs])) { luaL_addchar(&b, src[zs]); } else { char repr_char[5]; /* forget to cast unsigned leads to segmentation fault */ sprintf(repr_char, "\\%03u", (unsigned char)(src[zs])); luaL_addlstring(&b, repr_char, 4); } break; } } } } luaL_addchar(&b, quote); luaL_pushresult(&b); /* end of luaL_Buffer */ return 1; }
int lsp::read_request_data(lua_State *L) { FCGX_Request* r = (FCGX_Request*)luaL_lsp_get_io_ctx(L); const char* p=FCGX_GetParam("CONTENT_LENGTH", r->envp); int content_length = p? atoi(p) : -1; if(content_length < 0) return 411;//HTTP_LENGTH_REQUIRED; // TODO: for max post? if(content_length > 4096) return 400;//HTTP_BAD_REQUEST; int retval = 0; luaL_Buffer buf; luaL_buffinit(L,&buf); //if(ap_should_client_block(apr)) { char *tmp = new char[1024]; int len = 0; while(len<content_length) { int n = content_length - len; //n = ap_get_client_block(apr,tmp,n>sizeof(tmp)?sizeof(tmp):n); n = FCGX_GetStr(tmp, n > 1024 ? 1024 : n, r->in); if(n <= 0) break; len += n; luaL_addlstring(&buf,tmp,n); } if(len!=content_length) retval = -1;//HTTP_REQUEST_TIME_OUT; delete[] tmp; } const char* content_type = FCGX_GetParam("CONTENT_TYPE", r->envp); int n = lua_gettop(L); if(content_type && !strcmp(content_type,"application/x-www-form-urlencoded")) { lua_getglobal(L,"args_decode"); luaL_pushresult(&buf); if(lua_isfunction(L,-2) && !lua_pcall(L,1,1,0)) lua_setglobal(L,"args_post"); } else { lua_getfield(L,LUA_GLOBALSINDEX,"env"); luaL_pushresult(&buf); if(lua_istable(L,-2)) lua_setfield(L,-2,"content"); } lua_pop(L,lua_gettop(L)-n); return retval; }
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { luaL_addlstring(B, s, strlen(s)); }
static int str_pack (lua_State *L) { luaL_Buffer b; Header h; const char *fmt = luaL_checkstring(L, 1); /* format string */ int arg = 1; /* current argument to pack */ size_t totalsize = 0; /* accumulate total size of result */ initheader(L, &h); lua_pushnil(L); /* mark to separate arguments from string buffer */ luaL_buffinit(L, &b); while (*fmt != '\0') { int size, ntoalign; KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); totalsize += ntoalign + size; while (ntoalign-- > 0) luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ arg++; switch (opt) { case Kint: { /* signed integers */ lua_Integer n = luaL_checkinteger(L, arg); if (size < SZINT) { /* need overflow check? */ lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); } packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); break; } case Kuint: { /* unsigned integers */ lua_Integer n = luaL_checkinteger(L, arg); if (size < SZINT) /* need overflow check? */ luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), arg, "unsigned overflow"); packint(&b, (lua_Unsigned)n, h.islittle, size, 0); break; } case Kfloat: { /* floating-point options */ volatile Ftypes u; char *buff = luaL_prepbuffsize(&b, size); lua_Number n = luaL_checknumber(L, arg); /* get argument */ if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ else if (size == sizeof(u.d)) u.d = (double)n; else u.n = n; /* move 'u' to final result, correcting endianness if needed */ copywithendian(buff, u.buff, size, h.islittle); luaL_addsize(&b, size); break; } case Kchar: { /* fixed-size string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, len <= (size_t)size, arg, "string longer than given size"); luaL_addlstring(&b, s, len); /* add string */ while (len++ < (size_t)size) /* pad extra space */ luaL_addchar(&b, LUAL_PACKPADBYTE); break; } case Kstring: { /* strings with length count */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, size >= (int)sizeof(size_t) || len < ((size_t)1 << (size * NB)), arg, "string length does not fit in given size"); packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ luaL_addlstring(&b, s, len); totalsize += len; break; } case Kzstr: { /* zero-terminated string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); luaL_addlstring(&b, s, len); luaL_addchar(&b, '\0'); /* add zero at the end */ totalsize += len + 1; break; } case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ case Kpaddalign: case Knop: arg--; /* undo increment */ break; } } luaL_pushresult(&b); return 1; }
static int writer (lua_State *L, const void* b, size_t size, void* B) { (void)L; luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); return 0; }
int str_format_helper (luaL_Buffer* b, lua_State *L, int arg) { size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_buffinit(L, b); while (strfrmt < strfrmt_end) { if (*strfrmt != '%') luaL_putchar(b, *strfrmt++); else if (*++strfrmt == '%') luaL_putchar(b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ int hasprecision = 0; if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$') return luaL_error(L, "obsolete option (d$) to `format'"); arg++; strfrmt = scanformat(L, strfrmt, form, &hasprecision); switch (*strfrmt++) { case 'c': case 'd': case 'i': { sprintf(buff, form, luaL_checkint(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg))); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { sprintf(buff, form, luaL_checknumber(L, arg)); break; } case 'q': { luaI_addquoted(L, b, arg); continue; /* skip the `addsize' at the end */ } case 'Q': { luaI_addquotedbinary(L, b, arg); continue; /* skip the `addsize' at the end */ } case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (!hasprecision && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(b); continue; /* skip the `addsize' at the end */ } else { sprintf(buff, form, s); break; } } case 'b': { buff[1] = buff[2] = buff[3] = buff[4] = buff[5] = buff[6] = buff[7] = buff[8] = 0; switch (*strfrmt++) { case 'b': { unsigned int num = (unsigned int)luaL_checkint(L, arg); buff[0] = (unsigned char)num; luaL_addlstring(b, buff, 1); break; } case 'd': { unsigned int num = (unsigned int)luaL_checkint(L, arg); *(unsigned int*)(&buff) = num; luaL_addlstring(b, buff, 4); break; } case 'w': { unsigned int num = (unsigned int)luaL_checkint(L, arg); *(unsigned short*)(&buff) = (unsigned short)num; luaL_addlstring(b, buff, 2); break; } case 'f': { float numF = (float)luaL_checknumber(L, arg); *(float*)(&buff) = numF; luaL_addlstring(b, buff, 4); break; } case 'F': { double numD = (double)luaL_checknumber(L, arg); *(double*)(&buff) = numD; luaL_addlstring(b, buff, 8); break; } default: break; } buff[0] = 0; break; } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option to `format'"); } } luaL_addlstring(b, buff, strlen(buff)); } } return 1; }
static int str_format (lua_State *L) { int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != '%') luaL_putchar(&b, *strfrmt++); else if (*++strfrmt == '%') luaL_putchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ int hasprecision = 0; if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$') return luaL_error(L, "obsolete option (d$) to `format'"); arg++; strfrmt = scanformat(L, strfrmt, form, &hasprecision); switch (*strfrmt++) { case 'c': case 'd': case 'i': { sprintf(buff, form, luaL_checkint(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg))); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { sprintf(buff, form, luaL_checknumber(L, arg)); break; } case 'q': { luaI_addquoted(L, &b, arg); continue; /* skip the `addsize' at the end */ } case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (!hasprecision && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(&b); continue; /* skip the `addsize' at the end */ } else { sprintf(buff, form, s); break; } } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option to `format'"); } } luaL_addlstring(&b, buff, strlen(buff)); } } luaL_pushresult(&b); return 1; }
static size_t Lwriter(void *ud, mz_uint64 file_ofs, const void *p, size_t n) { (void)file_ofs; luaL_addlstring((luaL_Buffer*)ud, p, n); return n; }
static int tek_lib_exec_write(lua_State *L, const void *p, size_t sz, void *ud) { luaL_Buffer *b = ud; luaL_addlstring(b, p, sz); return 0; }
static int b_pack (lua_State *L) { luaL_Buffer b; int native; const char *fmt = luaL_checkstring(L, 1); int endian = getendianess(&fmt, &native); int align = getalign(&fmt); int arg = 2; int totalsize = 0; void *p; lua_pushnil(L); /* mark to separate arguments from string buffer */ luaL_buffinit(L, &b); for (; *fmt; arg++) { int opt = *fmt++; int size = optsize(opt, &fmt); int toalign = gettoalign(L, align, opt, size); while ((totalsize&(toalign-1)) != 0) { luaL_putchar(&b, '\0'); totalsize++; } switch (opt) { case ' ': break; /* ignore white spaces */ case 'b': case 'B': case 'h': case 'H': case 'l': case 'L': case 'i': case 'I': { /* integer types */ putinteger(L, &b, arg, endian, size); break; } case 'x': { arg--; /* undo increment */ luaL_putchar(&b, '\0'); break; } case 'f': { float f = (float)luaL_checknumber(L, arg); if (endian != native) invertbytes((char *)&f, size); luaL_addlstring(&b, (char *)&f, size); break; } case 'd': { double d = luaL_checknumber(L, arg); if (endian != native) invertbytes((char *)&d, size); luaL_addlstring(&b, (char *)&d, size); break; } case 'c': case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (size == 0) size = l; luaL_argcheck(L, l >= (size_t)size, arg, "string too short"); luaL_addlstring(&b, s, size); if (opt == 's') { luaL_putchar(&b, '\0'); /* add zero at the end */ size++; } break; } case 'p': { luaL_argcheck(L, lua_isuserdata(L, arg) || lua_isnil(L, arg), arg, "userdata, light userdata, or nil required"); p = lua_touserdata(L, arg); luaL_addlstring(&b, (char*)&p, size); break; } default: invalidformat(L, opt); } totalsize += size; } luaL_pushresult(&b); return 1; }
int libmcache::lua_mcache_get(lua_State* L) { int top=lua_gettop(L); LMCACHE* mcache=(LMCACHE*)luaL_checkudata(L,1,LUA_MCACHE); if(!mcache->fp) return luaL_error(L,err_closed); const char* key=luaL_checkstring(L,2); fprintf(mcache->fp,"get %s\r\n",key); fflush(mcache->fp); char result[512]; static const char end_tag[]="END"; static const char value_tag[]="VALUE"; for(;;) { if(!fgets(result,sizeof(result),mcache->fp)) { lua_mcache_close(mcache); return luaL_error(L,err_io); } char* p=strchr(result,'\r'); if(p) *p=0; if(!strncmp(result,end_tag,sizeof(end_tag)-1)) break; if(strncmp(result,value_tag,sizeof(value_tag)-1)) { lua_mcache_close(mcache); return luaL_error(L,err_invalid_server_response,result); } char* len=lua_mcache_find_substring_by_id(result+(sizeof(value_tag)-1),2); if(!len) { lua_mcache_close(mcache); return luaL_error(L,err_invalid_server_response,result); } p=strchr(len,' '); if(p) *p=0; size_t length=atol(len); luaL_Buffer buf; luaL_buffinit(L,&buf); size_t l=0; while(l<length) { size_t m=length-l; size_t n=fread(result,1,m<sizeof(result)?m:sizeof(result),mcache->fp); if(!n) break; luaL_addlstring(&buf,result,n); l+=n; } luaL_pushresult(&buf); if(l!=length || !fgets(result,sizeof(result),mcache->fp)) { lua_mcache_close(mcache); return luaL_error(L,err_io); } } return lua_gettop(L)-top; }
static int l_pack(lua_State *L) /* pack(s,...) */ { int i,j; const char *s=luaL_checkstring(L,1); luaL_Buffer b; luaL_buffinit(L,&b); for (i=0, j=2; s[i]; i++, j++) { int c=s[i]; switch (c) { case 'A': { size_t l; const char *a=luaL_checklstring(L,j,&l); luaL_addlstring(&b,(void*)&l,sizeof(l)); luaL_addlstring(&b,a,l); break; } case 'n': { lua_Number a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'd': { double a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'f': { float a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'c': { char a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'C': { unsigned char a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 's': { short a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'S': { unsigned short a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'i': { int a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'I': { unsigned int a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'l': { long a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case 'L': { unsigned long a=luaL_checknumber(L,j); luaL_addlstring(&b,(void*)&a,sizeof(a)); break; } case '_': { break; } default: badmode(L,c); break; } } luaL_pushresult(&b); return 1; }
/* according to send routines in pqformat */ void lpq_senduint32 (luaL_Buffer *b, uint32 n32) { n32 = htonl(n32); luaL_addlstring(b, (const char *) &n32, 4); }
/** * @param: the table (at stack 1) * @param: the cycle table (at stack 2) * @return: the table string */ static int l_pretty_repr_table(lua_State *L) { lua_pushvalue(L, 1); /* duplicate the table in stack 3 */ lua_rawget(L, 2); /* get from the cycle table 2 */ if (lua_isnil(L, -1)) { lua_pop(L, 1); /* save the table item into cycle table */ lua_pushfstring(L, "table_(%p)", lua_topointer(L, 1)); /* put in stack 3 */ lua_pushvalue(L, 1); /* push key in stack 4 */ lua_pushvalue(L, 3); /* push value in stack 5 */ lua_rawset(L, 2); /* adjust the cycle table and pop 4,5 */ /* save the level into cycle table */ lua_pushliteral(L, "level"); lua_rawget(L, 2); /* get the level into stack 4 */ int level = 1; if (!lua_isnil(L, -1)) { level += lua_tointeger(L, -1); } lua_pushliteral(L, "level"); lua_pushinteger(L, level); lua_rawset(L, 2); /* save the level and pop 5,6 */ /* luaL_Buffer START */ luaL_Buffer b; luaL_buffinit(L, &b); if (1) { luaL_addlstring(&b, "{\n", 2); } else { /* optional: suffix a pointer behind */ lua_pushfstring(L, "{ -- %p\n", lua_topointer(L, 1)); luaL_addvalue(&b); /* add the pointer value into buffer */ } /* iterate the table */ for (lua_pushnil(L); lua_next(L, 1) != 0; lua_pushvalue(L, 4)) { lua_replace(L, 3); /* backups the value in stack 3 */ lua_replace(L, 4); /* backups the key in stack 4 */ for (int i=level; i--; ) luaL_addchar(&b, '\t'); /* repr the key */ lua_pushcfunction(L, l_repr_key); lua_pushvalue(L, 4); lua_pushvalue(L, 2); lua_call(L, 2, 1); luaL_addvalue(&b); /* add the return value into buffer */ luaL_addlstring(&b, " = ", 3); /* repr the value */ lua_pushcfunction(L, l_pretty_repr_slice); lua_pushvalue(L, 3); lua_pushvalue(L, 2); lua_call(L, 2, 1); luaL_addvalue(&b); /* add the return value into buffer */ luaL_addlstring(&b, ",\n", 2); } --level; /* decrease level when table finished */ for (int i=level; i--; ) luaL_addchar(&b, '\t'); luaL_addchar(&b, '}'); luaL_pushresult(&b); /* luaL_Buffer END */ lua_pushliteral(L, "level"); lua_pushinteger(L, level); lua_rawset(L, 2); /* save the level and pop */ } else { /* just use the return value of gettable as the result */ } return 1; }
static int str_format (lua_State *L) { int arg = 1; const char *strfrmt = luaL_check_string(L, arg); luaL_Buffer b; luaL_buffinit(L, &b); while (*strfrmt) { if (*strfrmt != '%') luaL_putchar(&b, *strfrmt++); else if (*++strfrmt == '%') luaL_putchar(&b, *strfrmt++); /* %% */ else { /* format item */ struct Capture cap; char form[MAX_FORMAT]; /* to store the format ('%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ const char *initf = strfrmt; form[0] = '%'; if (isdigit((unsigned char)*initf) && *(initf+1) == '$') { arg = *initf - '0'; initf += 2; /* skip the 'n$' */ } arg++; cap.src_end = strfrmt+strlen(strfrmt)+1; cap.level = 0; strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */ strfrmt-initf > MAX_FORMAT-2) lua_error(L, "invalid format (width or precision too long)"); strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ form[strfrmt-initf+2] = 0; switch (*strfrmt++) { case 'c': case 'd': case 'i': sprintf(buff, form, luaL_check_int(L, arg)); break; case 'o': case 'u': case 'x': case 'X': sprintf(buff, form, (unsigned int)luaL_check_number(L, arg)); break; case 'e': case 'E': case 'f': case 'g': case 'G': sprintf(buff, form, luaL_check_number(L, arg)); break; case 'q': luaI_addquoted(L, &b, arg); continue; /* skip the "addsize" at the end */ case 's': { size_t l; const char *s = luaL_check_lstr(L, arg, &l); if (cap.capture[1].len == 0 && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(&b); continue; /* skip the "addsize" at the end */ } else { sprintf(buff, form, s); break; } } default: /* also treat cases 'pnLlh' */ lua_error(L, "invalid option in `format'"); } luaL_addlstring(&b, buff, strlen(buff)); } } luaL_pushresult(&b); return 1; }
/**-------------------------------------------------------------------------- * Finish of sending the T.Http.Message response. * \param L The lua state. * \lparam Http.Message instance. * \lparam string. * \return int # of values pushed onto the stack. * --------------------------------------------------------------------------*/ static int lt_htp_str_finish( lua_State *L ) { struct t_htp_str *s = t_htp_str_check_ud( L, 1, 1 ); size_t sz; /// length of optional string handed in char *b; size_t c = 0; luaL_Buffer lB; // the first action ever called on the stream, prep header first if (T_HTP_STR_SEND != s->state) { luaL_checklstring( L, 2, &sz ); luaL_buffinit( L, &lB ); c = t_htp_str_formHeader( L, &lB, s, 200, NULL, (int) sz, 0 ); lua_pushvalue( L, 2 ); luaL_addvalue( &lB ); luaL_pushresult( &lB ); t_htp_str_addbuffer( L, s, lB.n, 1 ); } else { if (LUA_TSTRING == lua_type( L, 2 )) { luaL_checklstring( L, 2, &sz ); if (! s->rsCl) // chunked { luaL_buffinit( L, &lB ); b = luaL_prepbuffer( &lB ); c = sprintf( b, "%zx\r\n", sz ); luaL_addsize( &lB, c ); lua_pushvalue( L, 2 ); luaL_addvalue( &lB ); luaL_addlstring( &lB, "\r\n0\r\n\r\n", 7 ); luaL_pushresult( &lB ); t_htp_str_addbuffer( L, s, lB.n, 1 ); } else { lua_pushvalue( L, 2 ); t_htp_str_addbuffer( L, s, sz, 1 ); } } else { if (! s->rsCl) // chunked { lua_pushstring( L, "0\r\n\r\n" ); t_htp_str_addbuffer( L, s, 5, 1 ); } } } /*if ( 0 == s->obc ) { if ( ! s->kpAlv) { lua_pushcfunction( L, lt_htp_str__gc ); lua_pushvalue( L, 1 ); lua_call( L, 1, 0 ); } else s->state = T_htp_str_S_ZERO; } */ s->state = T_HTP_STR_FINISH; return 0; }
static void sendint16 (luaL_Buffer *b, int16 i) { uint16 u = htons((uint16) i); luaL_addlstring(b, (const char *) &u, sizeof(uint16)); }
static void serialize_value(lua_State *L, int pos, luaL_Buffer* frame, int* indice, uint16_t* key) { if (!lua_checkstack(L, 2)) { luaL_error(L, "cannot serialize: stack won't grow"); } uint8_t type = get_luatobin_type(L, pos); switch (type) { case BIN_NIL: { //printf("(nil[1])"); lua_pushlstring(L, (char *) &type, 1); write_object(L, indice); break; } case BIN_BOOLEAN: { //printf("(boolean[2])"); int boolean = lua_toboolean(L, pos); luaL_buffinit(L, frame); luaL_addchar(frame, type); luaL_addchar(frame, boolean & 0xFF); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_DOUBLE: { double number = lua_tonumber(L, pos); luaL_buffinit(L, frame); luaL_addchar(frame, type); //printf("(number[%d])", sizeof(number)); if (sendian.double_) hton(&number, sizeof(number), sendian.double_); luaL_addlstring(frame, (char*) &number, sizeof(number)); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_INTEGER: { int32_t number = lua_tointeger(L, pos); luaL_buffinit(L, frame); luaL_addchar(frame, type); //printf("(number[%d])", sizeof(number)); if (sendian.int32_) hton(&number, sizeof(number), sendian.int32_); luaL_addlstring(frame, (char*) &number, sizeof(number)); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_STRING: { uint16_t cached = verify_cache(L, pos, key); if (cached != 0) { //printf("(stringref[%d])", cached); luaL_buffinit(L, frame); luaL_addchar(frame, BIN_REF); if (sendian.int16_) hton(&cached, sizeof(cached), sendian.int16_); luaL_addlstring(frame, (char*) &cached, sizeof(cached)); luaL_pushresult(frame); write_object(L, indice); break; } size_t s; const char* string = lua_tolstring(L, pos, &s); if (s >= 0xFFFF) luaL_error(L, "cannot serialize: string length > 65k"); uint16_t size = (uint16_t) s; luaL_buffinit(L, frame); luaL_addchar(frame, type); uint16_t nsize = size; if (sendian.int16_) hton(&nsize, sizeof(nsize), sendian.int16_); luaL_addlstring(frame, (char*) &nsize, sizeof(nsize)); //printf("(string[%d][%d])", *key, size); luaL_addlstring(frame, string, size); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_FUNCTION: { uint16_t cached = verify_cache(L, pos, key); if (cached != 0) { //printf("(functionref[%d])", cached); luaL_buffinit(L, frame); luaL_addchar(frame, BIN_REF); if (sendian.int16_) hton(&cached, sizeof(cached), sendian.int16_); luaL_addlstring(frame, (char*) &cached, sizeof(cached)); luaL_pushresult(frame); write_object(L, indice); break; } serialize_function(L, frame, pos); size_t s; const char* string = lua_tolstring(L, -1, &s); if (s >= 0xFFFF) luaL_error(L, "cannot serialize: function length > 65k"); uint16_t size = (uint16_t) s; luaL_buffinit(L, frame); luaL_addchar(frame, type); uint16_t nsize = size; if (sendian.int16_) hton(&nsize, sizeof(nsize), sendian.int16_); luaL_addlstring(frame, (char*) &nsize, sizeof(nsize)); //printf("(function[%d][%d])", *key, size); luaL_addlstring(frame, string, size); luaL_pushresult(frame); write_object(L, indice); lua_pop(L, 1); // remove the serialized function break; } case BIN_TABLE: { uint16_t cached = verify_cache(L, pos, key); if (cached != 0) { //printf("(tableref[%d])", cached); luaL_buffinit(L, frame); luaL_addchar(frame, BIN_REF); if (sendian.int16_) hton(&cached, sizeof(cached), sendian.int16_); luaL_addlstring(frame, (char*) &cached, sizeof(cached)); luaL_pushresult(frame); write_object(L, indice); break; } // reserved for table header (as size cannot be calculated beforehand) *indice = *indice + 1; int header = *indice; //printf("{table="); int top; size_t s = 0; lua_pushnil(L); while (lua_next(L, pos) != 0) { top = lua_gettop(L); serialize_value(L, top - 1, frame, indice, key); serialize_value(L, top, frame, indice, key); lua_pop(L, 1); s++; } if (s >= 0xFFFF) luaL_error(L, "cannot serialize: table length > 65k"); uint16_t size = (uint16_t) s; luaL_buffinit(L, frame); luaL_addchar(frame, type); uint16_t nsize = size; if (sendian.int16_) hton(&nsize, sizeof(nsize), sendian.int16_); luaL_addlstring(frame, (char*) &nsize, sizeof(nsize)); luaL_pushresult(frame); // set table header lua_rawseti(L, 3, header); //printf("[%d]}", size); break; } default: luaL_error(L, "cannot serialize: unsupported type (%d)", lua_type(L, pos)); } }
int rx_gsub (lua_State *L, int is_function, int is_wide) { size_t len, flen; TFarRegex* fr; FARAPIREGEXPCONTROL RegExpControl = GetRegExpControl(L); const wchar_t *s, *f; int max_rep_capture, ftype, n, matches, reps; luaL_Buffer out; struct RegExpSearch data; memset(&data, 0, sizeof(data)); if (is_function) { if (is_wide) data.Text = check_utf16_string(L, 1, &len); else data.Text = check_utf8_string(L, 1, &len); fr = push_far_regex(L, RegExpControl, check_regex_pattern(L, 2, 5)); lua_replace(L, 2); } else { fr = CheckFarRegex(L, 1); if (is_wide) data.Text = check_utf16_string(L, 2, &len); else data.Text = check_utf8_string(L, 2, &len); } data.Length = len; s = data.Text; f = NULL; flen = 0; max_rep_capture = 0; ftype = lua_type(L, 3); if (ftype == LUA_TSTRING) { const wchar_t* p; f = check_utf8_string(L, 3, &flen); for (p=f; *p; p++) { if (*p == L'%') { int n, ch; if ((ch = *++p) == 0) break; n = (ch >= L'0' && ch <= L'9') ? ch - L'0' : (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 : (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1; if (max_rep_capture < n) max_rep_capture = n; } } } else if (ftype != LUA_TTABLE && ftype != LUA_TFUNCTION) luaL_argerror(L, 3, "string or table or function"); if (lua_isnoneornil(L, 4)) n = -1; else { n = (int)luaL_checkinteger(L, 4); if (n < 0) n = 0; } lua_settop(L, 3); data.Count = RegExpControl(fr->hnd, RECTL_BRACKETSCOUNT, 0, 0); if ( (ftype == LUA_TSTRING) && !(max_rep_capture == 1 && data.Count == 1) && (data.Count <= max_rep_capture)) luaL_error(L, "replace string: invalid capture index"); data.Match = (struct RegExpMatch*)lua_newuserdata(L, data.Count*sizeof(struct RegExpMatch)); data.Match[0].end = -1; matches = reps = 0; luaL_buffinit(L, &out); while (n < 0 || reps < n) { int rep; intptr_t from, to; intptr_t prev_end = data.Match[0].end; if (!RegExpControl(fr->hnd, RECTL_SEARCHEX, 0, &data)) break; if (data.Match[0].end == prev_end) { if (data.Position < data.Length) { luaL_addlstring(&out, (const char*)(s+data.Position), sizeof(wchar_t)); data.Position++; continue; } break; } matches++; rep = 0; from = data.Match[0].start; to = data.Match[0].end; luaL_addlstring(&out, (const char*)(s + data.Position), (from - data.Position) * sizeof(wchar_t)); if (ftype == LUA_TSTRING) { size_t i, start = 0; for (i=0; i<flen; i++) { if (f[i] == L'%') { if (++i < flen) { int ch = f[i]; int n = (ch >= L'0' && ch <= L'9') ? ch - L'0' : (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 : (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1; if (n >= 0) { if (n==1 && data.Count==1) n = 0; luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t)); if (data.Match[n].start >= 0) { luaL_addlstring(&out, (const char*)(s + data.Match[n].start), (data.Match[n].end - data.Match[n].start) * sizeof(wchar_t)); } } else { // delete the percent sign luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t)); luaL_addlstring(&out, (const char*)(f+i), sizeof(wchar_t)); } start = i+1; } else { luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t)); start = flen; break; } } } rep++; luaL_addlstring(&out, (const char*)(f+start), (flen-start)*sizeof(wchar_t)); } else if (ftype == LUA_TTABLE) { int n = data.Count==1 ? 0:1; if (data.Match[n].start >= 0) { if (is_wide) push_utf16_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start)); else push_utf8_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start)); lua_gettable(L, 3); if (lua_isstring(L, -1)) { if (!is_wide) { size_t len; const wchar_t* ws = check_utf8_string(L, -1, &len); lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t)); lua_remove(L, -2); } luaL_addvalue(&out); rep++; } else if (lua_toboolean(L,-1)) luaL_error(L, "invalid replacement type"); else lua_pop(L, 1); } } else { // if (ftype == LUA_TFUNCTION) intptr_t i, skip = data.Count==1 ? 0:1; lua_checkstack(L, (int)(data.Count+1-skip)); lua_pushvalue(L, 3); for (i=skip; i<data.Count; i++) { if (data.Match[i].start >= 0) { if (is_wide) push_utf16_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start)); else push_utf8_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start)); } else lua_pushboolean(L, 0); } if (lua_pcall(L, (int)(data.Count-skip), 1, 0) == 0) { if (lua_isstring(L, -1)) { if (!is_wide) { size_t len; const wchar_t* ws = check_utf8_string(L, -1, &len); lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t)); lua_remove(L, -2); } luaL_addvalue(&out); rep++; } else if (lua_toboolean(L,-1)) luaL_error(L, "invalid return type"); else lua_pop(L, 1); } else luaL_error(L, lua_tostring(L, -1)); } if (rep) reps++; else luaL_addlstring(&out, (const char*)(s+from), (to-from)*sizeof(wchar_t)); if (data.Position < to) data.Position = to; else if (data.Position < data.Length) { luaL_addlstring(&out, (const char*)(s + data.Position), sizeof(wchar_t)); data.Position++; } else break; } luaL_addlstring(&out, (const char*)(s + data.Position), (data.Length - data.Position) * sizeof(wchar_t)); luaL_pushresult(&out); if (!is_wide) { push_utf8_string(L, (const wchar_t*)lua_tostring(L, -1), lua_objlen(L, -1) / sizeof(wchar_t)); } lua_pushinteger(L, matches); lua_pushinteger(L, reps); return 3; }
static int lua_util_win1251toUTF8(lua_State* L) { static const unsigned char win2utf_lead_tab[]= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 }; static const unsigned char win2utf_tab[]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0x81, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0x91, 0x4e, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f }; const unsigned char* s=(unsigned char*)lua_tostring(L,1); if(!s) return 0; luaL_Buffer B; luaL_buffinit(L,&B); unsigned char tmp[128]; int n=0; while(*s) { if(n>sizeof(tmp)-2) { luaL_addlstring(&B,(char*)tmp,n); n=0; } if(win2utf_lead_tab[*s]) { tmp[n++]=win2utf_lead_tab[*s]; tmp[n++]=win2utf_tab[*s]; }else tmp[n++]=win2utf_tab[*s]; s++; } if(n>0) luaL_addlstring(&B,(char*)tmp,n); luaL_pushresult(&B); return 1; }
/* writer function for lua_dump */ static int luaproc_buff_writer( lua_State *L, const void *buff, size_t size, void *ud ) { (void)L; luaL_addlstring((luaL_Buffer *)ud, (const char *)buff, size ); return 0; }
void lua_syck_output_handler(SyckEmitter *e, char *str, long len) { struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus; luaL_addlstring(&bonus->output, str, len); }
static int str_format (lua_State *L) { int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) luaL_addchar(&b, *strfrmt++); else if (*++strfrmt == L_ESC) luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ arg++; strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { sprintf(buff, form, (int)luaL_checknumber(L, arg)); break; } case 'd': case 'i': { addintlen(form); sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { addintlen(form); sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { sprintf(buff, form, (double)luaL_checknumber(L, arg)); break; } case 'q': { addquoted(L, &b, arg); continue; /* skip the 'addsize' at the end */ } case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(&b); continue; /* skip the `addsize' at the end */ } else { sprintf(buff, form, s); break; } } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); } } luaL_addlstring(&b, buff, strlen(buff)); } } luaL_pushresult(&b); return 1; }
static int binread(lua_State *L) { int n; FILE *f; FILE **fp; const char *fmt; const char *fmt_save; char buf[256]; luaL_Buffer lbuf; n = lua_gettop(L); if (n != 2) return luaL_error(L, "expected 2 arguments for binread function (got %d)", n); fp = luaL_checkudata(L, 1, LUA_FILEHANDLE); f = *fp; fmt = luaL_checkstring(L, 2); fmt_save = fmt; DEBUG(3, "binread(\"%s\", ...)\n", fmt); luaL_buffinit(L, &lbuf); for (; *fmt; fmt++) { switch (*fmt) { case '?': case 'b': case 'B': case 'c': luaL_addchar(&lbuf, GETCHAR); break; case 'h': case 'H': READ(2); break; case 'f': case 'i': case 'I': READ(4); break; case 'l': case 'L': READ(8); break; case 's': { int len = GETCHAR; luaL_addchar(&lbuf, len); READ(len); } break; case 'S': { unsigned short len; if (fread(&len, 2, 1, f) < 1) return luaL_error(L, "unexpected EOF"); luaL_addlstring(&lbuf, (char *) &len, 2); READ(len); } break; case 't': { unsigned int len; if (fread(&len, 4, 1, f) < 1) return luaL_error(L, "unexpected EOF"); luaL_addlstring(&lbuf, (char *) &len, 4); READ(len); } break; case 'v': READ(12); break; case 'z': { int c; while ((c = GETCHAR)) { if (c < 0) return luaL_error(L, "unexpected EOF"); luaL_addchar(&lbuf, c); } } break; default: return luaL_error(L, "invalid format string"); } } lua_settop(L, 0); lua_pushcfunction(L, unpack); lua_pushstring(L, fmt_save); luaL_pushresult(&lbuf); lua_call(L, 2, LUA_MULTRET); return lua_gettop(L); }
static int Writer (lua_State *L, const void *s, size_t l, void *B) { (void)L; luaL_addlstring((luaL_Buffer *)B, (const char *)s, l); return LUA_OK; }
static int b_invpack(lua_State *L) { luaL_Buffer b; size_t lformat, i, last; const char *format = luaL_checklstring(L, 1, &lformat); if (lformat == 0) { lua_pushliteral(L, ""); return 1; } luaL_checktype(L, 2, LUA_TTABLE); i = luaL_optint(L, 3, 1); last = luaL_optint(L, 4, lformat); luaL_argcheck(L, i > 0 && i <= lformat, 3, "out of bounds"); luaL_argcheck(L, last > 0 && last <= lformat, 4, "out of bounds"); luaL_buffinit(L, &b); for (; i <= last; i++, format++) { size_t size = 1; lua_rawgeti(L, 2, i); switch (*format) { #ifdef LARGE_NUMBERS case 'D': #endif case 'f': case 'd': size = 0; #ifdef LARGE_NUMBERS case 'g': case 'G': size *= 2; #endif case 'l': case 'L': size *= 2; case 's': case 'S': size *= 2; case 'b': case 'B': { lua_Number number; luaL_argcheck(L, lua_isnumber(L, -1), 2, "table contains mismatched values"); number = lua_tonumber(L, -1); lua_pop(L, 1); if (size) { add_inverted_integer(&b, number, size); } else { switch (*format) { case 'f': { float value; value = (float)number; invert_bytes((byte*)&value, sizeof(value)); luaL_addlstring(&b, (char*)&value, sizeof(value)); } break; case 'd': { double value; value = (double)number; invert_bytes((byte*)&value, sizeof(value)); luaL_addlstring(&b, (char*)&value, sizeof(value)); } break; #ifdef LARGE_NUMBERS case 'D': { long double value; value = (long double)number; invert_bytes((byte*)&value, sizeof(value)); luaL_addlstring(&b, (char*)&value, sizeof(value)); } break; #endif } } } break; case '"': luaL_argcheck(L, lua_isstring(L, -1), 2, "table contains mismatched values"); luaL_addvalue(&b); break; default: luaL_error(L, "invalid format character, got '%c'", *format); } } luaL_pushresult(&b); return 1; }
int thread_dump(lua_State* L, const void* p, size_t sz, void* B) { (void)L; luaL_addlstring((luaL_Buffer*) B, (const char*) p, sz); return 0; }
// sz 需要读的数据长度 // skip 需要跳过的数据长度 比如\n的长度 static void pop_lstring(lua_State *L, struct socket_buffer *sb, int sz, int skip) { struct buffer_node * current = sb->head; if (sz < current->sz - sb->offset) { // 如果需要读的长度小于剩余可读的长度 // 把缓冲区数据压入栈中作为lua返回值 lua_pushlstring(L, current->msg + sb->offset, sz-skip); // 偏移量增加 sb->offset+=sz; return; } if (sz == current->sz - sb->offset) { // 如果需要读的长度等于剩余可读的长度 // 把缓冲区数据压入栈中作为lua返回值 lua_pushlstring(L, current->msg + sb->offset, sz-skip); // 当前缓冲区节点已读完,归还缓冲区节点到缓冲池 return_free_node(L,2,sb); return; } // 字符串缓存可以让c代码分段构造一个Lua字符串 // 定义一个字符串缓存 luaL_Buffer b; // 初始化字符串缓存 luaL_buffinit(L, &b); // 循环读取缓冲区链表的数据 for (;;) { // 当前缓冲区节点可读数据长度 int bytes = current->sz - sb->offset; if (bytes >= sz) { // 如果需要读的长度小于剩余可读的长度 // 刚开始进入循环,不会走这段逻辑,首节点此种情况已处理,此后遍历的节点仍可能出现此种情况 if (sz > skip) { // 把缓冲区数据放入字符串缓存 luaL_addlstring(&b, current->msg + sb->offset, sz - skip); } // 偏移量增加 sb->offset += sz; if (bytes == sz) { // 如果正好全部读完,归还缓冲区节点到缓冲池 return_free_node(L,2,sb); } // 需要读的已读完,跳出循环不必再读 break; } // 实际要读的数据长度,除sep分隔符之外 int real_sz = sz - skip; if (real_sz > 0) { // 把缓冲区数据放入字符串缓存 luaL_addlstring(&b, current->msg + sb->offset, (real_sz < bytes) ? real_sz : bytes); } // 当前缓冲区节点已读完,归还缓冲区节点到缓冲池 return_free_node(L,2,sb); sz-=bytes; if (sz==0) // 如果全部读完,跳出循环不必再读 break; // 换下一个缓冲区节点 current = sb->head; assert(current); } // 结束对字符串缓存的使用,将最终的字符串留在栈顶 luaL_pushresult(&b); }
void elua_uip_appcall() { volatile struct elua_uip_state *s; elua_net_size temp; int sockno; // If uIP is not yet configured (DHCP response not received), do nothing if( !elua_uip_configured ) return; s = ( struct elua_uip_state* )&( uip_conn->appstate ); // Need to find the actual socket location, since UIP doesn't provide this ... for( temp = 0; temp < UIP_CONNS; temp ++ ) if( uip_conns + temp == uip_conn ) break; sockno = ( int )temp; if( uip_connected() ) { #ifdef BUILD_CON_TCP if( uip_conn->lport == HTONS( ELUA_NET_TELNET_PORT ) ) // special case: telnet server { if( elua_uip_telnet_socket != -1 ) { uip_close(); return; } else elua_uip_telnet_socket = sockno; } else #endif if( elua_uip_accept_request ) { elua_uip_accept_sock = sockno; elua_uip_accept_remote.ipwords[ 0 ] = uip_conn->ripaddr[ 0 ]; elua_uip_accept_remote.ipwords[ 1 ] = uip_conn->ripaddr[ 1 ]; elua_uip_accept_request = 0; } else if( s->state == ELUA_UIP_STATE_CONNECT ) s->state = ELUA_UIP_STATE_IDLE; uip_stop(); return; } if( s->state == ELUA_UIP_STATE_IDLE ) return; // Do we need to read? if( s->state == ELUA_UIP_STATE_RECV ) { // Re-enable data transfer on the socket and change state s->state = ELUA_UIP_STATE_RECV_2; uip_restart(); return; } if( uip_aborted() || uip_timedout() || uip_closed() ) { // Signal this error s->res = uip_aborted() ? ELUA_NET_ERR_ABORTED : ( uip_timedout() ? ELUA_NET_ERR_TIMEDOUT : ELUA_NET_ERR_CLOSED ); #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) elua_uip_telnet_socket = -1; #endif s->state = ELUA_UIP_STATE_IDLE; return; } // Handle data send if( ( uip_acked() || uip_rexmit() || uip_poll() ) && ( s->state == ELUA_UIP_STATE_SEND ) ) { // Special translation for TELNET: prepend all '\n' with '\r' // We write directly in UIP's buffer if( uip_acked() ) { elua_net_size minlen = UMIN( s->len, uip_mss() ); s->len -= minlen; s->ptr += minlen; if( s->len == 0 ) s->state = ELUA_UIP_STATE_IDLE; } if( s->len > 0 ) // need to (re)transmit? { #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) { temp = elua_uip_telnet_prep_send( s->ptr, s->len ); uip_send( uip_sappdata, temp ); } else #endif uip_send( s->ptr, UMIN( s->len, uip_mss() ) ); } return; } // Handle close if( s->state == ELUA_UIP_STATE_CLOSE ) { uip_close(); s->state = ELUA_UIP_STATE_IDLE; return; } // Handle data receive if( uip_newdata() ) { if( s->state == ELUA_UIP_STATE_RECV_2 ) { #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) { elua_uip_telnet_handle_input( s ); return; } #endif int lastfound = 0; // Check end of transmission if( uip_datalen() < UIP_RECEIVE_WINDOW ) lastfound = 1; // Check overflow if( s->len < uip_datalen() ) { s->res = ELUA_NET_ERR_OVERFLOW; temp = s->len; } else temp = uip_datalen(); if( s->readto != ELUA_NET_NO_LASTCHAR ) { char *tptr = ( char* )uip_appdata; char *last = ( char* )uip_appdata + temp - 1; luaL_Buffer *pbuf = ( luaL_Buffer* )s->ptr; char* dest = ( char* )s->ptr; while( tptr <= last ) { if( *tptr == s->readto ) { lastfound = 1; break; } if( *tptr != '\r' ) { if( s->res ) luaL_addchar( pbuf, *tptr ); else *dest ++ = *tptr; s->len --; } tptr ++; } } else { if( s->res ) luaL_addlstring( ( luaL_Buffer* )s->ptr, ( const char* )uip_appdata, temp ); else memcpy( ( char* )s->ptr, ( const char* )uip_appdata, temp ); s->len -= temp; } // Do we need to read another packet? if( s->len == 0 || lastfound ) { uip_stop(); s->res = ELUA_NET_ERR_OK; s->state = ELUA_UIP_STATE_IDLE; } } else uip_stop(); } }
int get_pgfunc(lua_State *L) { Lua_pgfunc *lf; Pgfunc_options opt; MemoryContext m; const char* reg_name = NULL; HeapTuple proctup; Form_pg_proc proc; int luasrc = 0; Oid funcid = 0; BEGINLUA; opt.only_internal = true; opt.throwable = true; if (lua_gettop(L) == 2){ luaL_checktype(L, 2, LUA_TTABLE); parse_options(L, &opt); }else if (lua_gettop(L) != 1){ return luaL_error(L, "pgfunc(text): wrong arguments"); } if(lua_type(L, 1) == LUA_TSTRING){ reg_name = luaL_checkstring(L, 1); m = MemoryContextSwitchTo(tmpcontext); PG_TRY(); { funcid = DatumGetObjectId(DirectFunctionCall1(regprocedurein, CStringGetDatum(reg_name))); } PG_CATCH();{} PG_END_TRY(); MemoryContextSwitchTo(m); MemoryContextReset(tmpcontext); }else if (lua_type(L, 1) == LUA_TNUMBER){ funcid = luaL_checkinteger(L, 1); } if (!OidIsValid(funcid)){ if (reg_name) return luaL_error(L,"failed to register %s", reg_name); return luaL_error(L,"failed to register function with oid %d", funcid); } proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); if (!HeapTupleIsValid(proctup)){ return luaL_error(L,"cache lookup failed for function %d", funcid); } proc = (Form_pg_proc) GETSTRUCT(proctup); luasrc = ((proc->prolang == get_pllua_oid()) || (proc->prolang == get_plluau_oid())); if ( opt.only_internal &&(proc->prolang != INTERNALlanguageId) &&(!luasrc) ){ ReleaseSysCache(proctup); return luaL_error(L, "supported only SQL/internal functions"); } lf = (Lua_pgfunc *)lua_newuserdata(L, sizeof(Lua_pgfunc)); /*make it g/collected*/ luaP_getfield(L, pg_func_type_name); lua_setmetatable(L, -2); lf->prorettype = proc->prorettype; lf->funcid = funcid; lf->options = opt; { Oid *argtypes; char **argnames; char *argmodes; int argc; MemoryContext cur = CurrentMemoryContext; MemoryContextSwitchTo(tmpcontext); argc = get_func_arg_info(proctup, &argtypes, &argnames, &argmodes); MemoryContextSwitchTo(get_common_ctx()); lf->numargs = argc; lf->argtypes = (Oid*)palloc(argc * sizeof(Oid)); memcpy(lf->argtypes, argtypes, argc * sizeof(Oid)); MemoryContextSwitchTo(cur); MemoryContextReset(tmpcontext); } if (luasrc){ bool isnull; text *t; const char *s; luaL_Buffer b; int pcall_result; Datum prosrc; if((lf->numargs != 1) || (lf->argtypes[0] != INTERNALOID) || (lf->prorettype != INTERNALOID)){ luaL_error(L, "pgfunc accepts only 'internal' pllua/u functions with internal argument"); } prosrc = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull); if (isnull) elog(ERROR, "[pgfunc]: null lua prosrc"); luaL_buffinit(L, &b); luaL_addstring(&b,"do "); t = DatumGetTextP(prosrc); luaL_addlstring(&b, VARDATA(t), VARSIZE(t) - VARHDRSZ); luaL_addstring(&b, " end"); luaL_pushresult(&b); s = lua_tostring(L, -1); ReleaseSysCache(proctup); clean_pgfuncinfo(lf); if (luaL_loadbuffer(L, s, strlen(s), "pgfunc chunk")) luaL_error(L, "compile"); lua_remove(L, -2); /*delete source element*/ pcall_result = lua_pcall(L, 0, 1, 0); lua_remove(L, -2); /*delete chunk*/ if(pcall_result == 0){ ENDLUAV(1); return 1; } if( pcall_result == LUA_ERRRUN) luaL_error(L,"%s %s","Runtime error:",lua_tostring(L, -1)); else if(pcall_result == LUA_ERRMEM) luaL_error(L,"%s %s","Memory error:",lua_tostring(L, -1)); else if(pcall_result == LUA_ERRERR) luaL_error(L,"%s %s","Error:",lua_tostring(L, -1)); return luaL_error(L, "pgfunc unknown error"); } if(proc->proretset) { lua_pushcclosure(L, pgfunc_rows, 1); } else { fmgr_info(funcid, &lf->fi); lua_pushcclosure(L, pg_callable_func, 1); } ReleaseSysCache(proctup); ENDLUAV(1); return 1; }