Initial source commit
This commit is contained in:
commit
f1384c11ee
335 changed files with 52715 additions and 0 deletions
360
minorGems/util/TranslationManager.cpp
Normal file
360
minorGems/util/TranslationManager.cpp
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2004-October-7 Jason Rohrer
|
||||
* Created.
|
||||
*
|
||||
* 2006-February-19 Jason Rohrer
|
||||
* Fixed an inconsistency in memory management.
|
||||
*
|
||||
* 2008-September-17 Jason Rohrer
|
||||
* Support for setting language data directly.
|
||||
*
|
||||
* 2010-March-21 Jason Rohrer
|
||||
* Fixed crash if default language file not found.
|
||||
*
|
||||
* 2010-May-14 Jason Rohrer
|
||||
* String parameters as const to fix warnings.
|
||||
*/
|
||||
|
||||
#include "TranslationManager.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "minorGems/io/file/File.h"
|
||||
|
||||
|
||||
|
||||
// will be destroyed automatically at program termination
|
||||
TranslationManagerStaticMembers TranslationManager::mStaticMembers;
|
||||
|
||||
|
||||
|
||||
void TranslationManager::setDirectoryName( const char *inName ) {
|
||||
mStaticMembers.setDirectoryAndLanguage( inName,
|
||||
mStaticMembers.mLanguageName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *TranslationManager::getDirectoryName() {
|
||||
return stringDuplicate( mStaticMembers.mDirectoryName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
char **TranslationManager::getAvailableLanguages( int *outNumLanguages ) {
|
||||
File *languageDirectory = new File( NULL, mStaticMembers.mDirectoryName );
|
||||
|
||||
if( languageDirectory->exists() && languageDirectory->isDirectory() ) {
|
||||
|
||||
int numChildFiles;
|
||||
File **childFiles = languageDirectory->getChildFiles( &numChildFiles );
|
||||
|
||||
if( childFiles != NULL ) {
|
||||
SimpleVector<char*> *languageNames = new SimpleVector<char*>();
|
||||
|
||||
for( int i=0; i<numChildFiles; i++ ) {
|
||||
|
||||
char *name = childFiles[i]->getFileName();
|
||||
|
||||
char *extensionPointer = strstr( name, ".txt" );
|
||||
|
||||
if( extensionPointer != NULL ) {
|
||||
// terminate string, cutting off extension
|
||||
extensionPointer[0] = '\0';
|
||||
|
||||
languageNames->push_back( stringDuplicate( name ) );
|
||||
}
|
||||
|
||||
delete [] name;
|
||||
delete childFiles[i];
|
||||
}
|
||||
delete [] childFiles;
|
||||
|
||||
char **returnArray = languageNames->getElementArray();
|
||||
|
||||
*outNumLanguages = languageNames->size();
|
||||
|
||||
delete languageNames;
|
||||
|
||||
|
||||
delete languageDirectory;
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete languageDirectory;
|
||||
|
||||
// default, if we didn't return above
|
||||
*outNumLanguages = 0;
|
||||
return new char*[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TranslationManager::setLanguage( const char *inLanguageName ) {
|
||||
mStaticMembers.setDirectoryAndLanguage( mStaticMembers.mDirectoryName,
|
||||
inLanguageName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TranslationManager::setLanguageData( const char *inData ) {
|
||||
mStaticMembers.setTranslationData( inData );
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *TranslationManager::translate( const char *inTranslationKey ) {
|
||||
|
||||
char *translatedString = NULL;
|
||||
|
||||
SimpleVector<char *> *keys =
|
||||
mStaticMembers.mTranslationKeys;
|
||||
|
||||
SimpleVector<char *> *naturalLanguageStrings =
|
||||
mStaticMembers.mNaturalLanguageStrings;
|
||||
|
||||
|
||||
if( keys != NULL ) {
|
||||
int numKeys = keys->size();
|
||||
|
||||
for( int i=0; i<numKeys && translatedString == NULL; i++ ) {
|
||||
|
||||
if( strcmp( inTranslationKey, *( keys->getElement( i ) ) ) == 0 ) {
|
||||
// keys match
|
||||
translatedString =
|
||||
*( naturalLanguageStrings->getElement( i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( translatedString == NULL ) {
|
||||
// no translation exists
|
||||
|
||||
// the translation for this key is the key itself
|
||||
|
||||
// add it to our translation table
|
||||
|
||||
char *key = stringDuplicate( inTranslationKey );
|
||||
char *value = stringDuplicate( inTranslationKey );
|
||||
|
||||
keys->push_back( key );
|
||||
naturalLanguageStrings->push_back( value );
|
||||
|
||||
// thus, we return a value from our table, just as if a translation
|
||||
// had existed for this string
|
||||
translatedString = value;
|
||||
}
|
||||
|
||||
return translatedString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TranslationManagerStaticMembers::TranslationManagerStaticMembers()
|
||||
: mDirectoryName( NULL ),
|
||||
mLanguageName( NULL ),
|
||||
mTranslationKeys( NULL ),
|
||||
mNaturalLanguageStrings( NULL ) {
|
||||
|
||||
// default
|
||||
setDirectoryAndLanguage( "languages", "English" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
TranslationManagerStaticMembers::~TranslationManagerStaticMembers() {
|
||||
if( mDirectoryName != NULL ) {
|
||||
delete [] mDirectoryName;
|
||||
}
|
||||
|
||||
if( mLanguageName != NULL ) {
|
||||
delete [] mLanguageName;
|
||||
}
|
||||
|
||||
if( mTranslationKeys != NULL ) {
|
||||
int numKeys = mTranslationKeys->size();
|
||||
|
||||
for( int i=0; i<numKeys; i++ ) {
|
||||
delete [] *( mTranslationKeys->getElement( i ) );
|
||||
}
|
||||
delete mTranslationKeys;
|
||||
}
|
||||
|
||||
if( mNaturalLanguageStrings != NULL ) {
|
||||
int numKeys = mNaturalLanguageStrings->size();
|
||||
|
||||
for( int i=0; i<numKeys; i++ ) {
|
||||
delete [] *( mNaturalLanguageStrings->getElement( i ) );
|
||||
}
|
||||
delete mNaturalLanguageStrings;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TranslationManagerStaticMembers::setDirectoryAndLanguage(
|
||||
const char *inDirectoryName,
|
||||
const char *inLanguageName ) {
|
||||
|
||||
// save temp copies first to allow caller to pass our own members in to us
|
||||
char *tempDirectoryName = stringDuplicate( inDirectoryName );
|
||||
char *tempLanguageName = stringDuplicate( inLanguageName );
|
||||
|
||||
|
||||
if( mDirectoryName != NULL ) {
|
||||
delete [] mDirectoryName;
|
||||
}
|
||||
|
||||
if( mLanguageName != NULL ) {
|
||||
delete [] mLanguageName;
|
||||
}
|
||||
|
||||
mDirectoryName = tempDirectoryName;
|
||||
mLanguageName = tempLanguageName;
|
||||
|
||||
char dataSet = false;
|
||||
|
||||
|
||||
File *directoryFile = new File( NULL, mDirectoryName );
|
||||
|
||||
if( directoryFile->exists() && directoryFile->isDirectory() ) {
|
||||
|
||||
char *languageFileName = autoSprintf( "%s.txt", mLanguageName );
|
||||
|
||||
File *languageFile = directoryFile->getChildFile( languageFileName );
|
||||
|
||||
delete [] languageFileName;
|
||||
|
||||
|
||||
if( languageFile != NULL ) {
|
||||
|
||||
|
||||
char *languageData = languageFile->readFileContents();
|
||||
|
||||
if( languageData != NULL ) {
|
||||
|
||||
dataSet = true;
|
||||
|
||||
setTranslationData( languageData );
|
||||
delete [] languageData;
|
||||
}
|
||||
delete languageFile;
|
||||
}
|
||||
}
|
||||
|
||||
delete directoryFile;
|
||||
|
||||
|
||||
if( !dataSet ) {
|
||||
// failed to open file...
|
||||
|
||||
// set blank data to ensure that vectors are created
|
||||
setTranslationData( "" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline char *stringSkip( const char *inString, int inNumChars ) {
|
||||
return (char *)( &( inString[ inNumChars ] ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TranslationManagerStaticMembers::setTranslationData( const char *inData ) {
|
||||
|
||||
// clear the old translation table
|
||||
if( mTranslationKeys != NULL ) {
|
||||
int numKeys = mTranslationKeys->size();
|
||||
|
||||
for( int i=0; i<numKeys; i++ ) {
|
||||
delete [] *( mTranslationKeys->getElement( i ) );
|
||||
}
|
||||
delete mTranslationKeys;
|
||||
}
|
||||
|
||||
if( mNaturalLanguageStrings != NULL ) {
|
||||
int numKeys = mNaturalLanguageStrings->size();
|
||||
|
||||
for( int i=0; i<numKeys; i++ ) {
|
||||
delete [] *( mNaturalLanguageStrings->getElement( i ) );
|
||||
}
|
||||
delete mNaturalLanguageStrings;
|
||||
}
|
||||
|
||||
|
||||
// now read in the translation table
|
||||
mTranslationKeys = new SimpleVector<char *>();
|
||||
mNaturalLanguageStrings = new SimpleVector<char *>();
|
||||
|
||||
|
||||
|
||||
char readError = false;
|
||||
|
||||
while( ! readError ) {
|
||||
|
||||
char *key = new char[ 100 ];
|
||||
|
||||
int numRead = sscanf( inData, "%99s", key );
|
||||
|
||||
if( numRead == 1 ) {
|
||||
|
||||
inData = stringSkip( inData, strlen( key ) );
|
||||
|
||||
|
||||
// skip the first "
|
||||
int readChar = ' ';
|
||||
|
||||
while( readChar != '"' && readChar != '\0' ) {
|
||||
readChar = inData[0];
|
||||
inData = stringSkip( inData, 1 );
|
||||
}
|
||||
if( readChar != EOF ) {
|
||||
char *naturalLanguageString = new char[1000];
|
||||
// scan a string of up to 999 characters, stopping
|
||||
// at the first " character
|
||||
numRead = sscanf( inData, "%999[^\"]",
|
||||
naturalLanguageString );
|
||||
|
||||
if( numRead == 1 ) {
|
||||
inData = stringSkip( inData,
|
||||
strlen( naturalLanguageString ) );
|
||||
|
||||
// trim the key and string and save them
|
||||
mTranslationKeys->push_back(
|
||||
stringDuplicate( key ) );
|
||||
mNaturalLanguageStrings->push_back(
|
||||
stringDuplicate( naturalLanguageString ) );
|
||||
}
|
||||
else {
|
||||
readError = true;
|
||||
}
|
||||
delete [] naturalLanguageString;
|
||||
|
||||
// skip the trailing "
|
||||
readChar = ' ';
|
||||
|
||||
while( readChar != '"' && readChar != '\0' ) {
|
||||
readChar = inData[0];
|
||||
inData = stringSkip( inData, 1 );
|
||||
}
|
||||
}
|
||||
else {
|
||||
readError = true;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
readError = true;
|
||||
}
|
||||
delete [] key;
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue