[sword-cvs] sword/src/mgr stringmgr.cpp,NONE,1.1 Makefile.am,1.15,1.16 localemgr.cpp,1.18,1.19 swlocale.cpp,1.9,1.10

sword@www.crosswire.org sword@www.crosswire.org
Sat, 17 Apr 2004 10:16:19 -0700


Update of /cvs/core/sword/src/mgr
In directory www:/tmp/cvs-serv8616/src/mgr

Modified Files:
	Makefile.am localemgr.cpp swlocale.cpp 
Added Files:
	stringmgr.cpp 
Log Message:
Added StringMgr to allow frontend side unicode handling; breaks no code; IcuStringMgr needs a fix in upperUtf8; added support for loading Utf8 locales (joachim)

--- NEW FILE: stringmgr.cpp ---
/******************************************************************************
 *  stringmgr.cpp - implementation of class LocaleMgr used to interact with
 *				registered locales for a sword installation
 *
 * $Id: stringmgr.cpp,v 1.1 2004/04/17 17:16:17 joachim Exp $
 *
 * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
 *	CrossWire Bible Society
 *	P. O. Box 2528
 *	Tempe, AZ  85280-2528
 *
 * This program 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.
 *
 * 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.
 *
 */

#include <stringmgr.h>
#include <swlog.h>
#include <localemgr.h>
#include <utilstr.h>

#ifdef _ICU_

#include <unicode/utypes.h>
#include <unicode/ucnv.h>
#include <unicode/ustring.h>
#include <unicode/uchar.h>

#include <unicode/unistr.h>
#include <unicode/translit.h>

#include <unicode/locid.h>

#endif

SWORD_NAMESPACE_START

StringMgr* StringMgr::m_systemStringMgr = 0;

class __staticsystemStringMgr {
public:
 	__staticsystemStringMgr() { }
 	~__staticsystemStringMgr() { delete StringMgr::m_systemStringMgr; StringMgr::m_systemStringMgr = 0; }
} _staticsystemStringMgr;


#ifdef _ICU_

	//here comes our IcuStringMgr reimplementation
	class IcuStringMgr : public StringMgr {
	public:
		virtual char* upperUtf8(char*, const unsigned int maxlen = 0);
		virtual char* upperLatin1(char*);
	
	protected:
		virtual const bool supportsUnicode() const {
			return true;
		};
	};

#endif


/** Default constructor
*/		
StringMgr::StringMgr() {
}

/** Copy constructor
*/	
StringMgr::StringMgr( const StringMgr& m ) {
}

/** Destructor
*/	
StringMgr::~StringMgr() {
}

/** Sets the global StringMgr handle
* @param newStringMgr The new global StringMgr. This pointer will be deleted by this StringMgr
*/	
void StringMgr::setSystemStringMgr( StringMgr* newStringMgr ) {
	if (m_systemStringMgr) 
		delete m_systemStringMgr;
	
	m_systemStringMgr = newStringMgr;
	LocaleMgr::getSystemLocaleMgr()->setSystemLocaleMgr( new LocaleMgr() );
}

/** Returns the global StringMgr handle
* @return The global string handle
*/
StringMgr* StringMgr::getSystemStringMgr() {
	if (!m_systemStringMgr) {
#ifndef _ICU_
		m_systemStringMgr = new StringMgr();
		SWLog::getSystemLog()->logError("created default StringMgr");
#else
		m_systemStringMgr = new IcuStringMgr();
		SWLog::getSystemLog()->logError("created default IcuStringMgr");
#endif	
	}
	
	return m_systemStringMgr;
}


/** Converts the param to an upper case Utf8 string
* @param The text encoded in utf8 which should be turned into an upper case string
*/	
char* StringMgr::upperUtf8(char* t, const unsigned int maxlen) {
	//the default impl does nothing
// 	SWLog::getSystemLog()->logError("StringMgr::upperUtf8 with %s and %d", t, maxlen);

	return t;
}

/** Converts the param to an uppercase latin1 string
* @param The text encoded in latin1 which should be turned into an upper case string
*/	
char* StringMgr::upperLatin1(char* t) {
// 	SWLog::getSystemLog()->logError("StringMgr::upperLatin1 with %s", t);
	char* ret = t;
 	while (*t) {
 		*t++ = SW_toupper(*t);
 	}
	
	return ret;
}

const bool StringMgr::supportsUnicode() const {
// 	SWLog::getSystemLog()->logError("StringMgr::supportsUtf8");
	return false; //default impl has no UTF8 support
}


#ifdef _ICU_

	char* IcuStringMgr::upperUtf8(char* buf, const unsigned int maxlen) {
		char *ret = buf;
		
		int max = maxlen;
		if (!max)
			max = strlen(ret);

		UErrorCode err = U_ZERO_ERROR;
		UConverter *conv = ucnv_open("UTF-8", &err);
		UnicodeString str(buf, -1, conv, err);
		UnicodeString ustr = str.toUpper();
		ustr.extract(ret, max+1, conv, err);
		
		SWLog::getSystemLog()->logError("%s", u_errorName(err));
		
		ucnv_close(conv);
		
		SWLog::getSystemLog()->logError("%s", ret);
		return ret;
	}
	
	char* IcuStringMgr::upperLatin1(char* t) {
 		StringMgr::upperLatin1(t); //use the default implementation
	}
	
#endif

SWORD_NAMESPACE_END

Index: Makefile.am
===================================================================
RCS file: /cvs/core/sword/src/mgr/Makefile.am,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- Makefile.am	12 Apr 2004 13:47:22 -0000	1.15
+++ Makefile.am	17 Apr 2004 17:16:17 -0000	1.16
@@ -25,6 +25,7 @@
 libsword_la_SOURCES += $(mgrdir)/swcacher.cpp
 libsword_la_SOURCES += $(mgrdir)/swsearchable.cpp
 libsword_la_SOURCES += $(mgrdir)/installmgr.cpp
+libsword_la_SOURCES += $(mgrdir)/stringmgr.cpp
 
 if BUILDSPLITLIB
 libsword_imp_la_SOURCES += $(mgrsplits)

Index: localemgr.cpp
===================================================================
RCS file: /cvs/core/sword/src/mgr/localemgr.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- localemgr.cpp	6 Feb 2004 21:01:01 -0000	1.18
+++ localemgr.cpp	17 Apr 2004 17:16:17 -0000	1.19
@@ -36,8 +36,9 @@
 #include <swmgr.h>
 #include <utilfuns.h>
 
-#include <localemgr.h>
+#include <stringmgr.h>
 #include <filemgr.h>
+#include <localemgr.h>
 
 SWORD_NAMESPACE_START
 
@@ -120,7 +121,7 @@
 LocaleMgr::~LocaleMgr() {
 	if (defaultLocaleName)
 		delete [] defaultLocaleName;
-     deleteLocales();
+     	deleteLocales();
 	delete locales;
 }
 
@@ -140,15 +141,29 @@
 					newmodfile += "/";
 				newmodfile += ent->d_name;
 				SWLocale *locale = new SWLocale(newmodfile.c_str());
-				if (locale->getName()) {
+				
+				if (locale->getName()) {					
+					bool supported = false;
+					if (StringMgr::hasUtf8Support()) {
+						supported = (locale->getEncoding() && (!strcmp(locale->getEncoding(), "UTF-8") /*|| !strcmp(locale->getEncoding(), "ISO8859-1")*/) );
+					}
+					else {
+						supported = !locale->getEncoding() || (locale->getEncoding() && strcmp(locale->getEncoding(), "UTF-8"));
+					}
+					
+					if (!supported) { //not supported
+						delete locale;						
+						continue;
+					}
+				
 					it = locales->find(locale->getName());
-					if (it != locales->end()) {
+					if (it != locales->end()) { // already present
 						*((*it).second) += *locale;
 						delete locale;
 					}
 					else locales->insert(LocaleMap::value_type(locale->getName(), locale));
 				}
-                    else	delete locale;
+				else	delete locale;
 			}
 		}
 		closedir(dir);

Index: swlocale.cpp
===================================================================
RCS file: /cvs/core/sword/src/mgr/swlocale.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- swlocale.cpp	12 Apr 2004 13:49:12 -0000	1.9
+++ swlocale.cpp	17 Apr 2004 17:16:17 -0000	1.10
@@ -30,7 +30,7 @@
 
 	name         = 0;
 	description  = 0;
-	encoding		 = 0;
+	encoding     = 0;
 	bookAbbrevs  = 0;
 	BMAX         = 0;
 	books        = 0;
@@ -47,7 +47,7 @@
 	if (confEntry != localeSource->Sections["Meta"].end())
 		stdstr(&description, (*confEntry).second.c_str());
 
-	confEntry = localeSource->Sections["Meta"].find("Encoding");
+	confEntry = localeSource->Sections["Meta"].find("Encoding"); //Either empty (==Latin1) or UTF-8
 	if (confEntry != localeSource->Sections["Meta"].end())
 		stdstr(&encoding, (*confEntry).second.c_str());
 }
@@ -57,6 +57,9 @@
 
 	delete localeSource;
 
+	if (encoding)
+		delete [] encoding;
+	
 	if (description)
 		delete [] description;
 
@@ -90,7 +93,29 @@
 		confEntry = localeSource->Sections["Text"].find(text);
 		if (confEntry == localeSource->Sections["Text"].end())
 			lookupTable.insert(LookupMap::value_type(text, text));
-		else	lookupTable.insert(LookupMap::value_type(text, (*confEntry).second.c_str()));
+		else {//valid value found
+			/*
+			- If Encoding==Latin1 and we have a StringHelper, convert to UTF-8
+			- If StringHelper present and Encoding is UTF-8, use UTF8
+			- If StringHelper not present and Latin1, use Latin1
+			- If StringHelper not present and UTF-8, no idea what to do. Should't happen
+			*/
+/*			if (StringHelper::getSystemStringHelper()) {
+				if (!strcmp(encoding, "UTF-8")) {
+					lookupTable.insert(LookupMap::value_type(text, (*confEntry).second.c_str()));
+				}
+				else { //latin1 expected, convert to UTF-8
+					SWBuf t((*confEntry).second.c_str());
+					t = StringHelper::getSystemStringHelper()->latin2unicode( t );
+					
+					lookupTable.insert(LookupMap::value_type(text, t.c_str()));
+				}
+			}
+			else { //no stringhelper, just insert. Nothing we can do*/
+				lookupTable.insert(LookupMap::value_type(text, (*confEntry).second.c_str()));
+// 			}
+			
+		}
 		entry = lookupTable.find(text);
 	}
 	return (*entry).second.c_str();