Skip to content
Snippets Groups Projects
Select Git revision
  • master default
  • mingw_gcc44
  • release_ABP1_012
  • release_ABP1_008
  • release_ABP1_006
  • release_ABP1_007
  • release_ABP1_005
  • release_ABP1_004
  • release_ABP1_003
  • pre_release_0.15
  • release_ABP1_001
  • release_ABP1_002
  • pre_release_0.13
  • pre_release_0.14
  • pre_release_0.11
  • pre_release_0.12
  • pre_release_0.10
  • pre_release_0.09
  • pre_release_0.08
19 results

ResourceCompiler.cpp

Blame
  • Forked from einsteinathome / graphicsframework
    230 commits behind the upstream repository.
    ResourceCompiler.cpp 6.57 KiB
    /***************************************************************************
     *   Copyright (C) 2008 by Oliver Bock                                     *
     *   oliver.bock[AT]aei.mpg.de                                             *
     *                                                                         *
     *   This file is part of Einstein@Home.                                   *
     *                                                                         *
     *   Einstein@Home is free software: you can redistribute it and/or modify *
     *   it under the terms of the GNU General Public License as published     *
     *   by the Free Software Foundation, version 2 of the License.            *
     *                                                                         *
     *   Einstein@Home is distributed in the hope that it will be useful,      *
     *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
     *   GNU General Public License for more details.                          *
     *                                                                         *
     *   You should have received a copy of the GNU General Public License     *
     *   along with Einstein@Home. If not, see <http://www.gnu.org/licenses/>. *
     *                                                                         *
     ***************************************************************************/
    
    #include "ResourceCompiler.h"
    
    ResourceCompiler::ResourceCompiler(const string inputFilename, const string outputFilename)
    {
    	m_ResourceSpecFile = inputFilename;
    	m_ResourceCodeFile = outputFilename;
    }
    
    ResourceCompiler::~ResourceCompiler()
    {
    }
    
    void ResourceCompiler::compile()
    {
    	// parse input file (resource <-> file mapping)
    	parseInputFile();
    	
    	// load the binary files (resource <-> data mapping)
    	loadBinaryData();
    	
    	// temporary variables
    	ostringstream resourceIdentifierInitializer;
    	ostringstream resourceIndexInitializer;
    	ostringstream resourceStorageInitializer;
    	
    	map<string, vector<unsigned char> >::iterator mapPos;
    	vector<unsigned char>::iterator dataPos;
    	unsigned int currentIndex = 0;
    	
    	// store total amount of resources
    	resourceIndexInitializer << "{0x" << hex << m_ResourceDataMap.size() << ", 0x0},";
    	
    	// iterate over all resource data mappings we have
    	for(mapPos = m_ResourceDataMap.begin(); mapPos != m_ResourceDataMap.end(); ++mapPos) {
    		
    		// store identifier
    		resourceIdentifierInitializer << "\"" << mapPos->first << "\",";
    		
    		// store data base index
    		resourceIndexInitializer << "{0x" << hex << currentIndex << ",";
    		resourceIndexInitializer << "0x" << hex << mapPos->second.size() << "},";
    		currentIndex += mapPos->second.size();
    
    		// iterate over the data content byte by byte
    		for(dataPos = mapPos->second.begin(); dataPos != mapPos->second.end(); ++dataPos) {
    			// store byte value as part of array initializer
    			resourceStorageInitializer << "0x" << hex << (int)*dataPos << ",";
    		}
    	}
    	
    	// open the output code file
    	ofstream outputFile(m_ResourceCodeFile.c_str(), ios::out);
    	if(!outputFile) {
    		cerr << "Couldn't open output file \"" <<  m_ResourceCodeFile << "\"!" << endl,		
    		exit(1);
    	}
    	
    	// let's get some exceptions
    	outputFile.exceptions(ios::failbit | ios::badbit);
    	
    	try {
    		// write header
    		outputFile << "#include <string>" << endl << endl;
    		
    		// write code file contents (remove trailing commas)
    		string output = resourceIdentifierInitializer.str();
    		outputFile << "extern const std::string c_ResourceIdentifiers[] = {" << endl;
    		outputFile << output.substr(0, output.length() - 1);
    		outputFile << endl << "};" << endl << endl;
    		
    		output = resourceIndexInitializer.str();
    		outputFile << "extern const unsigned int c_ResourceIndex[][2] = {" << endl;		
    		outputFile << output.substr(0, output.length() - 1);
    		outputFile << endl << "};" << endl << endl;
    		
    		output = resourceStorageInitializer.str();
    		outputFile << "extern const unsigned char c_ResourceStorage[] = {" << endl;
    		outputFile << output.substr(0, output.length() - 1);
    		outputFile << endl << "};" << endl << endl;
    	}
    	catch(const ios::failure& error) {
    		cerr << "Error during output file processing: " << error.what() << endl;
    	}
    	
    	// clean up and clode file
    	outputFile.flush();
    	outputFile.close();
    }
    
    void ResourceCompiler::parseInputFile()
    {
    	// open input file
    	ifstream inputFile(m_ResourceSpecFile.c_str(), ios::in);
    	if(!inputFile) {
    		cerr << "Couldn't open input file \"" <<  m_ResourceSpecFile << "\"!" << endl,
    		exit(1);
    	}
    	
    	// let's get some exceptions
    	inputFile.exceptions(ios::failbit | ios::badbit);
    	
    	try {
    		string line;
    		// read input file line by line
    		while(getline(inputFile, line)) {
    			
    			unsigned int firstCharacter = line.find_first_not_of(" \t\r\n\f");
    			
    			// we (sort of) allow for empty lines and comments
    			if(firstCharacter != string::npos && line.substr(firstCharacter, 1) != "#") { 
    				
    				// find our token delimiter
    				unsigned int separator = line.find("|");
    				
    				// make sure there's exactly one delimiter
    				if(separator == string::npos || separator != line.rfind("|")) {
    					cerr << "Unexpected resource specification: " << line << endl;
    				}
    				else {
    					// store tokens in resource file map
    					m_ResourceFileMap[line.substr(0, separator)] = line.substr(separator + 1);
    				}
    			}
    		}
    	}
    	catch(const ios::failure& error) {
    		// check stream state for real error
    		if(!inputFile.eof()) {
    			cerr << "Error during input file processing: " << error.what();
    		}		
    	}
    	
    	// close input file
    	inputFile.close();
    }
    
    void ResourceCompiler::loadBinaryData()
    {
    	map<string, string>::iterator pos;
    	
    	// iterate over all resource file mappings we have
    	for(pos = m_ResourceFileMap.begin(); pos != m_ResourceFileMap.end(); ++pos) {
    		
    		// open given resource file
    		ifstream binaryFile(pos->second.c_str(), ios::in | ios::binary);
    		if(!binaryFile) {
    			cerr << "Couldn't open binary file \"" <<  pos->second << "\"!" << endl,
    			exit(1);
    		}
    		
    		// let's get some exceptions
    		binaryFile.exceptions(ios::failbit | ios::badbit);
    		
    		try {
    			// store binary resource file using stream iterators
    //			copy(	istream_iterator<unsigned char>(binaryFile),
    //					istream_iterator<unsigned char>(),
    //					back_inserter(m_ResourceDataMap[pos->first])
    //			);
    			
    			// "copy" ends prematurely, so use the crude way instead
    			char c = 0;
    			while(binaryFile.get(c)) {
    				m_ResourceDataMap[pos->first].push_back(c);
    			}
    		}
    		catch(const ios::failure& error) {
    			// check stream state for real error
    			if(!binaryFile.eof()) {
    				cerr << "Error during binary file processing: " << error.what();
    			}	
    		}
    
    		// close current file
    		binaryFile.close();
    	}
    }