diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 9ff7e04..5254c20 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -1563,8 +1563,8 @@ void AppFrame::saveSession(std::string fileName) { *demod->newChild("type") = (*instance_i)->getDemodulatorType(); //TODO: now we can only 7 bit strings properly, so convert back to Ascii... - wxString intermediate((*instance_i)->getDemodulatorUserLabel()); - demod->newChild("user_label")->element()->set(intermediate.ToAscii()); +// wxString intermediate((*instance_i)->getDemodulatorUserLabel()); + demod->newChild("user_label")->element()->set((*instance_i)->getDemodulatorUserLabel()); *demod->newChild("squelch_level") = (*instance_i)->getSquelchLevel(); *demod->newChild("squelch_enabled") = (*instance_i)->isSquelchEnabled() ? 1 : 0; @@ -1703,8 +1703,9 @@ bool AppFrame::loadSession(std::string fileName) { //toString() re-formats strings recognized as numerals, but at least it works for //all kind of data. //TODO: DataTree do not support 16 bit strings, so... - std::string rawStr = demodUserLabel->element()->toString(); - user_label.assign(rawStr.begin(), rawStr.end()); +// std::string rawStr = demodUserLabel->element()->toString(); +// user_label.assign(rawStr.begin(), rawStr.end()); + demodUserLabel->element()->get(user_label); } diff --git a/src/util/DataTree.cpp b/src/util/DataTree.cpp index 4b269a5..e774457 100755 --- a/src/util/DataTree.cpp +++ b/src/util/DataTree.cpp @@ -26,6 +26,9 @@ #include "DataTree.h" #include #include +#include +#include +#include /* DataElement class */ @@ -107,6 +110,16 @@ void DataElement::set(const string &str_in) { memcpy(data_val, str_in.c_str(), data_size); } +void DataElement::set(const wstring &wstr_in) { + data_type = DATA_WSTRING; + + std::wstring_convert > utf8conv; + std::string wstrVal = utf8conv.to_bytes(wstr_in); + + data_init(wstrVal.length() + 1); + memcpy(data_val, wstrVal.c_str(), data_size); +} + void DataElement::set(vector &strvect_in) { vector::iterator i; long vectsize; @@ -274,6 +287,26 @@ void DataElement::get(string &str_in) { } } +void DataElement::get(wstring &wstr_in) { + if (!data_type) + return; + + if (data_type != DATA_WSTRING) + throw(new DataTypeMismatchException("Type mismatch, not a WSTRING")); + + std::wstring_convert > utf8conv; + std::wstring wstrVal = utf8conv.from_bytes((char *)data_val); + + if (!wstr_in.empty()) // flush the string + { + wstr_in.erase(wstr_in.begin(), wstr_in.end()); + } + + if (data_val) { + wstr_in.append(wstrVal); + } +} + void DataElement::get(vector &strvect_in) { size_t ptr; if (!data_type) @@ -540,6 +573,44 @@ std::string trim(std::string& s, const std::string& drop = " ") { return r.erase(0, r.find_first_not_of(drop)); } +string DataTree::wsEncode(const wstring wstr) { + stringstream encStream; + + std::wstring_convert > utf8conv; + std::string byte_str = utf8conv.to_bytes(wstr); + + encStream << std::hex; + + for(auto i = byte_str.begin(); i != byte_str.end(); i++) { + encStream << '%' << setfill('0') << (unsigned int)((unsigned char)(*i)); + } + + return encStream.str(); +} + +wstring DataTree::wsDecode(const string str) { + + std::stringstream decStream; + std::stringstream utf8str; + unsigned int x; + + string decStr = str; + std::replace( decStr.begin(), decStr.end(), '%', ' '); + decStream << trim(decStr); + + string sResult; + wstring wsResult; + + std::wstring_convert> utf8conv; + + while (!decStream.eof()) { + decStream >> std::hex >> x; + utf8str << (unsigned char) x; + } + + return utf8conv.from_bytes(utf8str.str().c_str()); +} + void DataTree::decodeXMLText(DataNode *elem, const char *src_text, DT_FloatingPointPolicy fpp) { int tmp_char; @@ -673,6 +744,8 @@ void DataTree::decodeXMLText(DataNode *elem, const char *src_text, DT_FloatingPo } else { elem->element()->set(tmp_doublevect); } + } else if (in_text.find_first_not_of("0123456789abcdef%") == string::npos) { + elem->element()->set(wsDecode(src_text)); } else { elem->element()->set(src_text); // printf( "Unhandled DataTree XML Field: [%s]", tmp_str.c_str() ); @@ -787,6 +860,7 @@ void DataTree::nodeToXML(DataNode *elem, TiXmlElement *elxml) { element = new TiXmlElement(nodeName.length() ? nodeName.c_str() : "node"); std::string tmp; + std::wstring wtmp; std::stringstream tmp_stream; TiXmlText *text; std::vector tmp_floatvect; @@ -951,7 +1025,18 @@ void DataTree::nodeToXML(DataNode *elem, TiXmlElement *elxml) { element->LinkEndChild(text); } break; - + case DATA_WSTRING: + child->element()->get(wtmp); + tmp = wsEncode(wtmp); + if (nodeName.substr(0, 1) == string("@")) { + elxml->SetAttribute(nodeName.substr(1).c_str(), tmp.c_str()); + delete element; + element = NULL; + } else { + text = new TiXmlText(tmp.c_str()); + element->LinkEndChild(text); + } + break; case DATA_STR_VECTOR: child->element()->get(tmp_stringvect); diff --git a/src/util/DataTree.h b/src/util/DataTree.h index ebb2482..a0bf017 100755 --- a/src/util/DataTree.h +++ b/src/util/DataTree.h @@ -67,7 +67,7 @@ using namespace std; #define DATA_DOUBLE_VECTOR 21 #define DATA_LONGDOUBLE_VECTOR 22 #define DATA_VOID 23 - +#define DATA_WSTRING 24 /* map comparison function */ struct string_less : public std::binary_function @@ -151,6 +151,7 @@ public: void set(const char *data_in); /* strings, stops at NULL, returns as string */ void set(const string &str_in); + void set(const wstring &wstr_in); void set(vector &strvect_in); void set(std::set &strset_in); @@ -180,6 +181,7 @@ public: void get(char **data_in); /* getting a void or string */ void get(string &str_in); + void get(wstring &wstr_in); void get(std::set &strset_in); void get(vector &strvect_in); @@ -330,6 +332,9 @@ class DataTree private: DataNode dn_root; + string wsEncode(const wstring wstr); + wstring wsDecode(const string str); + public: DataTree(const char *name_in); DataTree(); diff --git a/src/util/GLFont.cpp b/src/util/GLFont.cpp index b81fcf3..bfe3857 100644 --- a/src/util/GLFont.cpp +++ b/src/util/GLFont.cpp @@ -341,7 +341,7 @@ void GLFont::loadFont(const std::wstring& fontFile) { lodepng::State state; unsigned error = lodepng::decode(image, imgWidth, imgHeight, raw_image, png_size); - delete raw_image; + delete[] raw_image; png_file.Close(); if (error) {