tahoma2d/toonz/sources/tnzbase/stringtable.cpp

316 lines
8 KiB
C++
Raw Normal View History

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