int w_newFileData(lua_State *L)
{
	// Single argument: treat as filepath or File.
	if (lua_gettop(L) == 1)
	{
		// We don't use luax_getfiledata because we want to use an ioError.
		if (lua_isstring(L, 1))
			luax_convobj(L, 1, "filesystem", "newFile");

		// Get FileData from the File.
		if (luax_istype(L, 1, FILESYSTEM_FILE_ID))
		{
			File *file = luax_checkfile(L, 1);

			FileData *data = 0;
			try
			{
				data = file->read();
			}
			catch (love::Exception &e)
			{
				return luax_ioError(L, "%s", e.what());
			}
			luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, data);
			data->release();
			return 1;
		}
		else
			return luaL_argerror(L, 1, "filename or File expected");
	}

	size_t length = 0;
	const char *str = luaL_checklstring(L, 1, &length);
	const char *filename = luaL_checkstring(L, 2);
	const char *decstr = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0;

	FileData::Decoder decoder = FileData::FILE;

	if (decstr && !FileData::getConstant(decstr, decoder))
		return luaL_error(L, "Invalid FileData decoder: %s", decstr);

	FileData *t = 0;

	switch (decoder)
	{
	case FileData::FILE:
		t = instance()->newFileData((void *)str, (int)length, filename);
		break;
	case FileData::BASE64:
		t = instance()->newFileData(str, filename);
		break;
	default:
		return luaL_error(L, "Invalid FileData decoder: %s", decstr);
	}

	luax_pushtype(L, FILESYSTEM_FILE_DATA_ID, t);
	t->release();
	return 1;
}
Example #2
0
FileData *File::read(int64 size)
{
	bool isopen = isOpen();

	if (!isopen && !open(MODE_READ))
		throw love::Exception("Could not read file %s.", getFilename().c_str());

	int64 max = getSize();
	int64 cur = tell();
	size = (size == ALL) ? max : size;

	if (size < 0)
		throw love::Exception("Invalid read size.");

	// Clamping because the file offset may be in a weird position.
	if (cur < 0)
		cur = 0;
	else if (cur > max)
		cur = max;

	if (cur + size > max)
		size = max - cur;

	FileData *fileData = new FileData(size, getFilename());
	int64 bytesRead = read(fileData->getData(), size);

	if (bytesRead < 0 || (bytesRead == 0 && bytesRead != size))
	{
		delete fileData;
		throw love::Exception("Could not read from file.");
	}

	if (bytesRead < size)
	{
		FileData *tmpFileData = new FileData(bytesRead, getFilename());
		memcpy(tmpFileData->getData(), fileData->getData(), (size_t) bytesRead);
		fileData->release();
		fileData = tmpFileData;
	}

	if (!isopen)
		close();

	return fileData;
}