Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tw/stringtable.h"
Toshihiro Shimizu 890ddd
// #include "tw/message.h"
Toshihiro Shimizu 890ddd
//#include "tfilepath.h"
Toshihiro Shimizu 890ddd
#include "tfilepath_io.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
//#include "texception.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TStringTableImp : public TStringTable
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	bool m_initialized;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	map<string, item=""> m_table;</string,>
Toshihiro Shimizu 890ddd
	std::pair<string, int=""> m_defaultFontNameAndSize;</string,>
Toshihiro Shimizu 890ddd
	string m_defaultMacFontName;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStringTableImp();
Toshihiro Shimizu 890ddd
	~TStringTableImp();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void init();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void load(const TFilePath &);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void loadCoded(const TFilePath &);
Toshihiro Shimizu 890ddd
	void saveCoded(const TFilePath &);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const Item *getItem(string name) const;
Toshihiro Shimizu 890ddd
	std::pair<string, int=""> getDefaultFontNameAndSize() const</string,>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return m_defaultFontNameAndSize;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	string getDefaultMacFontName() const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStringTableImp::TStringTableImp()
Toshihiro Shimizu 890ddd
	: m_initialized(false), m_defaultFontNameAndSize("", 0), m_defaultMacFontName("")
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStringTableImp::~TStringTableImp()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TStringTableImp::init()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_initialized)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_initialized = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath plainFp = TEnv::getConfigDir() + "current.txt";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		load(plainFp);
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string TStringTableImp::getDefaultMacFontName() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_defaultMacFontName;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void writeShort(Tofstream &os, int x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	os.put(x & 0xff);
Toshihiro Shimizu 890ddd
	os.put((x >> 8) & 0xff);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int readShort(Tifstream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	char hi = 0, lo = 0;
Toshihiro Shimizu 890ddd
	is.get(lo);
Toshihiro Shimizu 890ddd
	is.get(hi);
Toshihiro Shimizu 890ddd
	return (unsigned char)hi << 8 | (unsigned char)lo;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void writeString(Tofstream &os, string s)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int len = s.length();
Toshihiro Shimizu 890ddd
	writeShort(os, len);
Toshihiro Shimizu 890ddd
	os.write(s.c_str(), len);
Toshihiro Shimizu 890ddd
	if (len & 0x3) {
Toshihiro Shimizu 890ddd
		os.write("____", 4 - (len & 0x3));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
string readString(Tifstream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int len = readShort(is);
Toshihiro Shimizu 890ddd
	int len2 = len;
Toshihiro Shimizu 890ddd
	if (len2 & 0x3)
Toshihiro Shimizu 890ddd
		len2 += 4 - (len2 & 0x3);
Toshihiro Shimizu 890ddd
	char buffer[1204];
Toshihiro Shimizu 890ddd
	assert(len2 <= (int)(sizeof(buffer)));
Toshihiro Shimizu 890ddd
	is.read(buffer, len2);
Toshihiro Shimizu 890ddd
	return string(buffer, len);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void writeStringW(Tofstream &os, wstring s)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int len = s.length();
Toshihiro Shimizu 890ddd
	writeShort(os, len);
Toshihiro Shimizu 890ddd
	os.write(reinterpret_cast<const *="" char="">(s.c_str()), sizeof(wchar_t) * len);</const>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
wstring readStringW(Tifstream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int len = readShort(is);
Toshihiro Shimizu 890ddd
	wchar_t buffer[1204];
Toshihiro Shimizu 890ddd
	assert(len <= (int)(sizeof(buffer)));
Toshihiro Shimizu 890ddd
	is.read(reinterpret_cast<char *="">(buffer), sizeof(wchar_t) * len);</char>
Toshihiro Shimizu 890ddd
	return wstring(buffer, len);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
class TMagic //singleton
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	string m_magic;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	TMagic()
Toshihiro Shimizu 890ddd
		: m_magic("stab.001")
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	static TMagic *instance()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		static TMagic inst;
Toshihiro Shimizu 890ddd
		;
Toshihiro Shimizu 890ddd
		return &inst;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
const string magic = "stab.001";
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TStringTableImp::loadCoded(const TFilePath &fp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		Tifstream is(fp);
Toshihiro Shimizu 890ddd
		char buffer[1024];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
		is.read(buffer, TMagic::instance()->m_magic.length());
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		is.read(buffer, magic.length());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_defaultFontNameAndSize.first = readString(is);
Toshihiro Shimizu 890ddd
		m_defaultFontNameAndSize.second = readShort(is);
Toshihiro Shimizu 890ddd
		int count = readShort(is);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < count; i++) {
Toshihiro Shimizu 890ddd
			int m = readShort(is);
Toshihiro Shimizu 890ddd
			assert(1 <= m && m <= 3);
Toshihiro Shimizu 890ddd
			string id = readString(is);
Toshihiro Shimizu 890ddd
			Item &item = m_table[id];
Toshihiro Shimizu 890ddd
			item.m_name = readStringW(is);
Toshihiro Shimizu 890ddd
			if (m >= 2) {
Toshihiro Shimizu 890ddd
				item.m_help = readStringW(is);
Toshihiro Shimizu 890ddd
				if (m == 3)
Toshihiro Shimizu 890ddd
					item.m_tip = readStringW(is);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		int check = readShort(is);
Toshihiro Shimizu 890ddd
		assert(check == 12345);
Toshihiro Shimizu 890ddd
		//if(check != 12345)
Toshihiro Shimizu 890ddd
		//  throw;
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		// TMessage::error("Error reading StringTable file: ", fp);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void TStringTableImp::saveCoded(const TFilePath &fp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  try {
Toshihiro Shimizu 890ddd
    Tofstream os(fp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef MACOSX    
Toshihiro Shimizu 890ddd
    os.write(TMagic::instance()->m_magic.c_str(), TMagic::instance()->m_magic.length());
Toshihiro Shimizu 890ddd
 #else
Toshihiro Shimizu 890ddd
    os.write(magic.c_str(), magic.length());
Toshihiro Shimizu 890ddd
 #endif
Toshihiro Shimizu 890ddd
    writeString(os, m_defaultFontNameAndSize.first);
Toshihiro Shimizu 890ddd
    writeShort(os, m_defaultFontNameAndSize.second);
Toshihiro Shimizu 890ddd
    writeShort(os, m_table.size());
Toshihiro Shimizu 890ddd
    for(std::map<string, item="">::iterator it = m_table.begin();</string,>
Toshihiro Shimizu 890ddd
        it != m_table.end(); ++it)
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
       Item &item = it->second;
Toshihiro Shimizu 890ddd
       int m = 1;
Toshihiro Shimizu 890ddd
       if(item.m_tip != L"") m = 3;
Toshihiro Shimizu 890ddd
       else if(item.m_help != L"") m = 2;
Toshihiro Shimizu 890ddd
       writeShort(os, m);
Toshihiro Shimizu 890ddd
       writeString(os, it->first);
Toshihiro Shimizu 890ddd
       writeStringW(os, item.m_name);
Toshihiro Shimizu 890ddd
       if(m>=2)
Toshihiro Shimizu 890ddd
         {
Toshihiro Shimizu 890ddd
          writeStringW(os, item.m_help);
Toshihiro Shimizu 890ddd
          if(m==3) 
Toshihiro Shimizu 890ddd
            writeStringW(os, item.m_tip);          
Toshihiro Shimizu 890ddd
         }
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
    writeShort(os, 12345);
Toshihiro Shimizu 890ddd
  } catch(...) {
Toshihiro Shimizu 890ddd
    TMessage::error("Unable to save StringTable file: ", fp);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TStringTableImp::load(const TFilePath &fp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!TFileStatus(fp).doesExist())
Toshihiro Shimizu 890ddd
		throw TException("file not found");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TIStream is(fp);
Toshihiro Shimizu 890ddd
	if (!is)
Toshihiro Shimizu 890ddd
		throw TException("can't read string table ");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string tagName;
Toshihiro Shimizu 890ddd
	if (!is.matchTag(tagName) || tagName != "stringtable")
Toshihiro Shimizu 890ddd
		throw TException("not a string table file");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (!is.matchEndTag()) {
Toshihiro Shimizu 890ddd
		if (!is.matchTag(tagName))
Toshihiro Shimizu 890ddd
			throw TException("expected tag");
Toshihiro Shimizu 890ddd
		if (tagName == "item") {
Toshihiro Shimizu 890ddd
			string id, name, help, tip;
Toshihiro Shimizu 890ddd
			is >> id >> name;
Toshihiro Shimizu 890ddd
			if (!is.matchEndTag()) {
Toshihiro Shimizu 890ddd
				is >> help;
Toshihiro Shimizu 890ddd
				if (!is.matchEndTag()) {
Toshihiro Shimizu 890ddd
					is >> tip;
Toshihiro Shimizu 890ddd
					if (!is.matchEndTag())
Toshihiro Shimizu 890ddd
						throw TException("Expected end tag");
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			Item &item = m_table[id];
Toshihiro Shimizu 890ddd
			item.m_name = toWideString(name);
Toshihiro Shimizu 890ddd
			item.m_help = toWideString(help);
Toshihiro Shimizu 890ddd
			item.m_tip = toWideString(tip);
Toshihiro Shimizu 890ddd
		} else if (tagName == "defaultFont") {
Toshihiro Shimizu 890ddd
			string fontName;
Toshihiro Shimizu 890ddd
			int fontSize = 0;
Toshihiro Shimizu 890ddd
			is >> fontName >> fontSize;
Toshihiro Shimizu 890ddd
			if (!is.matchEndTag())
Toshihiro Shimizu 890ddd
				throw TException("Expected end tag");
Toshihiro Shimizu 890ddd
			m_defaultFontNameAndSize = std::make_pair(fontName, fontSize);
Toshihiro Shimizu 890ddd
		} else if (tagName == "defaultMacFont") {
Toshihiro Shimizu 890ddd
			string macFontName;
Toshihiro Shimizu 890ddd
			is >> macFontName;
Toshihiro Shimizu 890ddd
			if (!is.matchEndTag())
Toshihiro Shimizu 890ddd
				throw TException("Expected end tag");
Toshihiro Shimizu 890ddd
			m_defaultMacFontName = macFontName;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			throw TException("unexpected tag /" + tagName + "/");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//m_valid =true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TStringTable::Item *TStringTableImp::getItem(string name) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::map<string, item="">::const_iterator it;</string,>
Toshihiro Shimizu 890ddd
	it = m_table.find(name);
Toshihiro Shimizu 890ddd
	if (it == m_table.end())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return &(it->second);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStringTable::TStringTable()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStringTable::~TStringTable()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
wstring TStringTable::translate(string name)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const TStringTable::Item *item = instance()->getItem(name);
Toshihiro Shimizu 890ddd
	if (item)
Toshihiro Shimizu 890ddd
		return item->m_name;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return toWideString(name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TStringTable *TStringTable::instance()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// may hurt MacOsX
Toshihiro Shimizu 890ddd
	static TStringTableImp *instance = 0;
Toshihiro Shimizu 890ddd
	if (!instance)
Toshihiro Shimizu 890ddd
		instance = new TStringTableImp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	instance->init();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return instance;
Toshihiro Shimizu 890ddd
}