tinyxml2 supports wide char

minor fixes for basic_string
This commit is contained in:
Nomango 2019-08-04 16:18:35 +08:00 committed by Nomango
parent cefabe71ff
commit dfb9ba4a33
4 changed files with 560 additions and 533 deletions

View File

@ -43,8 +43,11 @@ namespace kiwano
namespace kiwano
{
//
// basic_string
// Lightweight std::wstring<>-like class
// basic_string<>
// Lightweight std::basic_string<>-like class
// When using basic_string<> with a c-style string (char* or wchar_t*), constructor and operator=() just hold
// a pointer to the character array but don't copy its content, considering performance issues.
// Use assign() and basic_string<>::cstr() to work fine with c-style strings.
//
template <typename _CharTy>
class basic_string
@ -174,7 +177,7 @@ namespace kiwano
basic_string& assign(size_type count, const char_type ch);
basic_string& assign(const char_type* cstr, size_type count);
inline basic_string& assign(const char_type* cstr, bool const_str = true) { basic_string(cstr, const_str).swap(*this); return *this; }
inline basic_string& assign(const char_type* cstr) { basic_string(cstr, false).swap(*this); return *this; }
inline basic_string& assign(basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; }
inline basic_string& assign(std::basic_string<char_type> const& rhs) { basic_string{ rhs }.swap(*this); return *this; }
basic_string& assign(basic_string const& rhs, size_type pos, size_type count = npos);
@ -218,6 +221,8 @@ namespace kiwano
template <typename ..._Args>
static basic_string format(const char_type* fmt, _Args&&... args);
static inline basic_string cstr(const char_type* cstr) { return basic_string(cstr, false); }
public:
inline iterator begin() { check_operability(); return iterator(str_); }
inline const_iterator begin() const { return const_iterator(const_str_); }
@ -237,7 +242,7 @@ namespace kiwano
inline const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty string"); return const_str_[size_ - 1]; }
public:
inline char_type operator[](size_type off) const { if(off >= size_) throw std::out_of_range("string subscript out of range"); return const_str_[off]; }
inline char_type operator[](size_type off) const { if (off >= size_) throw std::out_of_range("string subscript out of range"); return const_str_[off]; }
inline char_type& operator[](size_type off) { if (off >= size_) throw std::out_of_range("string subscript out of range"); check_operability(); return str_[off]; }
public:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ namespace kiwano
};
bool LoadImagesFromData(ResLoader* loader, GlobalData* gdata, const String* id, const String* type,
const String* file, const Array<String>* files, int rows, int cols)
const String* file, const Array<const wchar_t*>* files, int rows, int cols)
{
if (!gdata || !id) return false;
@ -104,11 +104,11 @@ namespace kiwano
if (image.count(L"files"))
{
Array<String> files;
Array<const wchar_t*> files;
files.reserve(image[L"files"].size());
for (const auto& file : image[L"files"])
{
files.push_back(file.as_string());
files.push_back(file.as_string().c_str());
}
if (!LoadImagesFromData(loader, &global_data, id, type, file, &files, rows, cols))
return false;
@ -126,32 +126,32 @@ namespace kiwano
bool LoadXmlData(ResLoader* loader, tinyxml2::XMLElement* elem)
{
GlobalData global_data;
if (auto path = elem->FirstChildElement("path"))
if (auto path = elem->FirstChildElement(L"path"))
{
global_data.path = string_to_wide(path->GetText());
global_data.path = path->GetText();
}
if (auto images = elem->FirstChildElement("images"))
if (auto images = elem->FirstChildElement(L"images"))
{
for (auto image = images->FirstChildElement(); image; image = image->NextSiblingElement())
{
String id, type, file;
int rows = 0, cols = 0;
if (auto attr = image->Attribute("id")) id = string_to_wide(attr);
if (auto attr = image->Attribute("type")) type = string_to_wide(attr);
if (auto attr = image->Attribute("file")) file = string_to_wide(attr);
if (auto attr = image->IntAttribute("rows")) rows = attr;
if (auto attr = image->IntAttribute("cols")) cols = attr;
if (auto attr = image->Attribute(L"id")) id.assign(attr); // assign() copies attr content
if (auto attr = image->Attribute(L"type")) type = attr; // operator=() just holds attr pointer
if (auto attr = image->Attribute(L"file")) file = attr;
if (auto attr = image->IntAttribute(L"rows")) rows = attr;
if (auto attr = image->IntAttribute(L"cols")) cols = attr;
if (file.empty() && !image->NoChildren())
{
Array<String> files_arr;
Array<const wchar_t*> files_arr;
for (auto file = image->FirstChildElement(); file; file = file->NextSiblingElement())
{
if (auto path = file->Attribute("path"))
if (auto path = file->Attribute(L"path"))
{
files_arr.push_back(string_to_wide(path));
files_arr.push_back(path);
}
}
if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, &files_arr, rows, cols))
@ -237,12 +237,30 @@ namespace kiwano
bool ResLoader::LoadFromXmlFile(String const& file_path)
{
tinyxml2::XMLDocument doc;
if (tinyxml2::XML_SUCCESS != doc.LoadFile(kiwano::wide_to_string(file_path).c_str()))
std::wifstream ifs;
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
KGE_WARNING_LOG(L"ResLoader::LoadFromXmlFile failed: %s",
string_to_wide(tinyxml2::XMLDocument::ErrorIDToName(doc.ErrorID())).c_str());
ifs.open(file_path.c_str());
std::wstringstream ss;
ss << ifs.rdbuf();
if (tinyxml2::XML_SUCCESS != doc.Parse(ss.str().c_str()))
{
KGE_WARNING_LOG(L"ResLoader::LoadFromXmlFile failed: %s (%s)",
tinyxml2::XMLDocument::ErrorIDToName(doc.ErrorID()), doc.ErrorStr());
return false;
}
}
catch (std::wifstream::failure& e)
{
KGE_WARNING_LOG(L"ResLoader::LoadFromXmlFile failed: Cannot open file. (%s)", string_to_wide(e.what()).c_str());
return false;
}
return LoadFromXml(&doc);
}
@ -252,21 +270,19 @@ namespace kiwano
{
try
{
auto root = doc->FirstChildElement("resources");
KGE_ASSERT(root);
if (root)
if (auto root = doc->FirstChildElement(L"resources"))
{
kiwano::string version = root->FirstChildElement("version")->GetText();
kiwano::wstring version;
if (auto ver = root->FirstChildElement(L"version")) version = ver->GetText();
auto load = load_xml_funcs.find(string_to_wide(version));
auto load = load_xml_funcs.find(version);
if (load != load_xml_funcs.end())
{
load->second(this, root);
return load->second(this, root);
}
else if (version.empty())
{
load_xml_funcs[L"latest"](this, root);
return load_xml_funcs[L"latest"](this, root);
}
else
{