1. Andreas Tscharner
  2. lrc

Source

lrc / src / ResourceData.cxx

Andreas Tscharne… f2756e1 

Andreas Tscharne… c6b409b 
Andreas Tscharne… f2756e1 

Andreas Tscharne… 13365b8 


Andreas Tscharne… f2756e1 





Andreas Tscharne… 13365b8 

Andreas Tscharne… f2756e1 



Andreas Tscharne… d2a5ff6 
Andreas Tscharne… c6b409b 

Andreas Tscharne… 697e785 
Andreas Tscharne… d2a5ff6 

Andreas Tscharne… f2756e1 

Andreas Tscharne… 697e785 
Andreas Tscharne… c6b409b 













Andreas Tscharne… f2756e1 


Andreas Tscharne… dd97817 
Andreas Tscharne… d4048e1 
Andreas Tscharne… ec0a3ef 

Andreas Tscharne… d4048e1 
Andreas Tscharne… c6b409b 
Andreas Tscharne… f2756e1 



Andreas Tscharne… dd97817 

Andreas Tscharne… 2fbe679 

Andreas Tscharne… c6b409b 

Andreas Tscharne… f2756e1 
Andreas Tscharne… 2fbe679 
Andreas Tscharne… ef66100 
Andreas Tscharne… 2fbe679 







Andreas Tscharne… dee68cb 
Andreas Tscharne… 2fbe679 
Andreas Tscharne… 697e785 
Andreas Tscharne… 2fbe679 

Andreas Tscharne… ef66100 
Andreas Tscharne… 2fbe679 







Andreas Tscharne… 9efd195 
Andreas Tscharne… 2fbe679 
Andreas Tscharne… 697e785 
Andreas Tscharne… 2fbe679 

Andreas Tscharne… 6f99145 




Andreas Tscharne… dd97817 
Andreas Tscharne… 2fbe679 
Andreas Tscharne… dd97817 


Andreas Tscharne… 2fbe679 
Andreas Tscharne… 697e785 
Andreas Tscharne… dd97817 











Andreas Tscharne… 2fbe679 

Andreas Tscharne… 6f99145 




Andreas Tscharne… ec0a3ef 
Andreas Tscharne… 2fbe679 

Andreas Tscharne… 697e785 
Andreas Tscharne… 2fbe679 
Andreas Tscharne… d4048e1 
Andreas Tscharne… 6f99145 




Andreas Tscharne… d4048e1 


Andreas Tscharne… 5218d13 
Andreas Tscharne… d4048e1 
Andreas Tscharne… 6f99145 
Andreas Tscharne… a97de46 
Andreas Tscharne… 6f99145 


Andreas Tscharne… d2a5ff6 












Andreas Tscharne… f1e1c44 
Andreas Tscharne… d2a5ff6 



Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 




Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 


Andreas Tscharne… c6b409b 








Andreas Tscharne… d2a5ff6 


Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 








Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 







Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 











Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 









Andreas Tscharne… 2513f74 
Andreas Tscharne… dee68cb 
Andreas Tscharne… d2a5ff6 



Andreas Tscharne… dd97817 
Andreas Tscharne… d2a5ff6 


Andreas Tscharne… 2513f74 
Andreas Tscharne… d2a5ff6 


Andreas Tscharne… dee68cb 
Andreas Tscharne… d2a5ff6 




Andreas Tscharne… 4d1e6e6 
Andreas Tscharne… dd97817 


Andreas Tscharne… 4d1e6e6 
Andreas Tscharne… dee68cb 
















Andreas Tscharne… c6b409b 







Andreas Tscharne… dee68cb 





Andreas Tscharne… dd97817 
Andreas Tscharne… dee68cb 




















Andreas Tscharne… dd97817 
Andreas Tscharne… dee68cb 
Andreas Tscharne… 4d1e6e6 

Andreas Tscharne… c6b409b 



















//      ResourceData.cxx
//
//      Copyright 2011, 2012 Andreas Tscharner <andy@vis.ethz.ch>
//
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU Lesser General Public License as
//      published by the Free Software Foundation; either version 3 of the
//      License, or (at your option) any later version.
//
//      This program 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 Lesser General Public
//      License along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.


#include <tuple>
#include <cstring>
#include <cstdio>
#include "Utils.hxx"
#include "StatusCodes.hxx"
#include "Factories.hxx"
#include "ResourceData.hxx"


void ResourceData::set_error_msg(char *p_newErrMsg)
{
	size_t newLen;


	if (m_errorMsg) {
		delete[] m_errorMsg;
	};

	newLen = strlen(p_newErrMsg) + 1;
	m_errorMsg = new char[newLen];
	memset(m_errorMsg, 0, newLen);
	strncpy(m_errorMsg, p_newErrMsg, (newLen-1));
}

ResourceData::ResourceData(void)
{
	m_password = nullptr;
	m_filename = nullptr;
	m_encryption = lrc::NoneEncryption;
	m_compression = lrc::NoneCompression;
	m_inFilePosition = std::make_tuple(-1, -1);
	m_errorMsg = nullptr;
}

ResourceData::~ResourceData(void)
{
	if (m_password)
		delete[] m_password;
	if (m_filename)
		delete[] m_filename;
	if (m_errorMsg)
		delete[] m_errorMsg;
}

void ResourceData::set_ident(const char *p_resIdent)
{
	int sLen;


	sLen = strlen(p_resIdent);
	if (m_resID)
		delete[] m_resID;
	m_resID = new char[sLen+1];
	memset(m_resID, 0, (sLen+1));
	strncpy(m_resID, p_resIdent, sLen);
	DEBUG_PRINT(("New resource ID: %s\n", m_resID))
}

void ResourceData::set_file(const char *p_resFilename)
{
	int sLen;


	sLen = strlen(p_resFilename);
	if (m_filename)
		delete[] m_filename;
	m_filename = new char[sLen+1];
	memset(m_filename, 0, (sLen+1));
	strncpy(m_filename, p_resFilename, sLen);
	DEBUG_PRINT(("Filename for resource: %s\n", m_filename))
}

char *ResourceData::get_file(void)
{
	return m_filename;
}

void ResourceData::set_encryption(lrc::EncryptionType p_resEncryption, const unsigned char *p_password)
{
	int pLen;


	m_encryption = p_resEncryption;
	DEBUG_PRINT(("Encryption type: %u\n", m_encryption))

	if (m_password) {
		delete[] m_password;
	};
	if (p_password == nullptr) {
		m_password = nullptr;
		return;
	};
	pLen = password_len(p_password) + 1;
	m_password = new unsigned char[pLen];
	memset(m_password, 0, pLen);
	memcpy(m_password, p_password, (pLen-1));
}

lrc::EncryptionType ResourceData::get_encryption(void)
{
	return m_encryption;
}

void ResourceData::set_compression(lrc::CompressionType p_resCompression)
{
	m_compression = p_resCompression;
	DEBUG_PRINT(("Compression type: %u\n", m_compression))
}

lrc::CompressionType ResourceData::get_compression(void)
{
	return m_compression;
}

void ResourceData::set_rc_position(int p_line, int p_col)
{
	m_inFilePosition = std::make_tuple(p_line, p_col);
	DEBUG_PRINT(("InFilePosition (RC): %d/%d\n", std::get<0>(m_inFilePosition), std::get<1>(m_inFilePosition)))
}

inFilePosition ResourceData::get_rc_position(void)
{
	return m_inFilePosition;
}

int ResourceData::prepare_resource_from_file(unsigned char **p_resData, size_t &p_resSize)
{
	lrc::CompressDecompress *compressor;
	lrc::EncryptDecrypt *encryptor;
	FILE *resFileHandle;
	size_t resFileSize, actFileSize;
	int retVal;
	unsigned char *resFileBuf;
	unsigned char *compDataBuf;
	unsigned char *encDataBuf;


	if (!p_resData) {
		return ERROR_INVALID_PARAMETER;
	};

	if (!file_exists(m_filename)) {
		std::get<1>(m_inFilePosition) = 2;
		return ERROR_FILE_NOT_FOUND;
	};

	compressor = CompressionFactory::get_compression_class(m_compression);
	if (!compressor) {
		std::get<1>(m_inFilePosition) = 3;
		return ERROR_COMPRESSION_NOT_AVAILABLE;
	};

	try {
		encryptor = EncryptionFactory::get_encryption_class(m_encryption, m_resID);
	} catch (lrcEncryptionDisabledException const &encDisabledEx) {
		this->set_error_msg((char *)encDisabledEx.what());

		delete compressor;
		std::get<1>(m_inFilePosition) = 4;
		return ERROR_ENCRYPTION_NOT_AVAILABLE;
	};
	if (!encryptor) {
		delete compressor;

		std::get<1>(m_inFilePosition) = 4;
		return ERROR_ENCRYPTION_NOT_AVAILABLE;
	};

	resFileSize = file_size(m_filename);
	DEBUG_PRINT(("File %s is %d in size\n", m_filename, resFileSize))
	if (resFileSize < 0) {
		delete encryptor;
		delete compressor;

		std::get<1>(m_inFilePosition) = 2;
		return resFileSize;
	};

	resFileHandle = fopen(m_filename, "rb");
	if (!resFileHandle) {
		delete encryptor;
		delete compressor;

		std::get<1>(m_inFilePosition) = 2;
		return ERROR_FILE_OPEN;
	};

	resFileBuf = new unsigned char[resFileSize+1];
	actFileSize = fread(resFileBuf, sizeof(unsigned char), resFileSize, resFileHandle);
	DEBUG_PRINT(("%d bytes read from %s (%d expected)\n", actFileSize, m_filename, resFileSize))
	if (actFileSize != resFileSize) {
		delete[] resFileBuf;
		fclose(resFileHandle);
		delete encryptor;
		delete compressor;

		std::get<1>(m_inFilePosition) = 2;
		return ERROR_FILE_READ;
	};
	fclose(resFileHandle);

	retVal = compressor->compress(resFileBuf, resFileSize, &compDataBuf, actFileSize);
	if (!no_error(retVal)) {
		delete[] resFileBuf,
		delete encryptor;
		delete compressor;

		std::get<1>(m_inFilePosition) = 3;
		return ERROR_COMPRESSION_COMPRESS;
	};
	delete[] resFileBuf;
	delete compressor;

	retVal = encryptor->encrypt(m_password, compDataBuf, actFileSize, &encDataBuf, actFileSize);
	if (!no_error(retVal)) {
		delete encryptor;

		std::get<1>(m_inFilePosition) = 4;
		return ERROR_ENCRYPTION_ENCRYPT;
	};
	delete[] compDataBuf;
	delete encryptor;

	*p_resData = encDataBuf;
	p_resSize = actFileSize;
	return NO_ERROR;
}

int ResourceData::get_data_from_memory(unsigned char *p_dataStart,
                                       resEntry p_resEntry,
                                       const unsigned char *p_password)
{
	lrc::CompressDecompress *decompressor;
	lrc::EncryptDecrypt *decryptor;
	int retVal;
	unsigned char *decryptData;
	unsigned char *decompData;
	size_t decryptSize, decompSize;


	if ((!p_dataStart) || (!p_resEntry.resID) || (p_resEntry.resSize <= 0)) {
		return ERROR_INVALID_PARAMETER;
	};

	decompressor = CompressionFactory::get_compression_class(p_resEntry.compType);
	if (!decompressor) {
		return ERROR_COMPRESSION_NOT_AVAILABLE;
	};

	try {
		decryptor = EncryptionFactory::get_encryption_class(p_resEntry.encType, p_resEntry.resID);
	} catch (lrcEncryptionDisabledException const &encDisabledEx) {
		this->set_error_msg((char *)encDisabledEx.what());

		delete decompressor;
		return ERROR_ENCRYPTION_NOT_AVAILABLE;
	};
	if (!decryptor) {
		delete decompressor;

		return ERROR_ENCRYPTION_NOT_AVAILABLE;
	};

	retVal = decryptor->decrypt(p_password, p_dataStart, p_resEntry.resSize, &decryptData, decryptSize);
	if (!no_error(retVal)) {
		delete decryptor;
		delete decompressor;

		return ERROR_ENCRYPTION_DECRYPT;
	};
	delete decryptor;

	retVal = decompressor->decompress(decryptData, decryptSize, &decompData, decompSize);
	if (!no_error(retVal)) {
		delete[] decryptData;
		delete decompressor;

		return ERROR_COMPRESSION_DECOMPRESS;
	};
	delete[] decryptData;

	this->set_ident(p_resEntry.resID);
	m_resData = decompData;
	m_resSize = decompSize;
	this->set_compression(p_resEntry.compType);
	this->set_encryption(p_resEntry.encType, p_password);

	return NO_ERROR;
}

char *ResourceData::get_error_msg(void)
{
	size_t errMsgLen;
	char *retErrMsg;


	if (!m_errorMsg) {
		return nullptr;
	};

	errMsgLen = strlen(m_errorMsg);
	retErrMsg = new char[errMsgLen+1];
	memset(retErrMsg, 0, (errMsgLen+1));
	strncpy(retErrMsg, m_errorMsg, errMsgLen);

	delete[] m_errorMsg;
	m_errorMsg = nullptr;

	return retErrMsg;
}