| Index: src/shared/Dictionary.cpp |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/src/shared/Dictionary.cpp |
| @@ -0,0 +1,90 @@ |
| +#include <fstream> |
| +#include <stdexcept> |
| +#include <Windows.h> |
| + |
| +#include "Dictionary.h" |
| +#include "Utils.h" |
| + |
| +Dictionary* Dictionary::instance = 0; |
| + |
| +const std::wstring baseLocale = L"en"; |
| + |
| +Dictionary::Dictionary(const std::wstring& locale) |
| +{ |
| + std::wstring basePath = GetDllDir() + L"locales\\"; |
| + |
| + // Always load base locale first - that's our fallback |
| + ReadDictionary(basePath, baseLocale); |
| + |
| + // Now try to load by full locale code |
| + if (locale != baseLocale && !ReadDictionary(basePath, locale)) |
|
Felix Dahlke
2013/06/11 12:31:14
It looks like if this or the other ReadDictionary
Wladimir Palant
2013/06/12 13:46:07
Yes, it is intended - even incomplete localization
Felix Dahlke
2013/06/13 18:07:37
Okay, just wasn't sure if it was intended.
|
| + { |
| + // Fall back to short locale name |
| + size_t pos = locale.find(L'-'); |
| + if (pos != std::wstring::npos && locale.compare(0, pos, baseLocale) != 0) |
| + ReadDictionary(basePath, locale.substr(0, pos)); |
| + } |
| +} |
| + |
| +void Dictionary::Create(const std::wstring& locale) |
| +{ |
| + if (!instance) |
| + instance = new Dictionary(locale); |
| +} |
| + |
| +Dictionary* Dictionary::GetInstance() |
| +{ |
| + if (!instance) |
| + throw std::runtime_error("Attempt to access dictionary before creating"); |
| + |
| + return instance; |
| +} |
| + |
| +bool Dictionary::ReadDictionary(const std::wstring& basePath, const std::wstring& locale) |
| +{ |
| + std::ifstream stream(basePath + locale + L".ini"); |
|
Oleksandr
2013/06/18 07:41:09
I think it wouldn't hurt to use "filebuf::sh_read
Wladimir Palant
2013/06/18 08:17:48
Good point even though this is non-standard, will
Wladimir Palant
2013/11/05 11:30:25
After looking into this I am less convinced that t
Eric
2013/11/05 13:56:06
The full constructor is declared thus:
explic
Wladimir Palant
2013/11/06 08:51:46
Not really. If you look at http://msdn.microsoft.c
Eric
2013/11/06 17:49:53
After realizing that I hadn't remembered what was
Felix Dahlke
2013/11/06 23:09:50
This seems a bit like premature optimisation to me
Wladimir Palant
2013/11/07 06:53:57
According to http://msdn.microsoft.com/en-us/libra
|
| + if (stream.fail()) |
| + return false; |
| + |
| + std::string section; |
| + while (!stream.eof()) |
|
Felix Dahlke
2013/06/11 12:31:14
I think the following would suffice, it'd be a bit
Wladimir Palant
2013/06/12 13:46:07
IMHO that will get us into an endless loop - std::
Felix Dahlke
2013/06/13 18:07:37
No, it wouldn't be an endless loop, this is the ca
|
| + { |
| + std::string line; |
| + std::getline(stream, line); |
| + if (stream.fail()) |
| + return false; |
| + |
| + line = ::TrimString(line); |
| + if (line.size() >= 2 && line[0] == '[' && line[line.size() - 1] == ']') |
| + { |
| + // Section header |
| + section = line.substr(1, line.size() - 2); |
| + } |
| + else if (line.size() >= 1 && line[0] == '#') |
|
Felix Dahlke
2013/06/11 12:31:14
This won't allow for comments preceeded by whitesp
Wladimir Palant
2013/06/12 13:46:07
We call TrimLine earlier so whitespace is allowed.
Felix Dahlke
2013/06/13 18:07:37
Hm. One benefit of this is that the translated str
|
| + { |
| + // Comment |
| + continue; |
| + } |
| + else |
| + { |
| + // Value |
| + size_t pos = line.find('='); |
| + if (pos != std::string::npos) |
| + { |
| + std::string key = ::TrimString(line.substr(0, pos)); |
| + std::string value = ::TrimString(line.substr(pos + 1)); |
| + data[KeyType(section, key)] = ToUtf16String(value); |
| + } |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +std::wstring Dictionary::Lookup(const std::string& section, const std::string& key) const |
| +{ |
| + DataType::const_iterator it = data.find(KeyType(section, key)); |
| + if (it == data.end()) |
| + return L"### MISSING STRING [" + ToUtf16String(section) + L", " + ToUtf16String(key) + L"] ###"; |
| + |
| + return it->second; |
| +} |