//
// Load template with specified name
//
INT_32 CTPP2FileSourceLoader::LoadTemplate(CCHAR_P szTemplateName)
{
	sNormalizedFileName.erase();
	INT_32 iStatCode = 0;
	STLW::vector<STLW::string>::const_iterator itvIncludeDirs = vIncludeDirs.begin();
	while(itvIncludeDirs != vIncludeDirs.end())
	{
		STLW::string sTMP = *itvIncludeDirs;
#ifdef WIN32
		if ( sTMP.length() && sTMP[sTMP.length() - 1] != '/' && sTMP[sTMP.length() - 1] != '\\' ) { sTMP.append("\\", 1); }
#else
		if (sTMP.length() && sTMP[sTMP.length() - 1] != '/') { sTMP.append("/", 1); }
#endif
		sTMP.append(szTemplateName);

		sCurrentDir = GetBaseDir(sTMP, sNormalizedFileName);
		if (sNormalizedFileName.length() == 0)
		{
			STLW::string sError("invalid file name `");
			sError.append(sTMP);
			sError.append("`");
			throw CTPPLogicError(sError.c_str());
		}

		// Get file size
		struct stat oStat;
		iStatCode = stat(sNormalizedFileName.c_str(), &oStat);
		if (iStatCode == 0)
		{
			iTemplateSize = oStat.st_size;
			break;
		}
		++itvIncludeDirs;
	}

	if (iStatCode == -1)
	{
		STLW::string sError("cannot find file in include directories ");
		itvIncludeDirs = vIncludeDirs.begin();
		for (;;)
		{
			sError.append("`");
			if (itvIncludeDirs -> size() != 0) { sError.append(*itvIncludeDirs); }
			else
			{
				CHAR_P szPWD = getcwd(NULL, 0);
				sError.append(szPWD);
				free(szPWD);
			}
			sError.append("`");

			++itvIncludeDirs;
			if (itvIncludeDirs == vIncludeDirs.end()) { break; }

			sError.append(", ");
		}
		throw CTPPLogicError(sError.c_str());
	}

	if (iTemplateSize == 0)
	{
		STLW::string sError("empty file `");
		sError.append(sNormalizedFileName);
		sError.append("` found");
		throw CTPPLogicError(sError.c_str());
	}

	// Load file
	FILE * F = fopen(sNormalizedFileName.c_str(), "rb");
	if (F == NULL) { throw CTPPUnixException("fopen", errno); }

	if (sTemplate != NULL) { free(sTemplate); }

	// Allocate memory
	sTemplate = (CHAR_P)malloc(iTemplateSize);

	// Read from file
	if (fread(sTemplate, iTemplateSize, 1, F) != 1)
	{
		if (ferror(F) != 0)
		{
			free(sTemplate);
			fclose(F);
			throw CTPPUnixException("fread", errno);
		}
		else
		{
			free(sTemplate);
			fclose(F);
			throw CTPPLogicError("Cannot read from file");
		}
	}

	fclose(F);

return 0;
}
Ejemplo n.º 2
0
//
// Constructor
//
VMStringLoader::VMStringLoader(CCHAR_P rawContent, size_t rawContentSize)
{
    oCore = (VMExecutable *)malloc(rawContentSize + 1);
    memcpy(oCore, rawContent, rawContentSize);

	if (oCore -> magic[0] == 'C' &&
	    oCore -> magic[1] == 'T' &&
	    oCore -> magic[2] == 'P' &&
	    oCore -> magic[3] == 'P')
	{
		// Check version
		if (oCore -> version[0] >= 1)
		{
			// Platform-dependent data (byte order)
			if (oCore -> platform == 0x4142434445464748ull)
			{
#ifdef _DEBUG
				fprintf(stderr, "Big/Little Endian conversion: Nothing to do\n");
#endif

				// Nothing to do, only check crc
				UINT_32 iCRC = oCore -> crc;
				oCore -> crc = 0;

				// Calculate CRC of file
                // KELSON: next line used to refer to oStat.st_size
                // changed it to rawContentSize
				if (iCRC != crc32((UCCHAR_P)oCore, rawContentSize))
				{
					free(oCore);
					throw CTPPLogicError("CRC checksum invalid");
				}
			}
			// Platform-dependent data (byte order)
			else if (oCore -> platform == 0x4847464544434241ull)
			{
				// Need to reconvert data
#ifdef _DEBUG
				fprintf(stderr, "Big/Little Endian conversion: Need to reconvert core\n");
#endif
				ConvertExecutable(oCore);
			}
			else
			{
				free(oCore);
				throw CTPPLogicError("Conversion of middle-end architecture does not supported.");
			}

			// Check IEEE 754 format
			if (oCore -> ieee754double != 15839800103804824402926068484019465486336.0)
			{
				free(oCore);
				throw CTPPLogicError("IEEE 754 format is broken, cannot convert file");
			}
		}

		pVMMemoryCore = new VMMemoryCore(oCore);
	}
	else
	{
		free(oCore);
		throw CTPPLogicError("Not an CTPP bytecode file.");
	}
}