示例#1
0
bool createUtilities(std::vector<FileData> & fileList, const FS_NAMESPACE::path & utilitiesPath, const FS_NAMESPACE::path & commonHeaderPath, bool useCConstructs = false, bool addFileData = false)
{
	// try opening the output file. truncate it when it exists
	std::ofstream outStream;
	outStream.open(utilitiesPath.generic_string(), std::ofstream::out | std::ofstream::trunc);
	if (outStream.is_open() && outStream.good())
	{
		if (beVerbose)
		{
			std::cout << std::endl << "Creating utilities file " << utilitiesPath;
		}
		// add message
		outStream << "// this file was auto-generated by res2h" << std::endl << std::endl;
		// create path to include file RELATIVE to this file
		FS_NAMESPACE::path relativePath = naiveUncomplete(commonHeaderPath, utilitiesPath);
		// include header file
		outStream << "#include \"" << relativePath.string() << "\"" << std::endl << std::endl;
		// if the data should go to this file too, add it
		if (addFileData)
		{
			for (auto fdIt = fileList.begin(); fdIt != fileList.cend(); ++fdIt)
			{
				if (!convertFile(*fdIt, commonHeaderFilePath, outStream, false))
				{
					std::cout << "Error: Failed to convert all files. Aborting!" << std::endl;
					outStream.close();
					return false;
				}
			}
		}
		// begin data arrays. switch depending whether C or C++
		outStream << "const uint32_t res2hNrOfFiles = " << fileList.size() << ";" << std::endl;
		// add files
		outStream << "const Res2hEntry res2hFiles[res2hNrOfFiles] = {" << std::endl;
		outStream << "    "; // first indent
		for (auto fdIt = fileList.cbegin(); fdIt != fileList.cend();)
		{
			outStream << "{\"" << fdIt->internalName << "\", " << fdIt->sizeVariableName << ", " << fdIt->dataVariableName << "}";
			// was this the last entry?
			++fdIt;
			if (fdIt != fileList.cend())
			{
				// no. add comma.
				outStream << ",";
				// add break after every entry and add indent again
				outStream << std::endl << "    ";
			}
		}
		outStream << std::endl << "};" << std::endl;
		if (!useCConstructs)
		{
			// add files to map
			outStream << std::endl << "res2hMapType::value_type mapTemp[] = {" << std::endl;
			outStream << "    ";
			for (auto fdIt = fileList.cbegin(); fdIt != fileList.cend();)
			{
				outStream << "std::make_pair(\"" << fdIt->internalName << "\", res2hFiles[" << (fdIt - fileList.cbegin()) << "])";
				// was this the last entry?
				++fdIt;
				if (fdIt != fileList.cend())
				{
					// no. add comma.
					outStream << ",";
					// add break after every entry and add indent again
					outStream << std::endl << "    ";
				}
			}
			outStream << std::endl << "};" << std::endl << std::endl;
			// create map
			outStream << "res2hMapType res2hMap(mapTemp, mapTemp + sizeof mapTemp / sizeof mapTemp[0]);" << std::endl;
		}
		// close file
		outStream.close();
		if (beVerbose)
		{
			std::cout << " - succeeded." << std::endl;
		}
		return true;
	}
	else
	{
		std::cout << "Error: Failed to open file \"" << utilitiesPath << "\" for writing!" << std::endl;
	}
	return true;
}
示例#2
0
bool createCommonHeader(const std::vector<FileData> & fileList, const FS_NAMESPACE::path & commonHeaderPath, bool addUtilityFunctions = false, bool useCConstructs = false)
{
	// try opening the output file. truncate it when it exists
	std::ofstream outStream;
	outStream.open(commonHeaderPath.generic_string(), std::ofstream::out | std::ofstream::trunc);
	if (outStream.is_open() && outStream.good())
	{
		if (beVerbose)
		{
			std::cout << std::endl << "Creating common header " << commonHeaderPath;
		}
		// add message
		outStream << "// this file was auto-generated by res2h" << std::endl << std::endl;
		// add #pragma to only include once
		outStream << "#pragma once" << std::endl << std::endl;
		// add includes for C++
		if (!useCConstructs)
		{
			outStream << "#include <string>" << std::endl;
			if (addUtilityFunctions)
			{
				outStream << "#include <map>" << std::endl;
			}
			outStream << std::endl;
		}
		// add all files and check maximum size
		uint64_t maxSize = 0;
		for (auto fdIt = fileList.cbegin(); fdIt != fileList.cend(); ++fdIt)
		{
			// add size and data variable
			maxSize = maxSize < fdIt->size ? fdIt->size : maxSize;
			if (fdIt->size <= UINT16_MAX)
			{
				outStream << "extern const uint16_t ";
			}
			else if (fdIt->size <= UINT32_MAX)
			{
				outStream << "extern const uint32_t ";
			}
			else
			{
				outStream << "extern const uint64_t ";
			}
			outStream << fdIt->sizeVariableName << ";" << std::endl;
			outStream << "extern const uint8_t " << fdIt->dataVariableName << "[];" << std::endl << std::endl;
		}
		// if we want utilities, add array
		if (addUtilityFunctions)
		{
			// add resource struct
			outStream << "struct Res2hEntry {" << std::endl;
			if (useCConstructs)
			{
				outStream << "    const char * relativeFileName;" << std::endl;
			}
			else
			{
				outStream << "    const std::string relativeFileName;" << std::endl;
			}
			//  add size member depending on the determined maximum file size
			if (maxSize <= UINT16_MAX)
			{
				outStream << "    const uint16_t size;" << std::endl;
			}
			else if (maxSize <= UINT32_MAX)
			{
				outStream << "    const uint32_t size;" << std::endl;
			}
			else
			{
				outStream << "    const uint64_t size;" << std::endl;
			}
			outStream << "    const uint8_t * data;" << std::endl;
			outStream << "};" << std::endl << std::endl;
			// add list holding files
			outStream << "extern const uint32_t res2hNrOfFiles;" << std::endl;
			outStream << "extern const Res2hEntry res2hFiles[];" << std::endl << std::endl;
			if (!useCConstructs)
			{
				// add additional std::map if C++
				outStream << "typedef const std::map<const std::string, const Res2hEntry> res2hMapType;" << std::endl;
				outStream << "extern res2hMapType res2hMap;" << std::endl;
			}
		}
		// close file
		outStream.close();
		if (beVerbose)
		{
			std::cout << " - succeeded." << std::endl;
		}
		return true;
	}
	else
	{
		std::cout << "Error: Failed to open file \"" << commonHeaderPath << "\" for writing!" << std::endl;
	}
	return true;
}
示例#3
0
std::vector<FileData> getFileDataFrom(const FS_NAMESPACE::path & inPath, const FS_NAMESPACE::path & outPath, const FS_NAMESPACE::path & parentDir, const bool recurse)
{
	// get all files from directory
	std::vector<FileData> files;
	// check for infinite symlinks
	if (FS_NAMESPACE::is_symlink(inPath))
	{
		// check if the symlink points somewhere in the path. this would recurse
		if (inPath.string().find(FS_NAMESPACE::canonical(inPath).string()) == 0)
		{
			std::cout << "Warning: Path " << inPath << " contains recursive symlink! Skipping." << std::endl;
			return files;
		}
	}
	// iterate through source directory searching for files
	const FS_NAMESPACE::directory_iterator dirEnd;
	for (FS_NAMESPACE::directory_iterator fileIt(inPath); fileIt != dirEnd; ++fileIt)
	{
		FS_NAMESPACE::path filePath = (*fileIt).path();
		if (!FS_NAMESPACE::is_directory(filePath))
		{
			if (beVerbose)
			{
				std::cout << "Found input file " << filePath << std::endl;
			}
			// add file to list
			FileData temp;
			temp.inPath = filePath;
			// replace dots in file name with '_' and add a .c/.cpp extension
			std::string newFileName = filePath.filename().generic_string();
			std::replace(newFileName.begin(), newFileName.end(), '.', '_');
			if (useC)
			{
				newFileName.append(".c");
			}
			else
			{
				newFileName.append(".cpp");
			}
			// remove parent directory of file from path for internal name. This could surely be done in a safer way
			FS_NAMESPACE::path subPath(filePath.generic_string().substr(parentDir.generic_string().size() + 1));
			// add a ":/" before the name to mark internal resources (Yes. Hello Qt!)
			temp.internalName = ":/" + subPath.generic_string();
			// add subdir below parent path to name to enable multiple files with the same name
			std::string subDirString(subPath.remove_filename().generic_string());
			if (!subDirString.empty())
			{
				// replace dir separators by underscores
				std::replace(subDirString.begin(), subDirString.end(), '/', '_');
				// add in front of file name
				newFileName = subDirString + "_" + newFileName;
			}
			// build new output file name
			temp.outPath = outPath / newFileName;
			if (beVerbose)
			{
				std::cout << "Internal name will be \"" << temp.internalName << "\"" << std::endl;
				std::cout << "Output path is " << temp.outPath << std::endl;
			}
			// get file size
			try
			{
				temp.size = static_cast<uint64_t>(FS_NAMESPACE::file_size(filePath));
				if (beVerbose)
				{
					std::cout << "Size is " << temp.size << " bytes." << std::endl;
				}
			}
			catch (...)
			{
				std::cout << "Error: Failed to get size of " << filePath << "!" << std::endl;
				temp.size = 0;
			}
			// add file to list
			files.push_back(temp);
		}
	}
	// does the user want subdirectories?
	if (recurse)
	{
		// iterate through source directory again searching for directories
		for (FS_NAMESPACE::directory_iterator dirIt(inPath); dirIt != dirEnd; ++dirIt)
		{
			FS_NAMESPACE::path dirPath = (*dirIt).path();
			if (FS_NAMESPACE::is_directory(dirPath))
			{
				if (beVerbose)
				{
					std::cout << "Found subdirectory " << dirPath << std::endl;
				}
				// subdirectory found. recurse.
				std::vector<FileData> subFiles = getFileDataFrom(dirPath, outPath, parentDir, recurse);
				// add returned result to file list
				files.insert(files.end(), subFiles.cbegin(), subFiles.cend());
			}
		}
	}
	// return result
	return files;
}
示例#4
0
bool convertFile(FileData & fileData, const FS_NAMESPACE::path & commonHeaderPath, std::ofstream & outStream = badOfStream, bool addHeader = true)
{
	if (FS_NAMESPACE::exists(fileData.inPath))
	{
		// try to open the input file
		std::ifstream inStream;
		inStream.open(fileData.inPath.string(), std::ifstream::in | std::ifstream::binary);
		if (inStream.is_open() && inStream.good())
		{
			if (beVerbose)
			{
				std::cout << "Converting input file " << fileData.inPath;
			}
			// try getting size of data
			inStream.seekg(0, std::ios::end);
			fileData.size = static_cast<uint64_t>(inStream.tellg());
			inStream.seekg(0);
			// check if the caller passed and output stream and use that
			bool closeOutStream = false;
			if (!outStream.is_open() || !outStream.good())
			{
				if (!fileData.outPath.empty())
				{
					// try opening the output stream. truncate it when it exists
					outStream.open(fileData.outPath.string(), std::ofstream::out | std::ofstream::trunc);
				}
				else
				{
					std::cout << "Error: No output stream passed, but output path for \"" << fileData.inPath.filename().string() << "\" is empty! Skipping." << std::endl;
					return false;
				}
				closeOutStream = true;
			}
			// now write to stream
			if (outStream.is_open() && outStream.good())
			{
				// check if caller want to add a header
				if (addHeader)
				{
					// add message 
					outStream << "// this file was auto-generated from \"" << fileData.inPath.filename().string() << "\" by res2h" << std::endl << std::endl;
					// add header include
					if (!commonHeaderPath.empty())
					{
						// common header path must be relative to destination directory
						FS_NAMESPACE::path relativeHeaderPath = naiveUncomplete(commonHeaderPath, fileData.outPath);
						outStream << "#include \"" << relativeHeaderPath.generic_string() << "\"" << std::endl << std::endl;
					}
				}
				// create names for variables
				fileData.dataVariableName = fileData.outPath.filename().stem().string() + "_data";
				fileData.sizeVariableName = fileData.outPath.filename().stem().string() + "_size";
				// add size and data variable
				if (fileData.size <= UINT16_MAX)
				{
					outStream << "const uint16_t ";
				}
				else if (fileData.size <= UINT32_MAX)
				{
					outStream << "const uint32_t ";
				}
				else
				{
					outStream << "const uint64_t ";
				}
				outStream << fileData.sizeVariableName << " = " << std::dec << fileData.size << ";" << std::endl;
				outStream << "const uint8_t " << fileData.dataVariableName << "[" << std::dec << fileData.size << "] = {" << std::endl;
				outStream << "    "; // first indent
				// now add content
				uint64_t breakCounter = 0;
				while (!inStream.eof())
				{
					// read byte from source
					unsigned char dataByte;
					inStream.read((char *)&dataByte, 1);
					// check if we have actually read something
					if (inStream.gcount() != 1 || inStream.eof())
					{
						// we failed to read. break the read loop and close the file.
						break;
					}
					// write to destination in hex with a width of 2 and '0' as padding
					// we do not use showbase as it doesn't work with zero values
					outStream << "0x" << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)dataByte;
					// was this the last character?
					if (!inStream.eof() && fileData.size > static_cast<uint64_t>(inStream.tellg()))
					{
						// no. add comma.
						outStream << ",";
						// add break after 10 bytes and add indent again
						if (++breakCounter % 10 == 0)
						{
							outStream << std::endl << "    ";
						}
					}
				}
				// close curly braces
				outStream << std::endl << "};" << std::endl << std::endl;
				// close files
				if (closeOutStream)
				{
					outStream.close();
				}
				inStream.close();
				if (beVerbose)
				{
					std::cout << " - succeeded." << std::endl;
				}
				return true;
			}
			else
			{
				std::cout << "Error: Failed to open file \"" << fileData.outPath.string() << "\" for writing!" << std::endl;
				return false;
			}
		}
		else
		{
			std::cout << "Error: Failed to open file \"" << fileData.inPath.string() << "\" for reading!" << std::endl;
			return false;
		}
	}
	else
	{
		std::cout << "Error: File \"" << fileData.inPath.string() << "\" does not exist!" << std::endl;
	}
	return false;
}
示例#5
0
            pDevDesc ide_device::create_file_device(const std::string& device_type, const std::tr2::sys::path& filename, double width, double height) {
                auto expr = boost::format("%1%(filename='%2%', width=%3%, height=%4%)") % device_type % filename.generic_string() % width % height;

                // Create the file device via the public R API
                ParseStatus ps;
                auto result = rhost::eval::r_try_eval_str(expr.str(), R_GlobalEnv, ps);
                if (result.has_error) {
                    throw rhost::util::r_error(result.error.c_str());
                }

                pDevDesc dev_desc = nullptr;

                // Retrieve the device descriptor of the current device (the one created above)
                rhost::util::errors_to_exceptions([&] {
                    int device_num = Rf_curDevice();
                    pGEDevDesc ge_dev_desc = GEgetDevice(device_num);
                    dev_desc = ge_dev_desc->dev;
                });

                return dev_desc;
            }