aboutsummaryrefslogtreecommitdiff
path: root/Src/omBrowser/xmlResponseParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/omBrowser/xmlResponseParser.cpp')
-rw-r--r--Src/omBrowser/xmlResponseParser.cpp207
1 files changed, 207 insertions, 0 deletions
diff --git a/Src/omBrowser/xmlResponseParser.cpp b/Src/omBrowser/xmlResponseParser.cpp
new file mode 100644
index 00000000..fb3065ae
--- /dev/null
+++ b/Src/omBrowser/xmlResponseParser.cpp
@@ -0,0 +1,207 @@
+#include "main.h"
+#include "./xmlResponseParser.h"
+#include "./ifc_omservicehost.h"
+#include "./ifc_omservice.h"
+#include "./ifc_omstoragehandlerenum.h"
+#include "./ifc_omstorageext.h"
+#include "./ifc_omfilestorage.h"
+
+
+#include "../xml/obj_xml.h"
+
+#include <shlwapi.h>
+#include <strsafe.h>
+
+
+XmlResponseParser::XmlResponseParser()
+ : reader(NULL), code((UINT)-1), text(NULL), host(NULL)
+{
+}
+
+XmlResponseParser::~XmlResponseParser()
+{
+ if (NULL != reader)
+ {
+ reader->Release();
+ reader = NULL;
+ }
+
+ if (NULL != host)
+ host->Release();
+
+ while(false == deque.empty())
+ {
+ deque.front()->Release();
+ deque.pop_front();
+ }
+}
+
+HRESULT XmlResponseParser::Initialize(obj_xml *xml, ifc_omservicehost *serviceHost)
+{
+ if (NULL == xml) return E_INVALIDARG;
+
+ if (NULL != reader)
+ {
+ if (reader == xml)
+ return S_FALSE;
+
+ reader->Release();
+ }
+
+ reader = xml;
+ reader->AddRef();
+
+ reader->xmlreader_registerCallback(L"response\fstatusCode", this);
+ reader->xmlreader_registerCallback(L"response\fstatusText", this);
+ reader->xmlreader_registerCallback(L"response\fdata\fservices\fservice", this);
+
+ if (NULL != host)
+ host->Release();
+
+ ifc_omstoragehandlerenum *handlerEnum(NULL);
+
+ host = serviceHost;
+ if (NULL != host)
+ {
+ host->AddRef();
+
+ ifc_omstorageext *storageExt;
+ if (SUCCEEDED(host->QueryInterface(IFC_OmStorageExt, (void**)&storageExt)))
+ {
+ if (FAILED(storageExt->Enumerate(&SUID_OmStorageXml, &handlerEnum)))
+ handlerEnum = NULL;
+ storageExt->Release();
+ }
+ }
+
+ parser.RegisterHandlers(handlerEnum);
+ if (NULL != handlerEnum)
+ {
+ handlerEnum->Release();
+ }
+
+ Reset();
+
+ return S_OK;
+}
+HRESULT XmlResponseParser::Finish()
+{
+ if (NULL != reader)
+ {
+ reader->Release();
+ reader = NULL;
+ }
+ return S_OK;
+}
+HRESULT XmlResponseParser::Reset()
+{
+ code = (UINT)-1;
+
+ if (NULL != text)
+ {
+ Plugin_FreeString(text);
+ text = NULL;
+ }
+
+ string.Clear();
+
+ return S_OK;
+}
+
+HRESULT XmlResponseParser::GetCode(UINT *value)
+{
+ if (NULL == value) return E_POINTER;
+ if ((UINT)-1 == code)
+ {
+ *value = 0;
+ return E_PENDING;
+ }
+
+ *value = code;
+ return S_OK;
+}
+
+HRESULT XmlResponseParser::GetText(LPWSTR pszBuffer, UINT cchBufferMax)
+{
+ if (NULL == pszBuffer) return E_POINTER;
+ if (NULL == text)
+ {
+ pszBuffer[0] = L'\0';
+ return E_PENDING;
+ }
+
+ return StringCchCopy(pszBuffer, cchBufferMax, text);
+}
+
+HRESULT XmlResponseParser::PeekService(ifc_omservice **service)
+{
+ if (NULL == service) return E_POINTER;
+ if (0 == deque.size()) return S_FALSE;
+
+ *service = deque.back();
+ deque.pop_back();
+ return S_OK;
+}
+
+void XmlResponseParser::OnStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
+{
+ if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, xmltag, -1, L"service", -1))
+ {
+ parser.Initialize(reader, xmlpath, host);
+ }
+ else
+ {
+ string.Clear();
+ }
+}
+
+void XmlResponseParser::OnEndElement(const wchar_t *xmlpath, const wchar_t *xmltag)
+{
+ if (S_OK == parser.GetActive())
+ {
+ ifc_omservice *service;
+ if (SUCCEEDED(parser.Finish(NULL, &service)) && NULL != service)
+ {
+ deque.push_front(service);
+ }
+ }
+ else
+ {
+ if ((UINT)-1 == code && CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, xmltag, -1, L"statusCode", -1))
+ {
+ LPCWSTR sCode = string.Get();
+ if (NULL == sCode || L'\0' == *sCode ||
+ FALSE == StrToIntEx(sCode, STIF_SUPPORT_HEX, (INT*)&code))
+ {
+ code = (UINT)-1;
+ }
+ }
+ else if (NULL == text && CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, xmltag, -1, L"statusText", -1))
+ {
+ text = Plugin_CopyString(string.Get());
+ }
+
+
+ }
+}
+
+void XmlResponseParser::OnCharData(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *value)
+{
+ if (S_OK != parser.GetActive())
+ {
+ string.Append(value);
+ }
+}
+
+void XmlResponseParser::OnError(int linenum, int errcode, const wchar_t *errstr)
+{
+ string.Clear();
+}
+
+#define CBCLASS XmlResponseParser
+START_DISPATCH;
+VCB(ONSTARTELEMENT, OnStartElement)
+VCB(ONENDELEMENT, OnEndElement)
+VCB(ONCHARDATA, OnCharData)
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file