Example #1
0
void EClassManager::parseFile(const std::string& filename)
{
	const std::string fullname = "def/" + filename;

	ArchiveTextFilePtr file = GlobalFileSystem().openTextFile(fullname);

	if (file == NULL) return;

	try {
		// Parse entity defs from the file
		parse(file->getInputStream(), file->getModName());
	}
		catch (parser::ParseException& e) {
			rError() << "[eclassmgr] failed to parse " << filename
					  << " (" << e.what() << ")" << std::endl;
	}
}
void ParticlesManager::saveParticleDef(const std::string& particleName)
{
	ParticleDefMap::const_iterator found = _particleDefs.find(particleName);

	if (found == _particleDefs.end())
	{
		throw std::runtime_error(_("Cannot save particle, it has not been registered yet."));
	}

	ParticleDefPtr particle = found->second;

	std::string relativePath = PARTICLES_DIR + particle->getFilename();

	fs::path particlesModPath = GlobalGameManager().getModPath();
	particlesModPath /= PARTICLES_DIR;

	// Ensure the particles folder exists
	fs::create_directories(particlesModPath);

	fs::path targetFile = particlesModPath / particle->getFilename();

	// If the file doesn't exist yet, let's check if we need to inherit stuff first from the VFS
	if (!fs::exists(targetFile))
	{
		ArchiveTextFilePtr inheritFile = GlobalFileSystem().openTextFile(relativePath);

		if (inheritFile != NULL)
		{
			// There is a file with that name already in the VFS, copy it to the target file
			TextInputStream& inheritStream = inheritFile->getInputStream();

			std::ofstream outFile(targetFile.string().c_str());

			if (!outFile.is_open())
			{
				throw std::runtime_error(
					(boost::format(_("Cannot open file for writing: %s")) % targetFile.string()).str());
			}

			char buf[16384];
			std::size_t bytesRead = inheritStream.read(buf, sizeof(buf));

			while (bytesRead > 0)
			{
				outFile.write(buf, bytesRead);

				bytesRead = inheritStream.read(buf, sizeof(buf));
			}

			outFile.close();
		}
	}

	// Open a temporary file
	fs::path tempFile = targetFile;

	tempFile.remove_filename();
	tempFile /= "_" + os::filename_from_path(targetFile);

	std::ofstream tempStream(tempFile.string().c_str());

	if (!tempStream.is_open())
	{
		throw std::runtime_error(
				(boost::format(_("Cannot open file for writing: %s")) % tempFile.string()).str());
	}

	std::string tempString;

	// If a previous file exists, open it for reading and filter out the particle def we'll be writing
	if (fs::exists(targetFile))
	{
		std::ifstream inheritStream(targetFile.string().c_str());

		if (!inheritStream.is_open())
		{
			throw std::runtime_error(
					(boost::format(_("Cannot open file for reading: %s")) % targetFile.string()).str());
		}

		// Write the file to the output stream, up to the point the particle def should be written to
		stripParticleDefFromStream(inheritStream, tempStream, particleName);

		if (inheritStream.eof())
		{
			// Particle def was not found in the inherited stream, write our comment
			tempStream << std::endl << std::endl;

			writeParticleCommentHeader(tempStream);
		}

		// We're at the insertion point (which might as well be EOF of the inheritStream)

		// Write the particle declaration
		tempStream << *particle << std::endl;

		tempStream << inheritStream.rdbuf();

		inheritStream.close();
	}
	else
	{
		// Just put the particle def into the file and that's it, leave a comment at the head of the decl
		writeParticleCommentHeader(tempStream);

		// Write the particle declaration
		tempStream << *particle << std::endl;
	}

	tempStream.close();

	// Move the temporary stream over the actual file, removing the target first
	if (fs::exists(targetFile))
	{
		try
		{
			fs::remove(targetFile);
		}
		catch (fs::filesystem_error& e)
		{
			rError() << "Could not remove the file " << targetFile.string() << std::endl
				<< e.what() << std::endl;

			throw std::runtime_error(
				(boost::format(_("Could not remove the file %s")) % targetFile.string()).str());
		}
	}

	try
	{
		fs::rename(tempFile, targetFile);
	}
	catch (fs::filesystem_error& e)
	{
		rError() << "Could not rename the temporary file " << tempFile.string() << std::endl
			<< e.what() << std::endl;

		throw std::runtime_error(
			(boost::format(_("Could not rename the temporary file %s")) % tempFile.string()).str());
	}
}