o2on svn commit
o2on-****@lists*****
2009年 2月 4日 (水) 01:54:13 JST
Revision: 136 http://svn.sourceforge.jp/view?root=o2on&view=rev&rev=136 Author: electrolysis Date: 2009-02-04 01:54:13 +0900 (Wed, 04 Feb 2009) Log Message: ----------- SAX周辺の改良 詳細:単一要素内でContentHandler::characters()が複数回呼ばれる可能性を考慮し、予期せぬデータロスを防ぐ Modified Paths: -------------- trunk/o2on/src.o2on/O2Boards.cpp trunk/o2on/src.o2on/O2Boards.h trunk/o2on/src.o2on/O2IMDB.cpp trunk/o2on/src.o2on/O2IMDB.h trunk/o2on/src.o2on/O2IPFilter.cpp trunk/o2on/src.o2on/O2IPFilter.h trunk/o2on/src.o2on/O2KeyDB.cpp trunk/o2on/src.o2on/O2KeyDB.h trunk/o2on/src.o2on/O2NodeDB.cpp trunk/o2on/src.o2on/O2NodeDB.h trunk/o2on/src.o2on/O2PerformanceCounter.h trunk/o2on/src.o2on/O2Profile.cpp trunk/o2on/src.o2on/O2Profile.h trunk/o2on/src.o2on/upnp_description.h Modified: trunk/o2on/src.o2on/O2Boards.cpp =================================================================== --- trunk/o2on/src.o2on/O2Boards.cpp 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2Boards.cpp 2009-02-03 16:54:13 UTC (rev 136) @@ -906,6 +906,17 @@ , const XMLCh* const localname , const XMLCh* const qname) { + switch (parse_elm) { + case 1: + parse_name = buf; + break; + case 2: + parse_enable = buf[0] == L'0' ? false : true; + break; + } + + buf = L""; + parse_elm = 0; if (MATCHLNAME(L"board")) { ExLock.Lock(); @@ -927,12 +938,6 @@ characters(const XMLCh* const chars , const unsigned int length) { - switch (parse_elm) { - case 1: - parse_name.assign(chars, length); - break; - case 2: - parse_enable = chars[0] == L'0' ? false : true; - break; - } + if (parse_elm != 0) + buf.append(chars, length); } Modified: trunk/o2on/src.o2on/O2Boards.h =================================================================== --- trunk/o2on/src.o2on/O2Boards.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2Boards.h 2009-02-03 16:54:13 UTC (rev 136) @@ -89,6 +89,7 @@ uint parse_elm; wstring parse_name; bool parse_enable; + wstring buf; wchar_t *host2domain(const wchar_t *host); Modified: trunk/o2on/src.o2on/O2IMDB.cpp =================================================================== --- trunk/o2on/src.o2on/O2IMDB.cpp 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2IMDB.cpp 2009-02-03 16:54:13 UTC (rev 136) @@ -725,59 +725,64 @@ , const XMLCh* const localname , const XMLCh* const qname) { - CurElm = IM_XMLELM_NONE; - if (!CurIM || !MATCHLNAME(L"message")) - return; - - IMDB->AddMessage(*CurIM); -} - - - - -void -O2IMDB_SAX2Handler:: -characters(const XMLCh* const chars, const unsigned int length) -{ - if (!CurIM) - return; - switch (CurElm) { case IM_XMLELM_IP: - CurIM->ip = e2ip(chars, length); + CurIM->ip = e2ip(buf.c_str(), buf.size()); break; case IM_XMLELM_PORT: - CurIM->port = (ushort)wcstoul(chars, NULL, 10); + CurIM->port = (ushort)wcstoul(buf.c_str(), NULL, 10); break; case IM_XMLELM_ID: - CurIM->id.assign(chars, length); + CurIM->id.assign(buf.c_str(), buf.size()); break; case IM_XMLELM_PUBKEY: - CurIM->pubkey.assign(chars, length); + CurIM->pubkey.assign(buf.c_str(), buf.size()); break; case IM_XMLELM_NAME: - CurIM->name.assign(chars, length); + CurIM->name = buf; break; case IM_XMLELM_DATE: - CurIM->date = datetime2time_t(chars, length); + CurIM->date = datetime2time_t(buf.c_str(), buf.size()); break; case IM_XMLELM_MSG: - CurIM->msg.assign(chars, length); + CurIM->msg = buf; break; case IM_XMLELM_KEY: - CurIM->key.assign(chars, length); + CurIM->key.assign(buf.c_str(), buf.size()); break; case IM_XMLELM_MINE: - CurIM->mine = chars[0] == L'0' ? false : true; + CurIM->mine = buf[0] == L'0' ? false : true; break; case IM_XMLELM_PATH: { hashT id; - id.assign(chars, length); + id.assign(buf.c_str(), buf.size()); CurIM->paths.push_back(id); while (CurIM->paths.size() > O2_BROADCAST_PATH_LIMIT) CurIM->paths.pop_front(); } break; } + + buf = L""; + + CurElm = IM_XMLELM_NONE; + if (!CurIM || !MATCHLNAME(L"message")) + return; + + IMDB->AddMessage(*CurIM); } + + + + +void +O2IMDB_SAX2Handler:: +characters(const XMLCh* const chars, const unsigned int length) +{ + if (!CurIM) + return; + + if (CurElm != IM_XMLELM_NONE) + buf.append(chars, length); +} Modified: trunk/o2on/src.o2on/O2IMDB.h =================================================================== --- trunk/o2on/src.o2on/O2IMDB.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2IMDB.h 2009-02-03 16:54:13 UTC (rev 136) @@ -157,18 +157,6 @@ size_t ExportToXML(O2IMSelectCondition &cond, string &out); size_t ImportFromXML(const wchar_t *filename, const char *in, uint len); - -public: - void endDocument(void); - void startElement(const XMLCh* const uri - , const XMLCh* const localname - , const XMLCh* const qname - , const Attributes& attrs); - void endElement(const XMLCh* const uri - , const XMLCh* const localname - , const XMLCh* const qname); - void characters(const XMLCh* const chars - , const unsigned int length); }; @@ -185,6 +173,7 @@ O2IMessage *CurIM; uint CurElm; size_t ParseNum; + wstring buf; public: O2IMDB_SAX2Handler(O2Logger *lgr, O2IMDB *imdb); Modified: trunk/o2on/src.o2on/O2IPFilter.cpp =================================================================== --- trunk/o2on/src.o2on/O2IPFilter.cpp 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2IPFilter.cpp 2009-02-03 16:54:13 UTC (rev 136) @@ -592,44 +592,49 @@ , const XMLCh* const localname , const XMLCh* const qname) { - CurElm = IPF_XMLELM_NONE; - - if (!CurRecord || !MATCHLNAME(L"filter")) - return; - if (CurRecord->cond.empty()) - return; - - IPFilter->add(CurRecord->enable, CurRecord->flag, CurRecord->cond.c_str()); -} - - - - -void -O2IPFilter_SAX2Handler:: -characters(const XMLCh* const chars, const unsigned int length) -{ switch (CurElm) { case IPF_XMLELM_DEFAULT: - if (_wcsnicmp(chars, L"allow", 5) == 0) + if (_wcsnicmp(buf.c_str(), L"allow", 5) == 0) IPFilter->setdefault(O2_ALLOW); else IPFilter->setdefault(O2_DENY); break; case IPF_XMLELM_ENABLE: - if (_wcsnicmp(chars, L"true", 4) == 0) + if (_wcsnicmp(buf.c_str(), L"true", 4) == 0) CurRecord->enable = true; else CurRecord->enable = false; break; case IPF_XMLELM_FLAG: - if (_wcsnicmp(chars, L"allow", 5) == 0) + if (_wcsnicmp(buf.c_str(), L"allow", 5) == 0) CurRecord->flag = O2_ALLOW; else CurRecord->flag = O2_DENY; break; case IPF_XMLELM_COND: - CurRecord->cond.assign(chars, length); + CurRecord->cond = buf; break; } + + buf = L""; + + CurElm = IPF_XMLELM_NONE; + + if (!CurRecord || !MATCHLNAME(L"filter")) + return; + if (CurRecord->cond.empty()) + return; + + IPFilter->add(CurRecord->enable, CurRecord->flag, CurRecord->cond.c_str()); } + + + + +void +O2IPFilter_SAX2Handler:: +characters(const XMLCh* const chars, const unsigned int length) +{ + if (CurElm != IPF_XMLELM_NONE) + buf.append(chars, length); +} Modified: trunk/o2on/src.o2on/O2IPFilter.h =================================================================== --- trunk/o2on/src.o2on/O2IPFilter.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2IPFilter.h 2009-02-03 16:54:13 UTC (rev 136) @@ -115,6 +115,7 @@ O2IPFilterRecord *CurRecord; uint CurElm; uint64 ParseNum; + wstring buf; public: O2IPFilter_SAX2Handler(const wchar_t *nm, O2Logger *lgr, O2IPFilter *ipf); Modified: trunk/o2on/src.o2on/O2KeyDB.cpp =================================================================== --- trunk/o2on/src.o2on/O2KeyDB.cpp 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2KeyDB.cpp 2009-02-03 16:54:13 UTC (rev 136) @@ -831,53 +831,58 @@ , const XMLCh* const localname , const XMLCh* const qname) { - CurElm = KEY_XMLELM_NONE; - if (!CurKey || !MATCHLNAME(L"key")) - return; - - KeyDB->AddKey(*CurKey); - ParseNum++; -} - -void -O2KeyDB_SAX2Handler:: -characters(const XMLCh* const chars, const unsigned int length) -{ - if (CurKey == NULL) - return; - switch (CurElm) { case KEY_XMLELM_HASH: - CurKey->hash.assign(chars, length); + CurKey->hash.assign(buf.c_str(), buf.size()); break; case KEY_XMLELM_NODEID: - CurKey->nodeid.assign(chars, length); + CurKey->nodeid.assign(buf.c_str(), buf.size()); break; case KEY_XMLELM_IP: - CurKey->ip = e2ip(chars, length); + CurKey->ip = e2ip(buf.c_str(), buf.size()); break; case KEY_XMLELM_PORT: - CurKey->port = (ushort)wcstoul(chars, NULL, 10); + CurKey->port = (ushort)wcstoul(buf.c_str(), NULL, 10); break; case KEY_XMLELM_SIZE: - CurKey->size = wcstoul(chars, NULL, 10); + CurKey->size = wcstoul(buf.c_str(), NULL, 10); break; case KEY_XMLELM_URL: - CurKey->url.assign(chars, length); + CurKey->url = buf; break; case KEY_XMLELM_TITLE: - if (length <= O2_MAX_KEY_TITLE_LEN) - CurKey->title.assign(chars, length); + if (buf.size() <= O2_MAX_KEY_TITLE_LEN) + CurKey->title = buf; break; case KEY_XMLELM_NOTE: - if (length <= O2_MAX_KEY_NOTE_LEN) - CurKey->note.assign(chars, length); + if (buf.size() <= O2_MAX_KEY_NOTE_LEN) + CurKey->note = buf; break; case KEY_XMLELM_DATE: - CurKey->date = datetime2time_t(chars, length); + CurKey->date = datetime2time_t(buf.c_str(), buf.size()); break; case KEY_XMLELM_ENABLE: - CurKey->enable = chars[0] == L'e' ? true : false; + CurKey->enable = buf[0] == L'e' ? true : false; break; } + + buf = L""; + + CurElm = KEY_XMLELM_NONE; + if (!CurKey || !MATCHLNAME(L"key")) + return; + + KeyDB->AddKey(*CurKey); + ParseNum++; } + +void +O2KeyDB_SAX2Handler:: +characters(const XMLCh* const chars, const unsigned int length) +{ + if (CurKey == NULL) + return; + + if (CurElm != KEY_XMLELM_NONE) + buf.append(chars, length); +} Modified: trunk/o2on/src.o2on/O2KeyDB.h =================================================================== --- trunk/o2on/src.o2on/O2KeyDB.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2KeyDB.h 2009-02-03 16:54:13 UTC (rev 136) @@ -150,6 +150,7 @@ O2Key *CurKey; uint CurElm; uint64 ParseNum; + wstring buf; public: O2KeyDB_SAX2Handler(O2Logger *lgr, O2KeyDB *kdb); Modified: trunk/o2on/src.o2on/O2NodeDB.cpp =================================================================== --- trunk/o2on/src.o2on/O2NodeDB.cpp 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2NodeDB.cpp 2009-02-03 16:54:13 UTC (rev 136) @@ -585,47 +585,52 @@ , const XMLCh* const localname , const XMLCh* const qname) { - CurElm = NODE_XMLELM_NONE; - if (!CurNode || !MATCHLNAME(L"node")) - return; - - if (ReceiveList) - ReceiveList->push_back(*CurNode); - else - NodeDB->touch(*CurNode); - ParseNum++; -} - -void -O2NodeDB_SAX2Handler:: -characters(const XMLCh* const chars, const unsigned int length) -{ string tmpstr; - if (CurNode == NULL && CurElm != NODE_XMLELM_STR) - return; - switch (CurElm) { case NODE_XMLELM_ID: - CurNode->id.assign(chars, length); + CurNode->id.assign(buf.c_str(), buf.size()); break; case NODE_XMLELM_IP: - CurNode->ip = e2ip(chars, length); + CurNode->ip = e2ip(buf.c_str(), buf.size()); break; case NODE_XMLELM_PORT: - CurNode->port = (ushort)wcstoul(chars, NULL, 10); + CurNode->port = (ushort)wcstoul(buf.c_str(), NULL, 10); break; case NODE_XMLELM_NAME: - if (length <= O2_MAX_NAME_LEN) - CurNode->name.assign(chars, length); + if (buf.size() <= O2_MAX_NAME_LEN) + CurNode->name = buf; break; case NODE_XMLELM_PUBKEY: - CurNode->pubkey.assign(chars, length); + CurNode->pubkey.assign(buf.c_str(), buf.size()); break; case NODE_XMLELM_STR: - unicode2ascii(chars, length, tmpstr); + unicode2ascii(buf, tmpstr); if (NodeDB->AddEncodedNode(tmpstr.c_str(), tmpstr.size())) ParseNum++; break; } + + buf = L""; + + CurElm = NODE_XMLELM_NONE; + if (!CurNode || !MATCHLNAME(L"node")) + return; + + if (ReceiveList) + ReceiveList->push_back(*CurNode); + else + NodeDB->touch(*CurNode); + ParseNum++; } + +void +O2NodeDB_SAX2Handler:: +characters(const XMLCh* const chars, const unsigned int length) +{ + if (CurNode == NULL && CurElm != NODE_XMLELM_STR) + return; + + if (CurElm != NODE_XMLELM_NONE) + buf.append(chars, length); +} Modified: trunk/o2on/src.o2on/O2NodeDB.h =================================================================== --- trunk/o2on/src.o2on/O2NodeDB.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2NodeDB.h 2009-02-03 16:54:13 UTC (rev 136) @@ -117,6 +117,7 @@ O2Node *CurNode; uint CurElm; size_t ParseNum; + wstring buf; public: O2NodeDB_SAX2Handler(O2Logger *lgr, O2NodeDB *ndb, O2NodeDB::NodeListT *rlist); Modified: trunk/o2on/src.o2on/O2PerformanceCounter.h =================================================================== --- trunk/o2on/src.o2on/O2PerformanceCounter.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2PerformanceCounter.h 2009-02-03 16:54:13 UTC (rev 136) @@ -45,6 +45,7 @@ uint64 Total_Send; uint64 Total_Recv; uint64 *pval; + wstring buf; public: O2PerformanceCounter(const wchar_t *name @@ -262,6 +263,9 @@ , const XMLCh* const localname , const XMLCh* const qname) { + if (pval) + *pval = _wcstoui64(buf.c_str(), NULL, 10); + buf = L""; pval = NULL; } void characters(const XMLCh* const chars @@ -269,6 +273,6 @@ { if (!pval) return; - *pval = _wcstoui64(chars, NULL, 10); + buf.append(chars, length); } }; Modified: trunk/o2on/src.o2on/O2Profile.cpp =================================================================== --- trunk/o2on/src.o2on/O2Profile.cpp 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2Profile.cpp 2009-02-03 16:54:13 UTC (rev 136) @@ -1670,104 +1670,100 @@ , const XMLCh* const localname , const XMLCh* const qname) { - CurElm = PROF_XMLELM_NONE; - if (!MATCHLNAME(L"profile")) - return; - - if (Profile->PrivKey.size() != RSA_PRIVKEY_SIZE - || Profile->PubKey.size() != RSA_PUBKEY_SIZE) { - Profile->SetRSAKey(NULL, 0, NULL, 0); - } -} - - - - -void -O2Profile_SAX2Handler:: -characters(const XMLCh* const chars, const unsigned int length) -{ - wstring str; - switch (CurElm) { case PROF_XMLELM_ID: - Profile->ID.assign(chars, length); + Profile->ID.assign(buf.c_str(), buf.size()); break; case PROF_XMLELM_PRIVKEY: - Profile->PrivKey.assign(chars, length); + Profile->PrivKey.assign(buf.c_str(), buf.size()); break; case PROF_XMLELM_PUBKEY: - Profile->PubKey.assign(chars, length); + Profile->PubKey.assign(buf.c_str(), buf.size()); break; case PROF_XMLELM_IP: - Profile->IP = e2ip(chars, length); + Profile->IP = e2ip(buf.c_str(), buf.size()); break; case PROF_XMLELM_P2PPORT: - Profile->P2PPort = (ushort)wcstoul(chars, NULL, 10); + Profile->P2PPort = (ushort)wcstoul(buf.c_str(), NULL, 10); break; case PROF_XMLELM_PROXYPORT: - Profile->ProxyPort = (ushort)wcstoul(chars, NULL, 10); + Profile->ProxyPort = (ushort)wcstoul(buf.c_str(), NULL, 10); break; case PROF_XMLELM_ADMINPORT: - Profile->AdminPort = (ushort)wcstoul(chars, NULL, 10); + Profile->AdminPort = (ushort)wcstoul(buf.c_str(), NULL, 10); break; case PROF_XMLELM_NAME: - if (length <= O2_MAX_NAME_LEN) { - str.assign(chars, length); - Profile->SetNodeName(str.c_str()); + if (buf.size() <= O2_MAX_NAME_LEN) { + Profile->SetNodeName(buf.c_str()); } break; case PROF_XMLELM_COMMENT: - if (length <= O2_MAX_COMMENT_LEN) { - for (size_t i = 0; i < length; i++) { - if (chars[i] == L'\n') + if (buf.size() <= O2_MAX_COMMENT_LEN) { + for (size_t i = 0; i < buf.size(); i++) { + if (buf[i] == L'\n') Profile->Comment += L"\r\n"; else - Profile->Comment += chars[i]; + Profile->Comment += buf[i]; } } break; case PROF_XMLELM_DBDIR: - str.assign(chars, length); - Profile->SetDBDir(str.c_str()); + Profile->SetDBDir(buf.c_str()); break; case PROF_XMLELM_CACHEROOT: - str.assign(chars, length); - Profile->SetCacheRoot(str.c_str()); + Profile->SetCacheRoot(buf.c_str()); break; case PROF_XMLELM_ADMINROOT: - str.assign(chars, length); - Profile->SetAdminRoot(str.c_str()); + Profile->SetAdminRoot(buf.c_str()); break; case PROF_XMLELM_ADMIN_BROWSER_TYPE: - Profile->AdminBrowserType.assign(chars, length); + Profile->AdminBrowserType = buf; break; case PROF_XMLELM_ADMIN_BROWSER_PATH: - Profile->AdminBrowserPath.assign(chars, length); + Profile->AdminBrowserPath = buf; break; case PROF_XMLELM_UPNP_ADAPTERNAME: - str.assign(chars, length); - unicode2ascii(str, Profile->UPnPAdapterName); + unicode2ascii(buf, Profile->UPnPAdapterName); break; case PROF_XMLELM_UPNP_LOCATION: - str.assign(chars, length); - unicode2ascii(str, Profile->UPnPLocation); + unicode2ascii(buf, Profile->UPnPLocation); break; case PROF_XMLELM_UPNP_SERVICEID: - str.assign(chars, length); - unicode2ascii(str, Profile->UPnPServiceId); + unicode2ascii(buf, Profile->UPnPServiceId); break; case PROF_XMLELM_LIMIT: if (plimit) - *plimit = wcstoul(chars, NULL, 10); + *plimit = wcstoul(buf.c_str(), NULL, 10); break; case PROF_XMLELM_SIZE_T: if (puint64) - *puint64 = _wcstoui64(chars, NULL, 10); + *puint64 = _wcstoui64(buf.c_str(), NULL, 10); break; case PROF_XMLELM_BOOL: - *pbool = chars[0] == '1' ? true : false; + *pbool = buf[0] == '1' ? true : false; break; } + + buf = L""; + + CurElm = PROF_XMLELM_NONE; + if (!MATCHLNAME(L"profile")) + return; + + if (Profile->PrivKey.size() != RSA_PRIVKEY_SIZE + || Profile->PubKey.size() != RSA_PUBKEY_SIZE) { + Profile->SetRSAKey(NULL, 0, NULL, 0); + } } + + + + +void +O2Profile_SAX2Handler:: +characters(const XMLCh* const chars, const unsigned int length) +{ + if (CurElm != PROF_XMLELM_NONE) + buf.append(chars, length); +} Modified: trunk/o2on/src.o2on/O2Profile.h =================================================================== --- trunk/o2on/src.o2on/O2Profile.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/O2Profile.h 2009-02-03 16:54:13 UTC (rev 136) @@ -308,7 +308,7 @@ // -// O2NodeDB_SAX2Handler +// O2Profile_SAX2Handler // class O2Profile_SAX2Handler : public SAX2Handler @@ -320,6 +320,7 @@ uint *plimit; uint64 *puint64; bool *pbool; + wstring buf; public: O2Profile_SAX2Handler(O2Logger *lgr, O2Profile *prof); Modified: trunk/o2on/src.o2on/upnp_description.h =================================================================== --- trunk/o2on/src.o2on/upnp_description.h 2009-01-31 18:42:58 UTC (rev 135) +++ trunk/o2on/src.o2on/upnp_description.h 2009-02-03 16:54:13 UTC (rev 136) @@ -210,6 +210,8 @@ UPnPService *cur_service; std::list<UPnPDevice*> parents; + wstring buf; + inline bool matchlname(const wchar_t *a, const wchar_t *b) { return (_wcsicmp(a, b) == 0 ? true : false); @@ -304,35 +306,16 @@ cur_service = new UPnPService; cur_service->rootObject = object; } + + buf = L""; } void endElement(const XMLCh* const uri , const XMLCh* const localname , const XMLCh* const qname) { - if (matchlname(localname, L"device")) { - if (!parents.empty()) { - parents.back()->deviceList.push_back(*cur_device); - delete cur_device; - cur_device = parents.back(); - parents.pop_back(); - } - } - else if (matchlname(localname, L"service")) { - if (cur_device) { - cur_device->serviceList.push_back(*cur_service); - delete cur_service; - cur_service = NULL; - } - } - - cur_element = L""; - } - - void characters(const XMLCh* const chars, const unsigned int length) - { string str; - unicode2ascii(chars, length, str); + unicode2ascii(buf, str); if (wcsstr(cur_element.c_str(), L"URLBase")) { if (str[str.size()-1] == '/') @@ -380,8 +363,34 @@ else if (matchelement(L"eventSubURL")) cur_service->eventSubURL = str; } + + buf =L""; + + if (matchlname(localname, L"device")) { + if (!parents.empty()) { + parents.back()->deviceList.push_back(*cur_device); + delete cur_device; + cur_device = parents.back(); + parents.pop_back(); + } + } + else if (matchlname(localname, L"service")) { + if (cur_device) { + cur_device->serviceList.push_back(*cur_service); + delete cur_service; + cur_service = NULL; + } + } + + cur_element = L""; } + void characters(const XMLCh* const chars, const unsigned int length) + { + if (!cur_element.empty()) + buf.append(chars, length); + } + void warning(const SAXParseException& e) { if (MessageHandler) { @@ -433,6 +442,8 @@ UPnPAction *cur_action; UPnPArgument *cur_argument; + wstring buf; + inline bool matchlname(const wchar_t *a, const wchar_t *b) { return (_wcsicmp(a, b) == 0 ? true : false); @@ -514,12 +525,32 @@ else if (matchlname(localname, L"argument")) { cur_argument = new UPnPArgument; } + + buf = L""; } void endElement(const XMLCh* const uri , const XMLCh* const localname , const XMLCh* const qname) { + string str; + unicode2ascii(buf, str); + + if (cur_argument) { + if (matchelement(L"name")) + cur_argument->name = str; + else if (matchelement(L"direction")) + cur_argument->direction = str; + else if (matchelement(L"relatedStateVariable")) + cur_argument->relatedStateVariable = str; + } + else if (cur_action) { + if (matchelement(L"name")) + cur_action->name = str; + } + + buf = L""; + if (matchlname(localname, L"action")) { if (cur_action) { service->actionList.push_back(*cur_action); @@ -541,21 +572,8 @@ void characters(const XMLCh* const chars, const unsigned int length) { - string str; - unicode2ascii(chars, length, str); - - if (cur_argument) { - if (matchelement(L"name")) - cur_argument->name = str; - else if (matchelement(L"direction")) - cur_argument->direction = str; - else if (matchelement(L"relatedStateVariable")) - cur_argument->relatedStateVariable = str; - } - else if (cur_action) { - if (matchelement(L"name")) - cur_action->name = str; - } + if (!cur_element.empty()) + buf.append(chars, length); } void warning(const SAXParseException& e) @@ -608,6 +626,8 @@ UPnPAction *cur_action; UPnPArgument *cur_argument; + wstring buf; + public: UPnPSOAPResponseParser(UPnPService *sv, void (*func)(const char *)) : service(sv) @@ -701,9 +721,12 @@ , const XMLCh* const localname , const XMLCh* const qname) { - string name; - unicode2ascii(localname, wcslen(localname), name); + if (cur_argument) { + unicode2ascii(buf, cur_argument->value); + } + buf = L""; + if (wcsncmp(qname, L"m:", 2) == 0) { cur_action = NULL; } @@ -714,11 +737,8 @@ void characters(const XMLCh* const chars, const unsigned int length) { - string str; - unicode2ascii(chars, length, str); - if (cur_argument) { - unicode2ascii(chars, length, cur_argument->value); + buf.append(chars, length); } }