static void Voxel_copy_region (LIScrArgs* args) { int i; int length; int sector; int offset[3]; LIArcPacket* packet; LIScrData* data; LIExtModule* module; LIMatVector point; LIMatVector size; LIVoxVoxel* result; /* Get region offset and size. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_VOXEL); if (liscr_args_gets_int (args, "sector", §or)) { lialg_sectors_index_to_offset (module->program->sectors, sector, offset + 0, offset + 1, offset + 2); point = limat_vector_init (offset[0], offset[1], offset[2]); point = limat_vector_multiply (point, module->voxels->tiles_per_line); size.x = size.y = size.z = module->voxels->tiles_per_line; length = module->voxels->tiles_per_sector; } else if (liscr_args_gets_vector (args, "point", &point) && liscr_args_gets_vector (args, "size", &size)) { if (point.x < 0.0f || point.y < 0.0f || point.z < 0.0f || size.x < 1.0f || size.y < 1.0f || size.z < 1.0f) return; length = (int) size.x * (int) size.y * (int) size.z; } else return; /* Read voxel data. */ result = lisys_calloc (length, sizeof (LIVoxVoxel)); if (result == NULL) return; livox_manager_copy_voxels (module->voxels, (int) point.x, (int) point.y, (int) point.z, (int) size.x, (int) size.y, (int) size.z, result); /* Create a packet writer. */ packet = liarc_packet_new_writable (0); if (packet == NULL) { lisys_free (result); return; } /* Write the dimensions. */ if (!liarc_writer_append_uint32 (packet->writer, (int) size.x) || !liarc_writer_append_uint32 (packet->writer, (int) size.y) || !liarc_writer_append_uint32 (packet->writer, (int) size.z)) { lisys_free (result); return; } /* Write voxel data. */ for (i = 0 ; i < length ; i++) { if (!livox_voxel_write (result + i, packet->writer)) { lisys_free (result); return; } } lisys_free (result); /* Return data. */ data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data == NULL) { liarc_packet_free (packet); return; } liscr_args_seti_stack (args); }
static void Database_query (LIScrArgs* args) { int i; int col; int row; int ret; int size; const char* query; const char* str; sqlite3* self; LIArcPacket* packet; LIScrData* data; sqlite3_stmt* statement; self = args->self; if (!liscr_args_geti_string (args, 0, &query) && !liscr_args_gets_string (args, "query", &query)) return; /* Create a statement. */ if (sqlite3_prepare_v2 (self, query, -1, &statement, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL prepare: %s", sqlite3_errmsg (self)); lisys_error_report (); return; } /* Bind variables. */ if (liscr_args_geti_table (args, 1) || liscr_args_gets_table (args, "bind")) { for (i = 1 ; i < sqlite3_bind_parameter_count (statement) + 1 ; i++) { /* We got a table that has the bound variables in fields matching the indices of the bound variables. We can simply loop through the table and use the binding index as the key. */ lua_pushnumber (args->lua, i); lua_gettable (args->lua, -2); switch (lua_type (args->lua, -1)) { /* Bind numbers as doubles. */ case LUA_TNUMBER: if (sqlite3_bind_double (statement, i, lua_tonumber (args->lua, -1)) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind strings as text. */ case LUA_TSTRING: if (sqlite3_bind_text (statement, i, lua_tostring (args->lua, -1), -1, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind packets as blobs. */ case LUA_TUSERDATA: data = liscr_isdata (args->lua, -1, LISCR_SCRIPT_PACKET); if (data == NULL) break; packet = liscr_data_get_data (data); if (packet->writer != NULL) { if (sqlite3_bind_blob (statement, i, packet->writer->memory.buffer, packet->writer->memory.length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } else { if (sqlite3_bind_blob (statement, i, packet->reader->buffer, packet->reader->length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } break; /* Bind any other values as NULL. */ default: if (sqlite3_bind_null (statement, i) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; } lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Execute the statement and process results. */ for (row = 0, ret = sqlite3_step (statement) ; ret != SQLITE_DONE ; ret = sqlite3_step (statement), row++) { /* Check for errors. */ if (ret != SQLITE_ROW) { lisys_error_set (EINVAL, "SQL step: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Create a row table. */ lua_newtable (args->lua); /* Push the columns to the table. */ for (col = 0 ; col < sqlite3_column_count (statement) ; col++) { switch (sqlite3_column_type (statement, col)) { case SQLITE_INTEGER: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_int (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_FLOAT: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_double (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_TEXT: str = (const char*) sqlite3_column_text (statement, col); size = sqlite3_column_bytes (statement, col); lua_pushnumber (args->lua, col + 1); if (size > 0 && str != NULL) lua_pushstring (args->lua, str); else lua_pushstring (args->lua, str); lua_settable (args->lua, -3); break; case SQLITE_BLOB: str = sqlite3_column_blob (statement, col); size = sqlite3_column_bytes (statement, col); packet = liarc_packet_new_readable (str, size); if (packet != NULL) { lua_pushnumber (args->lua, col + 1); data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data != NULL) lua_settable (args->lua, -3); else { lua_pop (args->lua, 1); liarc_packet_free (packet); } } break; case SQLITE_NULL: break; default: lisys_assert (0 && "invalid column type"); break; } } /* Add the row to the return values. */ liscr_args_seti_stack (args); } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); sqlite3_finalize (statement); }