/* ** Pushes the indexed value onto the lua stack */ static void push_column(lua_State *L, int i, cur_data *cur) { int varcharlen; struct tm timevar; char timestr[256]; ISC_STATUS blob_stat; isc_blob_handle blob_handle = 0; ISC_QUAD blob_id; luaL_Buffer b; char *buffer; unsigned short actual_seg_len; if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) && (*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) { /* a null field? */ lua_pushnil(L); } else { switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) { case SQL_VARYING: varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2); lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen); break; case SQL_TEXT: lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen); break; case SQL_SHORT: luasql_pushinteger(L, *(ISC_SHORT*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_LONG: luasql_pushinteger(L, *(ISC_LONG*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_INT64: luasql_pushinteger(L, *(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_FLOAT: lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_DOUBLE: lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_TYPE_TIME: isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%X", &timevar); lua_pushstring(L, timestr); break; case SQL_TYPE_DATE: isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%x", &timevar); lua_pushstring(L, timestr); break; case SQL_TIMESTAMP: isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%x %X", &timevar); lua_pushstring(L, timestr); break; case SQL_BLOB: /* get the BLOB ID and open it */ memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD)); isc_open_blob2( cur->env->status_vector, &cur->conn->db, &cur->conn->transaction, &blob_handle, &blob_id, 0, NULL ); /* fetch the blob data */ luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); blob_stat = isc_get_segment( cur->env->status_vector, &blob_handle, &actual_seg_len, LUAL_BUFFERSIZE, buffer ); while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) { luaL_addsize(&b, actual_seg_len); buffer = luaL_prepbuffer(&b); blob_stat = isc_get_segment( cur->env->status_vector, &blob_handle, &actual_seg_len, LUAL_BUFFERSIZE, buffer ); } /* finnished, close the BLOB */ isc_close_blob(cur->env->status_vector, &blob_handle); blob_handle = 0; luaL_pushresult(&b); break; default: lua_pushstring(L, "<unsupported data type>"); break; } } }
/* ** Retrieves data from the i_th column in the current row ** Input ** types: index in stack of column types table ** hstmt: statement handle ** i: column number ** Returns: ** 0 if successfull, non-zero otherwise; */ static int push_column(lua_State *L, int coltypes, const SQLHSTMT hstmt, SQLUSMALLINT i) { const char *tname; char type; /* get column type from types table */ lua_rawgeti (L, LUA_REGISTRYINDEX, coltypes); lua_rawgeti (L, -1, i); /* typename of the column */ tname = lua_tostring(L, -1); if (!tname) return luasql_faildirect(L, "invalid type in table."); type = tname[1]; lua_pop(L, 2); /* pops type name and coltypes table */ /* deal with data according to type */ switch (type) { /* nUmber */ case 'u': { double num; SQLINTEGER got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_DOUBLE, &num, 0, &got); if (error(rc)) return fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lua_pushnil(L); else lua_pushnumber(L, num); return 0; } /* bOol */ case 'o': { char b; SQLINTEGER got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_BIT, &b, 0, &got); if (error(rc)) return fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lua_pushnil(L); else lua_pushboolean(L, b); return 0; } /* sTring */ case 't': /* bInary */ case 'i': { SQLSMALLINT stype = (type == 't') ? SQL_C_CHAR : SQL_C_BINARY; SQLINTEGER got; char *buffer; luaL_Buffer b; SQLRETURN rc; luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); if (got == SQL_NULL_DATA) { lua_pushnil(L); return 0; } /* concat intermediary chunks */ while (rc == SQL_SUCCESS_WITH_INFO) { if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); } /* concat last chunk */ if (rc == SQL_SUCCESS) { if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); } if (rc == SQL_ERROR) return fail(L, hSTMT, hstmt); /* return everything we got */ luaL_pushresult(&b); return 0; } } return 0; }
int lodbc_push_column_value(lua_State *L, SQLHSTMT hstmt, SQLUSMALLINT i, const char type){ int top = lua_gettop(L); switch (type) {/* deal with data according to type */ case 'u': { /* nUmber */ lua_Number num; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, LODBC_C_NUMBER, &num, 0, &got); if (lodbc_iserror(rc)) return lodbc_fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lodbc_pushnull(L); else lua_pushnumber(L, num); break; } case 'o': { /* bOol */ unsigned char b; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_BIT, &b, 0, &got); if (lodbc_iserror(rc)) return lodbc_fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lodbc_pushnull(L); else lua_pushboolean(L, b); break; } case 't': case 'i': {/* sTring, bInary */ SQLSMALLINT stype = (type == 't') ? SQL_C_CHAR : SQL_C_BINARY; SQLLEN got; char *buffer; luaL_Buffer b; SQLRETURN rc; luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); if (got == SQL_NULL_DATA){ lodbc_pushnull(L); break; } while (rc == SQL_SUCCESS_WITH_INFO) {/* concat intermediary chunks */ if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); } if (rc == SQL_SUCCESS) {/* concat last chunk */ if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); } if (lodbc_iserror(rc)) return lodbc_fail(L, hSTMT, hstmt); /* return everything we got */ luaL_pushresult(&b); break; } default:{ // unsupported type ? assert(0); } } assert(1 == (lua_gettop(L)-top)); return 0; }
static int lzlib_compress(lua_State *L) { size_t avail_in; const char *next_in = luaL_checklstring(L, 1, &avail_in); int level = luaL_optint(L, 2, Z_DEFAULT_COMPRESSION); int method = luaL_optint(L, 3, Z_DEFLATED); int windowBits = luaL_optint(L, 4, 15); int memLevel = luaL_optint(L, 5, 8); int strategy = luaL_optint(L, 6, Z_DEFAULT_STRATEGY); int ret; luaL_Buffer b; z_stream zs; luaL_buffinit(L, &b); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.next_out = Z_NULL; zs.avail_out = 0; zs.next_in = Z_NULL; zs.avail_in = 0; ret = deflateInit2(&zs, level, method, windowBits, memLevel, strategy); if (ret != Z_OK) { lua_pushnil(L); lua_pushnumber(L, ret); return 2; } zs.next_in = (unsigned char*)next_in; zs.avail_in = avail_in; for(;;) { zs.next_out = (unsigned char*)luaL_prepbuffer(&b); zs.avail_out = LUAL_BUFFERSIZE; /* munch some more */ ret = deflate(&zs, Z_FINISH); /* push gathered data */ luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out); /* done processing? */ if (ret == Z_STREAM_END) break; /* error condition? */ if (ret != Z_OK) break; } /* cleanup */ deflateEnd(&zs); luaL_pushresult(&b); lua_pushnumber(L, ret); return 2; }
/** * @upvalue z_stream - Memory for the z_stream. * @upvalue remainder - Any remainder from the last deflate call. * * @param string - "print" to deflate stream. * @param int - flush output buffer? Z_SYNC_FLUSH, Z_FULL_FLUSH, or Z_FINISH. * * if no params, terminates the stream (as if we got empty string and Z_FINISH). */ static int lz_filter_impl(lua_State *L, int (*filter)(z_streamp, int), int (*end)(z_streamp), char* name) { int flush = Z_NO_FLUSH, result; z_stream* stream; luaL_Buffer buff; size_t avail_in; if ( filter == deflate ) { const char *const opts[] = { "none", "sync", "full", "finish", NULL }; flush = luaL_checkoption(L, 2, opts[0], opts); if ( flush ) flush++; /* Z_NO_FLUSH(0) Z_SYNC_FLUSH(2), Z_FULL_FLUSH(3), Z_FINISH (4) */ /* No arguments or nil, we are terminating the stream: */ if ( lua_gettop(L) == 0 || lua_isnil(L, 1) ) { flush = Z_FINISH; } } stream = (z_stream*)lua_touserdata(L, lua_upvalueindex(1)); if ( stream == NULL ) { if ( lua_gettop(L) >= 1 && lua_isstring(L, 1) ) { lua_pushfstring(L, "IllegalState: calling %s function when stream was previously closed", name); lua_error(L); } lua_pushstring(L, ""); lua_pushboolean(L, 1); return 2; /* Ignore duplicate calls to "close". */ } luaL_buffinit(L, &buff); if ( lua_gettop(L) > 1 ) lua_pushvalue(L, 1); if ( lua_isstring(L, lua_upvalueindex(2)) ) { lua_pushvalue(L, lua_upvalueindex(2)); if ( lua_gettop(L) > 1 && lua_isstring(L, -2) ) { lua_concat(L, 2); } } /* Do the actual deflate'ing: */ if (lua_gettop(L) > 0) { stream->next_in = (unsigned char*)lua_tolstring(L, -1, &avail_in); } else { stream->next_in = NULL; avail_in = 0; } stream->avail_in = avail_in; if ( ! stream->avail_in && ! flush ) { /* Passed empty string, make it a noop instead of erroring out. */ lua_pushstring(L, ""); lua_pushboolean(L, 0); lua_pushinteger(L, stream->total_in); lua_pushinteger(L, stream->total_out); return 4; } do { stream->next_out = (unsigned char*)luaL_prepbuffer(&buff); stream->avail_out = LUAL_BUFFERSIZE; result = filter(stream, flush); if ( Z_BUF_ERROR != result ) { /* Ignore Z_BUF_ERROR since that just indicates that we * need a larger buffer in order to proceed. Thanks to * Tobias Markmann for finding this bug! */ lz_assert(L, result, stream, __FILE__, __LINE__); } luaL_addsize(&buff, LUAL_BUFFERSIZE - stream->avail_out); } while ( stream->avail_out == 0 ); /* Need to do this before we alter the stack: */ luaL_pushresult(&buff); /* Save remainder in lua_upvalueindex(2): */ if ( NULL != stream->next_in ) { lua_pushlstring(L, (char*)stream->next_in, stream->avail_in); lua_replace(L, lua_upvalueindex(2)); } /* "close" the stream/remove finalizer: */ if ( result == Z_STREAM_END ) { /* Clear-out the metatable so end is not called twice: */ lua_pushnil(L); lua_setmetatable(L, lua_upvalueindex(1)); /* nil the upvalue: */ lua_pushnil(L); lua_replace(L, lua_upvalueindex(1)); /* Close the stream: */ lz_assert(L, end(stream), stream, __FILE__, __LINE__); lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); } lua_pushinteger(L, stream->total_in); lua_pushinteger(L, stream->total_out); return 4; }
/* * (string) / (msg, sz) * (msg, sz) */ static int linflate(lua_State* L) { luaL_Buffer buff; z_stream stream; void* src_buff; unsigned long src_len; int ret; if (lua_isnoneornil(L, 1)) { lua_pushnil(L); return 1; } if (lua_type(L, 1) == LUA_TSTRING) { size_t sz; src_buff = (void*)lua_tolstring(L, 1, &sz); src_len = (unsigned long)sz; } else { src_buff = lua_touserdata(L, 1); src_len = (unsigned long)luaL_checkinteger(L, 2); } if (src_len == 0) { lua_pushnil(L); return 1; } if (src_buff == NULL) { return luaL_error(L, "inflate null pointer"); } lua_settop(L, 0); /* allocate inflate state */ stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.avail_in = 0; stream.next_in = Z_NULL; ret = inflateInit(&stream); if (ret != Z_OK) { lua_pushnil(L); return 1; } luaL_buffinit(L, &buff); stream.avail_in = src_len; stream.next_in = src_buff; do { stream.avail_out = LUAL_BUFFERSIZE; stream.next_out = (unsigned char*)luaL_prepbuffer(&buff); ret = inflate(&stream, Z_NO_FLUSH); assert(ret != Z_STREAM_ERROR); switch (ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; /* fall through */ case Z_DATA_ERROR: case Z_MEM_ERROR: inflateEnd(&stream); lua_pushnil(L); return ret; } luaL_addsize(&buff, LUAL_BUFFERSIZE - stream.avail_out); } while (stream.avail_out == 0); /* clean up and return */ inflateEnd(&stream); luaL_pushresult(&buff); return 1; }
/* * (string) / (msg, sz) * (msg, sz) */ static int ldeflate(lua_State* L) { luaL_Buffer buff; z_stream stream; void* src_buff; unsigned long src_len; int ret; if (lua_isnoneornil(L, 1)) { lua_pushnil(L); return 1; } if (lua_type(L, 1) == LUA_TSTRING) { size_t sz; src_buff = (void*)lua_tolstring(L, 1, &sz); src_len = (unsigned long)sz; } else { src_buff = lua_touserdata(L, 1); src_len = (unsigned long)luaL_checkinteger(L, 2); } if (src_len == 0) { lua_pushnil(L); return 1; } if (src_buff == NULL) { return luaL_error(L, "deflate null pointer"); } lua_settop(L, 0); /* allocate deflate state */ stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; ret = deflateInit(&stream, Z_DEFAULT_COMPRESSION); if (ret != Z_OK) { lua_pushnil(L); return 1; } luaL_buffinit(L, &buff); stream.avail_in = src_len; stream.next_in = src_buff; do { stream.avail_out = LUAL_BUFFERSIZE; stream.next_out = (unsigned char*)luaL_prepbuffer(&buff); ret = deflate(&stream, Z_FINISH); assert(ret != Z_STREAM_ERROR); luaL_addsize(&buff, LUAL_BUFFERSIZE - stream.avail_out); } while (stream.avail_out == 0); /* stream will be complete */ assert(ret == Z_STREAM_END); /* clean up and return */ deflateEnd(&stream); luaL_pushresult(&buff); 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; }
/**----------------------------------------------------------------------------- * Form HTTP response Header. * \param L The lua state. * \param luaL_Buffer Lua Buffer pointer. * \param struct t_htp_str struct pointer. * \param int the HTTP Status Code to be returned. * \param char* the HTTP Status Message to be returned. * \param size_t* length of the HTTP Payload aka. Content-length. * \param int position of table on stack where headers are present. * 0 means no additional headers. * \return int size of string added to the buffer. * ---------------------------------------------------------------------------*/ static size_t t_htp_str_formHeader( lua_State *L, luaL_Buffer *lB, struct t_htp_str *s, int code, const char *msg, int len, int t ) { size_t c; ///< count all chars added in this method size_t bs; ///< chars added currently to buffers char *b = luaL_prepbuffer( lB ); if (len) { bs = sprintf( b, "HTTP/1.1 %d %s\r\n" "Connection: %s\r\n" "Date: %s\r\n" "Content-Length: %d\r\n" "%s", (int) code, // HTTP Status code (NULL == msg) ? t_htp_status( code ) : msg, // HTTP Status Message (s->con->kpAlv) ? "Keep-Alive" : "Close", // Keep-Alive or close s->con->srv->fnw, // Formatted Date len, // Content-Length (t) ? "" : "\r\n" ); s->rsCl = len; } else { bs = sprintf( b, "HTTP/1.1 %d %s\r\n" "Connection: %s\r\n" "Date: %s\r\n" "Transfer-Encoding: chunked\r\n" "%s", (int) code, // HTTP Status code (NULL == msg) ? t_htp_status( code ) : msg, // HTTP Status Message (s->con->kpAlv) ? "Keep-Alive" : "Close", // Keep-Alive or close s->con->srv->fnw, // Formatted Date (t) ? "" : "\r\n" ); s->rsCl = len; } luaL_addsize( lB, bs ); // TODO: Find a way to deal more efficiently with that buffer b = luaL_prepbuffer( lB ); c = bs; bs = 0; if (t) { lua_pushnil( L ); while (lua_next( L, t )) { bs += sprintf( b, "%s: %s\r\n", lua_tostring( L, -2 ), lua_tostring( L, -1 ) ); lua_pop( L, 1 ); //FIXME: this can't pop, it must remove } bs += sprintf( b, "\r\n" ); // finish off the HTTP Headers part luaL_addsize( lB, bs ); } c += bs; s->rsBl = (len) ? c + len : 0; return c; }
static int emit (lua_State *L) { lyaml_emitter *emitter; int yaml_ok = 0; int finalize = 0; luaL_argcheck (L, lua_istable (L, 1), 1, "expected table"); emitter = (lyaml_emitter *) lua_touserdata (L, lua_upvalueindex (1)); { const char *type; RAWGET_STRDUP (type); lua_pop (L, 1); if (type == NULL) { emitter->error++; luaL_addstring (&emitter->errbuff, "no type field in event table"); } #define MENTRY(_s) (STREQ (type, #_s)) { yaml_ok = emit_##_s (L, emitter); } /* Minimize comparisons by putting more common types earlier. */ else if MENTRY( SCALAR ) else if MENTRY( MAPPING_START ) else if MENTRY( MAPPING_END ) else if MENTRY( SEQUENCE_START ) else if MENTRY( SEQUENCE_END ) else if MENTRY( DOCUMENT_START ) else if MENTRY( DOCUMENT_END ) else if MENTRY( STREAM_START ) else if MENTRY( STREAM_END ) else if MENTRY( ALIAS ) #undef MENTRY else { emitter->error++; luaL_addsize (&emitter->errbuff, sprintf (luaL_prepbuffer (&emitter->errbuff), "invalid event type '%s'", type)); } /* If the stream has finished, finalize the YAML output. */ if (type && STREQ (type, "STREAM_END")) finalize = 1; if (type) free ((void *) type); } /* Copy any yaml_emitter_t errors into the error buffer. */ if (!emitter->error && !yaml_ok) { if (emitter->emitter.problem) luaL_addstring (&emitter->errbuff, emitter->emitter.problem); else luaL_addstring (&emitter->errbuff, "LibYAML call failed"); emitter->error++; } /* Report errors back to the caller as `false, "error message"`. */ if (emitter->error != 0) { assert (emitter->error == 1); /* bail on uncaught additional errors */ lua_pushboolean (L, 0); luaL_pushresult (&emitter->errbuff); lua_xmove (emitter->errL, L, 1); return 2; } /* Return `true, "YAML string"` after accepting a STREAM_END event. */ if (finalize) { lua_pushboolean (L, 1); luaL_pushresult (&emitter->yamlbuff); lua_xmove (emitter->outputL, L, 1); return 2; } /* Otherwise, just report success to the caller as `true`. */ lua_pushboolean (L, 1); return 1; }