bool TranslationManager::openTranslationsFile(const FSNode &node, File &inFile, int depth) {
	if (!node.exists() || !node.isReadable() || !node.isDirectory())
		return false;

	// Check if we can find the file in this directory
	// Since File::open(FSNode) makes all the needed tests, it is not really
	// necessary to make them here. But it avoid printing warnings.
	FSNode fileNode = node.getChild("translations.dat");
	if (fileNode.exists() && fileNode.isReadable() && !fileNode.isDirectory()) {
		if (inFile.open(fileNode)) {
			if (checkHeader(inFile))
				return true;
			inFile.close();
		}
	}

	// Check if we exceeded the given recursion depth
	if (depth - 1 == -1)
		return false;

	// Otherwise look for it in sub-directories
	FSList fileList;
	if (!node.getChildren(fileList, FSNode::kListDirectoriesOnly))
		return false;

	for (FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) {
		if (openTranslationsFile(*i, inFile, depth == -1 ? - 1 : depth - 1))
			return true;
	}

	// Not found in this directory or its sub-directories
	return false;
}
Example #2
0
void TranslationManager::loadLanguageDat(int index) {
	_currentTranslationMessages.clear();
	_currentCharset.clear();
	// Sanity check
	if (index < 0 || index >= (int)_langs.size()) {
		if (index != -1)
			warning("Invalid language index %d passed to TranslationManager::loadLanguageDat", index);
		return;
	}

	File in;
	if (!openTranslationsFile(in))
		return;

	if (!checkHeader(in))
		return;

	char buf[1024];
	int len;

	// Get number of translations
	int nbTranslations = in.readUint16BE();
	if (nbTranslations != (int)_langs.size()) {
		warning("The 'translations.dat' file has changed since starting ScummVM. GUI translation will not be available");
		return;
	}

	// Get size of blocks to skip.
	int skipSize = 0;
	for (int i = 0; i < index + 2; ++i)
		skipSize += in.readUint16BE();
	// We also need to skip the remaining block sizes
	skipSize += 2 * (nbTranslations - index);

	// Seek to start of block we want to read
	in.seek(skipSize, SEEK_CUR);

	// Read number of translated messages
	int nbMessages = in.readUint16BE();
	_currentTranslationMessages.resize(nbMessages);

	// Read charset
	len = in.readUint16BE();
	in.read(buf, len);
	_currentCharset = String(buf, len - 1);

	// Read messages
	for (int i = 0; i < nbMessages; ++i) {
		_currentTranslationMessages[i].msgid = in.readUint16BE();
		len = in.readUint16BE();
		in.read(buf, len);
		_currentTranslationMessages[i].msgstr = String(buf, len - 1);
		len = in.readUint16BE();
		if (len > 0) {
			in.read(buf, len);
			_currentTranslationMessages[i].msgctxt = String(buf, len - 1);
		}
	}
}
void TranslationManager::loadTranslationsInfoDat() {
	File in;
	if (!openTranslationsFile(in)) {
		warning("You are missing a valid 'translations.dat' file. GUI translation will not be available");
		return;
	}

	char buf[256];
	int len;

	// Get number of translations
	int nbTranslations = in.readUint16BE();

	// Get number of codepages
	int nbCodepages = in.readUint16BE();

	// Determine where the codepages start
	_charmapStart = 0;
	for (int i = 0; i < nbTranslations + 3; ++i)
		_charmapStart += in.readUint16BE();
	_charmapStart += in.pos();

	// Read list of languages
	_langs.resize(nbTranslations);
	_langNames.resize(nbTranslations);
	for (int i = 0; i < nbTranslations; ++i) {
		len = in.readUint16BE();
		in.read(buf, len);
		_langs[i] = String(buf, len - 1);
		len = in.readUint16BE();
		in.read(buf, len);
		_langNames[i] = String(buf, len - 1);
	}

	// Read list of codepages
	_charmaps.resize(nbCodepages);
	for (int i = 0; i < nbCodepages; ++i) {
		len = in.readUint16BE();
		in.read(buf, len);
		_charmaps[i] = String(buf, len - 1);
	}

	// Read messages
	int numMessages = in.readUint16BE();
	_messageIds.resize(numMessages);
	for (int i = 0; i < numMessages; ++i) {
		len = in.readUint16BE();
		String msg;
		while (len > 0) {
			in.read(buf, len > 256 ? 256 : len);
			msg += String(buf, len > 256 ? 256 : len - 1);
			len -= 256;
		}
		_messageIds[i] = msg;
	}
}
Example #4
0
bool TranslationManager::openTranslationsFile(File& inFile) {
	// First try to open it directly (i.e. using the SearchMan).
	if (inFile.open("translations.dat"))
		return true;

	// Then look in the Themepath if we can find the file.
	if (ConfMan.hasKey("themepath"))
		return openTranslationsFile(FSNode(ConfMan.get("themepath")), inFile);

	return false;
}
Example #5
0
bool TranslationManager::openTranslationsFile(File &inFile) {
	// First look in the Themepath if we can find the file.
	if (ConfMan.hasKey("themepath") && openTranslationsFile(FSNode(ConfMan.get("themepath")), inFile))
		return true;

	// Then try to open it using the SearchMan.
	ArchiveMemberList fileList;
	SearchMan.listMatchingMembers(fileList, "translations.dat");
	for (ArchiveMemberList::iterator it = fileList.begin(); it != fileList.end(); ++it) {
		SeekableReadStream *stream = it->get()->createReadStream();
		if (stream && inFile.open(stream, it->get()->getName())) {
			if (checkHeader(inFile))
				return true;
			inFile.close();
		}
	}

	return false;
}
Example #6
0
void TranslationManager::loadTranslationsInfoDat() {
	File in;
	if (!openTranslationsFile(in)) {
		warning("You are missing the 'translations.dat' file. GUI translation will not be available");
		return;
	}

	if (!checkHeader(in))
		return;

	char buf[256];
	int len;

	// Get number of translations
	int nbTranslations = in.readUint16BE();

	// Skip all the block sizes
	for (int i = 0; i < nbTranslations + 2; ++i)
		in.readUint16BE();

	// Read list of languages
	_langs.resize(nbTranslations);
	_langNames.resize(nbTranslations);
	for (int i = 0; i < nbTranslations; ++i) {
		len = in.readUint16BE();
		in.read(buf, len);
		_langs[i] = String(buf, len - 1);
		len = in.readUint16BE();
		in.read(buf, len);
		_langNames[i] = String(buf, len - 1);
	}

	// Read messages
	int numMessages = in.readUint16BE();
	_messageIds.resize(numMessages);
	for (int i = 0; i < numMessages; ++i) {
		len = in.readUint16BE();
		in.read(buf, len);
		_messageIds[i] = String(buf, len - 1);
	}
}
void TranslationManager::loadLanguageDat(int index) {
	_currentTranslationMessages.clear();
	_currentCharset.clear();
	// Sanity check
	if (index < 0 || index >= (int)_langs.size()) {
		if (index != -1)
			warning("Invalid language index %d passed to TranslationManager::loadLanguageDat", index);
		return;
	}

	File in;
	if (!openTranslationsFile(in))
		return;

	char buf[1024];
	int len;

	// Get number of translations
	int nbTranslations = in.readUint16BE();
	if (nbTranslations != (int)_langs.size()) {
		warning("The 'translations.dat' file has changed since starting ResidualVM. GUI translation will not be available");
		return;
	}

	// Get the number of codepages
	int nbCodepages = in.readUint16BE();
	if (nbCodepages != (int)_charmaps.size()) {
		warning("The 'translations.dat' file has changed since starting ResidualVM. GUI translation will not be available");
		return;
	}

	// Get size of blocks to skip.
	int skipSize = 0;
	for (int i = 0; i < index + 3; ++i)
		skipSize += in.readUint16BE();
	// We also need to skip the remaining block sizes
	skipSize += 2 * (nbTranslations - index);

	// Seek to start of block we want to read
	in.seek(skipSize, SEEK_CUR);

	// Read number of translated messages
	int nbMessages = in.readUint16BE();
	_currentTranslationMessages.resize(nbMessages);

	// Read charset
	len = in.readUint16BE();
	in.read(buf, len);
	_currentCharset = String(buf, len - 1);

	// Read messages
	for (int i = 0; i < nbMessages; ++i) {
		_currentTranslationMessages[i].msgid = in.readUint16BE();
		len = in.readUint16BE();
		String msg;
		while (len > 0) {
			in.read(buf, len > 256 ? 256 : len);
			msg += String(buf, len > 256 ? 256 : len - 1);
			len -= 256;
		}
		_currentTranslationMessages[i].msgstr = msg;
		len = in.readUint16BE();
		if (len > 0) {
			in.read(buf, len);
			_currentTranslationMessages[i].msgctxt = String(buf, len - 1);
		}
	}

	// Find the charset
	int charmapNum = -1;
	for (uint i = 0; i < _charmaps.size(); ++i) {
		if (_charmaps[i].equalsIgnoreCase(_currentCharset)) {
			charmapNum = i;
			break;
		}
	}

	// Setup the new charset mapping
	if (charmapNum == -1) {
		delete[] _charmap;
		_charmap = nullptr;
	} else {
		if (!_charmap)
			_charmap = new uint32[256];

		in.seek(_charmapStart + charmapNum * 256 * 4, SEEK_SET);
		for (int i = 0; i < 256; ++i)
			_charmap[i] = in.readUint32BE();
	}

}