Esempio n. 1
0
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", &sector))
	{
		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);
}
Esempio n. 2
0
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);
}