Index: base/xml_utils.cc |
diff --git a/base/xml_utils.cc b/base/xml_utils.cc |
deleted file mode 100644 |
index db7fe97751fe72e6609522032a25f152dbee5387..0000000000000000000000000000000000000000 |
--- a/base/xml_utils.cc |
+++ /dev/null |
@@ -1,874 +0,0 @@ |
-// Copyright 2005-2009 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
-// |
-// xml_utils.cpp |
-// |
-// Utilities for working with XML files via MSXML. |
- |
-#include "omaha/base/xml_utils.h" |
- |
-#include <msxml2.h> |
-#include <atlsafe.h> |
-#include <vector> |
-#include "omaha/base/debug.h" |
-#include "omaha/base/error.h" |
-#include "omaha/base/logging.h" |
-#include "omaha/base/string.h" |
-#include "omaha/base/utils.h" |
- |
-namespace omaha { |
- |
-XMLFQName::XMLFQName() {} |
- |
-XMLFQName::XMLFQName(const TCHAR* u, const TCHAR* b) |
- : uri(u && ::_tcslen(u) ? u : 0), |
- base(b && ::_tcslen(b) ? b : 0) {} |
- |
-XMLFQName::~XMLFQName() {} |
- |
-HRESULT CoCreateSafeDOMDocument(IXMLDOMDocument** my_xmldoc) { |
- ASSERT1(my_xmldoc && !*my_xmldoc); |
- if (!my_xmldoc) { |
- UTIL_LOG(LE, (L"[CoCreateSafeDOMDocument E_INVALIDARG]")); |
- return E_INVALIDARG; |
- } |
- *my_xmldoc = NULL; |
- CComPtr<IXMLDOMDocument> xml_doc; |
- HRESULT hr = xml_doc.CoCreateInstance(__uuidof(DOMDocument2)); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[xml_doc.CoCreateInstance failed][0x%x]"), hr)); |
- return hr; |
- } |
- ASSERT1(xml_doc); |
- hr = xml_doc->put_resolveExternals(VARIANT_FALSE); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[put_resolveExternals failed][0x%x]"), hr)); |
- return hr; |
- } |
- *my_xmldoc = xml_doc.Detach(); |
- return S_OK; |
-} |
- |
-HRESULT LoadXMLFromFile(const TCHAR* xmlfile, |
- bool preserve_whitespace, |
- IXMLDOMDocument** xmldoc) { |
- ASSERT1(xmlfile); |
- ASSERT1(xmldoc); |
- ASSERT1(!*xmldoc); |
- |
- *xmldoc = NULL; |
- CComPtr<IXMLDOMDocument> my_xmldoc; |
- HRESULT hr = CoCreateSafeDOMDocument(&my_xmldoc); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[CoCreateSafeDOMDocument failed][0x%x]"), hr)); |
- return hr; |
- } |
- hr = my_xmldoc->put_preserveWhiteSpace(VARIANT_BOOL(preserve_whitespace)); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[put_preserveWhiteSpace failed][0x%x]"), hr)); |
- return hr; |
- } |
- CComBSTR my_xmlfile(xmlfile); |
- VARIANT_BOOL is_successful(VARIANT_FALSE); |
- hr = my_xmldoc->load(CComVariant(my_xmlfile), &is_successful); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[my_xmldoc->load failed][0x%x]"), hr)); |
- return hr; |
- } |
- if (!is_successful) { |
- CComPtr<IXMLDOMParseError> error; |
- CString error_message; |
- hr = GetXMLParseError(my_xmldoc, &error); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[GetXMLParseError failed][0x%x]"), hr)); |
- return hr; |
- } |
- ASSERT1(error); |
- HRESULT error_code = 0; |
- hr = InterpretXMLParseError(error, &error_code, &error_message); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[InterpretXMLParseError failed][0x%x]"), hr)); |
- return hr; |
- } |
- UTIL_LOG(LE, (L"[LoadXMLFromFile '%s'][parse error: %s]", |
- xmlfile, error_message)); |
- ASSERT1(FAILED(error_code)); |
- return FAILED(error_code) ? error_code : CI_E_XML_LOAD_ERROR; |
- } |
- *xmldoc = my_xmldoc.Detach(); |
- return S_OK; |
-} |
- |
-HRESULT LoadXMLFromMemory(const TCHAR* xmlstring, |
- bool preserve_whitespace, |
- IXMLDOMDocument** xmldoc) { |
- ASSERT1(xmlstring); |
- ASSERT1(xmldoc); |
- ASSERT1(!*xmldoc); |
- |
- *xmldoc = NULL; |
- CComPtr<IXMLDOMDocument> my_xmldoc; |
- RET_IF_FAILED(CoCreateSafeDOMDocument(&my_xmldoc)); |
- RET_IF_FAILED(my_xmldoc->put_preserveWhiteSpace( |
- VARIANT_BOOL(preserve_whitespace))); |
- CComBSTR xmlmemory(xmlstring); |
- VARIANT_BOOL is_successful(VARIANT_FALSE); |
- RET_IF_FAILED(my_xmldoc->loadXML(xmlmemory, &is_successful)); |
- if (!is_successful) { |
- CComPtr<IXMLDOMParseError> error; |
- CString error_message; |
- RET_IF_FAILED(GetXMLParseError(my_xmldoc, &error)); |
- ASSERT1(error); |
- HRESULT error_code = 0; |
- RET_IF_FAILED(InterpretXMLParseError(error, &error_code, &error_message)); |
- UTIL_LOG(LE, (L"[LoadXMLFromMemory][parse error: %s]", error_message)); |
- ASSERT1(FAILED(error_code)); |
- return FAILED(error_code) ? error_code : CI_E_XML_LOAD_ERROR; |
- } |
- *xmldoc = my_xmldoc.Detach(); |
- return S_OK; |
-} |
- |
-HRESULT LoadXMLFromRawData(const std::vector<byte>& xmldata, |
- bool preserve_whitespace, |
- IXMLDOMDocument** xmldoc) { |
- ASSERT1(xmldoc); |
- ASSERT1(!*xmldoc); |
- |
- *xmldoc = NULL; |
- if (!xmldata.size()) { |
- return E_INVALIDARG; |
- } |
- |
- CComPtr<IXMLDOMDocument> my_xmldoc; |
- RET_IF_FAILED(CoCreateSafeDOMDocument(&my_xmldoc)); |
- RET_IF_FAILED(my_xmldoc->put_preserveWhiteSpace( |
- VARIANT_BOOL(preserve_whitespace))); |
- |
- CComSafeArray<byte> xmlsa; |
- xmlsa.Add(xmldata.size(), &xmldata.front()); |
- CComVariant xmlvar(xmlsa); |
- |
- VARIANT_BOOL is_successful(VARIANT_FALSE); |
- RET_IF_FAILED(my_xmldoc->load(xmlvar, &is_successful)); |
- if (!is_successful) { |
- CComPtr<IXMLDOMParseError> error; |
- CString error_message; |
- RET_IF_FAILED(GetXMLParseError(my_xmldoc, &error)); |
- ASSERT1(error); |
- HRESULT error_code = 0; |
- RET_IF_FAILED(InterpretXMLParseError(error, &error_code, &error_message)); |
- UTIL_LOG(LE, (_T("[LoadXMLFromRawData][parse error: %s]"), error_message)); |
- ASSERT1(FAILED(error_code)); |
- return FAILED(error_code) ? error_code : CI_E_XML_LOAD_ERROR; |
- } |
- *xmldoc = my_xmldoc.Detach(); |
- return S_OK; |
-} |
- |
-HRESULT SaveXMLToFile(IXMLDOMDocument* xmldoc, const TCHAR* xmlfile) { |
- ASSERT1(xmldoc); |
- ASSERT1(xmlfile); |
- |
- CComBSTR my_xmlfile(xmlfile); |
- RET_IF_FAILED(xmldoc->save(CComVariant(my_xmlfile))); |
- return S_OK; |
-} |
- |
-HRESULT SaveXMLToMemory(IXMLDOMDocument* xmldoc, CString* xmlstring) { |
- ASSERT1(xmldoc); |
- ASSERT1(xmlstring); |
- |
- CComBSTR xmlmemory; |
- RET_IF_FAILED(xmldoc->get_xml(&xmlmemory)); |
- *xmlstring = xmlmemory; |
- |
- return S_OK; |
-} |
- |
-HRESULT SaveXMLToRawData(IXMLDOMDocument* xmldoc, std::vector<byte>* buffer) { |
- ASSERT1(xmldoc); |
- ASSERT1(buffer); |
- |
- CComPtr<IStream> stream; |
- HRESULT hr = ::CreateStreamOnHGlobal(NULL, TRUE, &stream); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- ASSERT1(stream); |
- |
- hr = xmldoc->save(CComVariant(stream)); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- // To get the exact size of the stream, we have to use the seek function. |
- LARGE_INTEGER li = {0, 0}; |
- ULARGE_INTEGER uli = {0, 0}; |
- hr = stream->Seek(li, STREAM_SEEK_END, &uli); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- buffer->resize(static_cast<size_t>(uli.QuadPart)); |
- |
- HGLOBAL hglobal = NULL; |
- hr = ::GetHGlobalFromStream(stream, &hglobal); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- memcpy_s(&buffer->front(), |
- buffer->size(), |
- ::GlobalLock(hglobal), |
- buffer->size()); |
- ::GlobalUnlock(hglobal); |
- |
- return S_OK; |
-} |
- |
-HRESULT CanonicalizeXML(const TCHAR* xmlstring, CString* canonical_xmlstring) { |
- ASSERT1(xmlstring); |
- ASSERT1(canonical_xmlstring); |
- |
- // Round-trip through MSXML, having it strip whitespace. |
- |
- CComPtr<IXMLDOMDocument> xmldoc; |
- RET_IF_FAILED(CoCreateSafeDOMDocument(&xmldoc)); |
- RET_IF_FAILED(xmldoc->put_preserveWhiteSpace(VARIANT_FALSE)); |
- { |
- CComBSTR xmlmemory(StringAfterBOM(xmlstring)); |
- VARIANT_BOOL is_successful(VARIANT_FALSE); |
- RET_IF_FAILED(xmldoc->loadXML(xmlmemory, &is_successful)); |
- if (!is_successful) { |
- CComPtr<IXMLDOMParseError> error; |
- CString error_message; |
- RET_IF_FAILED(GetXMLParseError(xmldoc, &error)); |
- ASSERT1(error); |
- HRESULT error_code = 0; |
- RET_IF_FAILED(InterpretXMLParseError(error, &error_code, &error_message)); |
- UTIL_LOG(LE, (L"[CanonicalizeXML][parse error: %s]", error_message)); |
- ASSERT1(FAILED(error_code)); |
- return FAILED(error_code) ? error_code : CI_E_XML_LOAD_ERROR; |
- } |
- } |
- std::vector<CString> lines; |
- { |
- CComBSTR xmlmemory2; |
- RET_IF_FAILED(xmldoc->get_xml(&xmlmemory2)); |
- TextToLines(CString(xmlmemory2), L"\r\n", &lines); |
- } |
- { |
- for (size_t i = 0; i < lines.size(); ++i) { |
- TrimString(lines[i], L" \t"); |
- } |
- LinesToText(lines, L"", canonical_xmlstring); |
- } |
- |
- return S_OK; |
-} |
- |
-bool operator==(const XMLFQName& u, const XMLFQName& v) { |
- if (u.uri && v.uri) { |
- // Both uris are non-null -> compare all the components. |
- return !_tcscmp(u.uri, v.uri) && !_tcscmp(u.base, v.base); |
- } else if (!u.uri && !v.uri) { |
- // Both uris are null -> only compare the base names. |
- return !_tcscmp(u.base ? u.base : __T(""), v.base ? v.base : __T("")); |
- } else { |
- // Either uri is null -> the names are in different namespaces. |
- return false; |
- } |
-} |
- |
-bool operator!=(const XMLFQName& u, const XMLFQName& v) { |
- return !(u == v); |
-} |
- |
-bool operator<(const XMLFQName& u, const XMLFQName &v) { |
- if (u.uri && v.uri) { |
- return (_tcscmp(u.uri, v.uri) < 0) || |
- ((_tcscmp(u.uri, v.uri) == 0) && (_tcscmp(u.base, v.base) < 0)); |
- } else if (!u.uri && !v.uri) { |
- return _tcscmp(u.base, v.base) < 0; |
- } else { |
- return false; |
- } |
-} |
- |
-bool operator>(const XMLFQName& u, const XMLFQName& v) { |
- return v < u; |
-} |
- |
-bool operator<=(const XMLFQName& u, const XMLFQName& v) { |
- return !(v < u); |
-} |
- |
-bool operator>=(const XMLFQName& u, const XMLFQName& v) { |
- return !(u < v); |
-} |
- |
-bool EqualXMLName(const XMLFQName& u, const XMLFQName& v) { |
- return u == v; |
-} |
- |
-// msxml returns a null uri for nodes that don't belong to a namespace. |
-bool EqualXMLName(IXMLDOMNode* pnode, const XMLFQName& u) { |
- CComBSTR name; |
- CComBSTR uri; |
- if (FAILED(pnode->get_baseName(&name)) || |
- FAILED(pnode->get_namespaceURI(&uri))) { |
- return false; |
- } |
- return EqualXMLName(XMLFQName(uri, name), u); |
-} |
- |
-inline bool EqualXMLName(const XMLFQName& u, IXMLDOMNode* pnode) { |
- return EqualXMLName(pnode, u); |
-} |
- |
-HRESULT GetXMLFQName(IXMLDOMNode* node, XMLFQName* name) { |
- ASSERT1(node); |
- ASSERT1(name); |
- |
- CComBSTR basename, uri; |
- RET_IF_FAILED(node->get_baseName(&basename)); |
- RET_IF_FAILED(node->get_namespaceURI(&uri)); |
- *name = XMLFQName(uri, basename); |
- return S_OK; |
-} |
- |
-CString XMLFQNameToString(const XMLFQName& fqname) { |
- CString name; |
- if (fqname.uri) { |
- name += fqname.uri; |
- name += L":"; |
- } |
- if (fqname.base) { |
- name += fqname.base; |
- } |
- return name; |
-} |
- |
-CString NodeToString(IXMLDOMNode* pnode) { |
- ASSERT1(pnode); |
- |
- XMLFQName node_name; |
- if (SUCCEEDED(GetXMLFQName(pnode, &node_name))) { |
- return XMLFQNameToString(node_name); |
- } |
- return L""; |
-} |
- |
-HRESULT CreateXMLNode(IXMLDOMDocument* xmldoc, |
- int node_type, |
- const TCHAR* node_name, |
- const TCHAR* namespace_uri, |
- const TCHAR* text, |
- IXMLDOMNode** node_out) { |
- ASSERT1(xmldoc); |
- ASSERT1(node_name); |
- // namespace_uri can be NULL |
- // text can be NULL |
- ASSERT1(node_out); |
- ASSERT1(!*node_out); |
- |
- *node_out = NULL; |
- CComPtr<IXMLDOMNode> new_node; |
- CComBSTR node_name_string, namespace_uri_string; |
- RET_IF_FAILED(node_name_string.Append(node_name)); |
- RET_IF_FAILED(namespace_uri_string.Append(namespace_uri)); |
- RET_IF_FAILED(xmldoc->createNode(CComVariant(node_type), |
- node_name_string, |
- namespace_uri_string, |
- &new_node)); |
- ASSERT1(new_node); |
- |
- // If any text was supplied, put it in the node |
- if (text && text[0]) { |
- RET_IF_FAILED(new_node->put_text(CComBSTR(text))); |
- } |
- |
- *node_out = new_node.Detach(); |
- return S_OK; |
-} |
- |
-HRESULT AppendXMLNode(IXMLDOMNode* xmlnode, IXMLDOMNode* new_child) { |
- ASSERT1(xmlnode); |
- ASSERT1(new_child); |
- |
- CComPtr<IXMLDOMNode> useless; |
- RET_IF_FAILED(xmlnode->appendChild(new_child, &useless)); |
- return S_OK; |
-} |
- |
-HRESULT AppendXMLNode(IXMLDOMNode* xmlnode, const TCHAR* text) { |
- ASSERT1(xmlnode); |
- // text can be NULL |
- |
- if (text && text[0]) { |
- CComPtr<IXMLDOMDocument> xml_doc; |
- CComPtr<IXMLDOMText> text_node; |
- RET_IF_FAILED(xmlnode->get_ownerDocument(&xml_doc)); |
- ASSERT1(xml_doc); |
- RET_IF_FAILED(xml_doc->createTextNode(CComBSTR(text), &text_node)); |
- RET_IF_FAILED(AppendXMLNode(xmlnode, text_node)); |
- } |
- return S_OK; |
-} |
- |
-HRESULT AddXMLAttributeNode(IXMLDOMNode* xmlnode, IXMLDOMAttribute* new_child) { |
- ASSERT1(xmlnode); |
- ASSERT1(new_child); |
- |
- CComPtr<IXMLDOMNamedNodeMap> attributes; |
- CComPtr<IXMLDOMNode> useless; |
- RET_IF_FAILED(xmlnode->get_attributes(&attributes)); |
- RET_IF_FAILED(attributes->setNamedItem(new_child, &useless)); |
- return S_OK; |
-} |
- |
-HRESULT AddXMLAttributeNode(IXMLDOMElement* xmlelement, |
- const TCHAR* attribute_name, |
- const TCHAR* attribute_value) { |
- ASSERT1(xmlelement); |
- ASSERT1(attribute_name); |
- // attribute_value can be NULL |
- |
- RET_IF_FAILED(xmlelement->setAttribute(CComBSTR(attribute_name), |
- CComVariant(attribute_value))); |
- return S_OK; |
-} |
- |
-HRESULT AddXMLAttributeNode(IXMLDOMNode* xmlnode, |
- const TCHAR* attribute_namespace, |
- const TCHAR* attribute_name, |
- const TCHAR* attribute_value) { |
- ASSERT1(xmlnode); |
- ASSERT1(attribute_name); |
- // attribute_namespace can be NULL |
- // attribute_value can be NULL |
- |
- CComPtr<IXMLDOMDocument> xmldoc; |
- RET_IF_FAILED(xmlnode->get_ownerDocument(&xmldoc)); |
- ASSERT1(xmldoc); |
- |
- CComPtr<IXMLDOMNode> attribute_node; |
- RET_IF_FAILED(CreateXMLNode(xmldoc, |
- NODE_ATTRIBUTE, |
- attribute_name, |
- attribute_namespace, |
- attribute_value, |
- &attribute_node)); |
- CComQIPtr<IXMLDOMAttribute> attribute(attribute_node); |
- ASSERT1(attribute); |
- RET_IF_FAILED(AddXMLAttributeNode(xmlnode, attribute)); |
- return S_OK; |
-} |
- |
-HRESULT RemoveXMLChildrenByName(IXMLDOMNode* xmlnode, const XMLFQName& name) { |
- ASSERT1(xmlnode); |
- |
- CComPtr<IXMLDOMNodeList> node_list; |
- RET_IF_FAILED(xmlnode->get_childNodes(&node_list)); |
- ASSERT1(node_list); |
- |
- bool found = false; |
- do { |
- found = false; |
- long count = 0; // NOLINT |
- RET_IF_FAILED(node_list->get_length(&count)); |
- RET_IF_FAILED(node_list->reset()); |
- |
- for (int i = 0; i < count; ++i) { |
- CComPtr<IXMLDOMNode> child_node, useless; |
- RET_IF_FAILED(node_list->get_item(i, &child_node)); |
- ASSERT1(child_node); |
- if (EqualXMLName(child_node, name)) { |
- RET_IF_FAILED(xmlnode->removeChild(child_node, &useless)); |
- // Start loop over: the list is "alive" and changes when you remove a |
- // node from it. Yes this seems to be n^2 but in fact we expect at |
- // most one each of <Hash> and/or <Size> nodes. |
- found = true; |
- break; |
- } |
- } |
- } while (found); |
- |
- return S_OK; |
-} |
- |
-HRESULT GetXMLChildByName(IXMLDOMElement* xmlnode, |
- const TCHAR* child_name, |
- IXMLDOMNode** xmlchild) { |
- ASSERT1(xmlnode); |
- ASSERT1(child_name); |
- ASSERT1(xmlchild); |
- ASSERT1(!*xmlchild); |
- |
- *xmlchild = NULL; |
- CComPtr<IXMLDOMNodeList> node_list; |
- long node_list_length = 0; // NOLINT |
- RET_IF_FAILED(xmlnode->getElementsByTagName(CComBSTR(child_name), |
- &node_list)); |
- ASSERT1(node_list); |
- RET_IF_FAILED(node_list->get_length(&node_list_length)); |
- if (node_list_length <= 0) { |
- return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); |
- } |
- // Should only be one child node with name we're looking for. |
- if (node_list_length > 1) { |
- return CI_E_INVALID_MANIFEST; |
- } |
- RET_IF_FAILED(node_list->reset()); |
- RET_IF_FAILED(node_list->get_item(0, xmlchild)); |
- ASSERT1(*xmlchild); |
- return S_OK; |
-} |
- |
-HRESULT InsertXMLBeforeItem(IXMLDOMNode* xmlnode, |
- IXMLDOMNode* new_child, |
- size_t item_number) { |
- ASSERT1(xmlnode); |
- ASSERT1(new_child); |
- |
- CComPtr<IXMLDOMNodeList> child_list; |
- CComPtr<IXMLDOMNode> refchild, useless; |
- |
- RET_IF_FAILED(xmlnode->get_childNodes(&child_list)); |
- ASSERT1(child_list); |
- RET_IF_FAILED(child_list->get_item(item_number, &refchild)); |
- ASSERT1(refchild); |
- RET_IF_FAILED(xmlnode->insertBefore(new_child, |
- CComVariant(refchild), |
- &useless)); |
- return S_OK; |
-} |
- |
-HRESULT GetXMLParseError(IXMLDOMDocument* xmldoc, |
- IXMLDOMParseError** parse_error) { |
- ASSERT1(xmldoc); |
- ASSERT1(parse_error); |
- ASSERT1(!*parse_error); |
- |
- *parse_error = NULL; |
- CComPtr<IXMLDOMParseError> error; |
- RET_IF_FAILED(xmldoc->get_parseError(&error)); |
- HRESULT error_code = 0; |
- HRESULT hr = error->get_errorCode(&error_code); |
- if (hr == S_OK) { |
- *parse_error = error.Detach(); |
- return S_OK; |
- } else if (hr == S_FALSE) { |
- // No parse error |
- return S_FALSE; |
- } else { |
- return hr; |
- } |
-} |
- |
-HRESULT InterpretXMLParseError(IXMLDOMParseError* parse_error, |
- HRESULT* error_code, |
- CString* message) { |
- ASSERT1(parse_error); |
- ASSERT1(error_code); |
- ASSERT1(message); |
- |
- long line = 0; // NOLINT |
- long char_pos = 0; // NOLINT |
- CComBSTR src_text, reason; |
- RET_IF_FAILED(parse_error->get_errorCode(error_code)); |
- RET_IF_FAILED(parse_error->get_line(&line)); |
- RET_IF_FAILED(parse_error->get_linepos(&char_pos)); |
- RET_IF_FAILED(parse_error->get_srcText(&src_text)); |
- RET_IF_FAILED(parse_error->get_reason(&reason)); |
- |
- // Wild guess. |
- size_t size_estimate = src_text.Length() + reason.Length() + 100; |
- |
- // TODO(omaha): think about replacing this call to _snwprintf with a |
- // safestring function. |
- std::vector<TCHAR> s(size_estimate); |
- _snwprintf_s(&s.front(), size_estimate, _TRUNCATE, |
- L"%d(%d) : error 0x%08lx: %s\n %s", |
- line, char_pos, *error_code, |
- reason ? reason : L"", |
- src_text ? src_text : L"<no source text>"); |
- // _snwprintf doesn't terminate the string with a null if |
- // the formatted string fills the entire buffer. |
- s[s.size()- 1] = L'\0'; |
- *message = &s.front(); |
- return S_OK; |
-} |
- |
-HRESULT GetNumChildren(IXMLDOMNode* node, int* num_children) { |
- ASSERT1(node); |
- ASSERT1(num_children); |
- |
- *num_children = 0; |
- CComPtr<IXMLDOMNodeList> children; |
- RET_IF_FAILED(node->get_childNodes(&children)); |
- ASSERT1(children); |
- |
- long len = 0; // NOLINT |
- RET_IF_FAILED(children->get_length(&len)); |
- *num_children = len; |
- return S_OK; |
-} |
- |
-int GetNumAttributes(IXMLDOMNode* node) { |
- ASSERT1(node); |
- |
- CComPtr<IXMLDOMNamedNodeMap> attr_map; |
- if (FAILED(node->get_attributes(&attr_map))) { |
- return 0; |
- } |
- ASSERT1(attr_map); |
- long len = 0; // NOLINT |
- if (FAILED(attr_map->get_length(&len))) { |
- return 0; |
- } |
- return len; |
-} |
- |
-bool HasAttribute(IXMLDOMNode* node, const TCHAR* attr_name) { |
- ASSERT1(node); |
- ASSERT1(attr_name); |
- |
- CComPtr<IXMLDOMNamedNodeMap> attr_map; |
- if (FAILED(node->get_attributes(&attr_map))) { |
- return false; |
- } |
- if (!attr_map) { |
- return false; |
- } |
- |
- CComBSTR temp_attr_name(attr_name); |
- CComPtr<IXMLDOMNode> attribute_node; |
- if (FAILED(attr_map->getNamedItem(static_cast<BSTR>(temp_attr_name), |
- &attribute_node))) { |
- return false; |
- } |
- |
- return attribute_node != NULL; |
-} |
- |
-HRESULT ReadBooleanAttribute(IXMLDOMNode* node, |
- const TCHAR* attr_name, |
- bool* value) { |
- CORE_LOG(L4, (_T("[ReadBooleanAttribute][%s]"), attr_name)); |
- ASSERT1(node); |
- ASSERT1(attr_name); |
- ASSERT1(value); |
- |
- CComBSTR node_value; |
- HRESULT hr = ReadAttribute(node, attr_name, &node_value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[ReadAttribute failed][%s][0x%x]"), attr_name, hr)); |
- return hr; |
- } |
- |
- hr = String_StringToBool(static_cast<TCHAR*>(node_value), |
- value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[String_StringToBool failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- return S_OK; |
-} |
- |
-HRESULT ReadIntAttribute(IXMLDOMNode* node, |
- const TCHAR* attr_name, |
- int* value) { |
- CORE_LOG(L4, (_T("[ReadIntAttribute][%s]"), attr_name)); |
- ASSERT1(node); |
- ASSERT1(attr_name); |
- ASSERT1(value); |
- |
- CComBSTR node_value; |
- HRESULT hr = ReadAttribute(node, attr_name, &node_value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[ReadAttribute failed][%s][0x%x]"), attr_name, hr)); |
- return hr; |
- } |
- |
- if (!String_StringToDecimalIntChecked( |
- static_cast<const TCHAR*>(node_value), value)) { |
- return GOOPDATEXML_E_STRTOUINT; |
- } |
- return S_OK; |
-} |
- |
-HRESULT ReadGuidAttribute(IXMLDOMNode* node, |
- const TCHAR* attr_name, |
- GUID* value) { |
- CORE_LOG(L4, (_T("[ReadGuidAttribute][%s]"), attr_name)); |
- ASSERT1(node); |
- ASSERT1(attr_name); |
- ASSERT1(value); |
- |
- CComBSTR node_value; |
- HRESULT hr = ReadAttribute(node, attr_name, &node_value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[ReadAttribute failed][%s][0x%x]"), attr_name, hr)); |
- return hr; |
- } |
- |
- hr = StringToGuidSafe(static_cast<TCHAR*>(node_value), value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[StringToGuidSafe failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- return S_OK; |
-} |
- |
-HRESULT ReadStringAttribute(IXMLDOMNode* node, |
- const TCHAR* attr_name, |
- CString* value) { |
- CORE_LOG(L4, (_T("[ReadStringAttribute][%s]"), attr_name)); |
- ASSERT1(node); |
- ASSERT1(attr_name); |
- ASSERT1(value); |
- |
- CComBSTR node_value; |
- HRESULT hr = ReadAttribute(node, attr_name, &node_value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[ReadAttribute failed][%s][0x%x]"), attr_name, hr)); |
- return hr; |
- } |
- |
- // Will extract the underlying string. |
- *value = static_cast<TCHAR*>(node_value); |
- |
- return S_OK; |
-} |
- |
-HRESULT ReadAttribute(IXMLDOMNode* node, |
- const TCHAR* attr_name, |
- BSTR* value) { |
- CORE_LOG(L4, (_T("[ReadAttribute][%s]"), attr_name)); |
- ASSERT1(node); |
- ASSERT1(attr_name); |
- ASSERT1(value); |
- |
- // First read the attributes. |
- CComPtr<IXMLDOMNamedNodeMap> attributes; |
- HRESULT hr = node->get_attributes(&attributes); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[get_attributes failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- if (!attributes) { |
- CORE_LOG(LE, (_T("[Msxml S_FALSE return]"))); |
- return E_FAIL; // Protect against msxml S_FALSE return. |
- } |
- |
- CComPtr<IXMLDOMNode> attribute_node; |
- CComVariant node_value; |
- CComBSTR temp_attr_name(attr_name); |
- |
- // Get the attribute using a named node. |
- hr = attributes->getNamedItem(static_cast<BSTR>(temp_attr_name), |
- &attribute_node); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[getNamedItem failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- if (!attribute_node) { |
- CORE_LOG(LE, (_T("[Msxml S_FALSE return]"))); |
- return E_FAIL; // Protect against msxml S_FALSE return. |
- } |
- |
- hr = attribute_node->get_nodeValue(&node_value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[get_nodeValue failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- if (node_value.vt == VT_EMPTY) { |
- CORE_LOG(LE, (_T("[node_value.vt == VT_EMPTY]"))); |
- return E_FAIL; |
- } |
- |
- // Extract the variant into a BSTR. |
- node_value.CopyTo(value); |
- |
- return S_OK; |
-} |
- |
-HRESULT ReadStringValue(IXMLDOMNode* node, CString* value) { |
- CORE_LOG(L4, (_T("[ReadStringValue]"))); |
- ASSERT1(node); |
- ASSERT1(value); |
- |
- CComPtr<IXMLDOMNodeList> child_nodes; |
- HRESULT hr = node->get_childNodes(&child_nodes); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[get_childNodes failed][0x%x]"), hr)); |
- return hr; |
- } |
- if (!child_nodes) { |
- CORE_LOG(LE, (_T("[Msxml S_FALSE return]"))); |
- return E_FAIL; // Protect against msxml S_FALSE return. |
- } |
- |
- long count = 0; // NOLINT |
- hr = child_nodes->get_length(&count); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- ASSERT(count == 1, (_T("count: %u"), count)); |
- CComPtr<IXMLDOMNode> child_node; |
- hr = child_nodes->nextNode(&child_node); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- DOMNodeType type = NODE_INVALID; |
- hr = child_node->get_nodeType(&type); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[get_nodeType failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- if (type != NODE_TEXT) { |
- CORE_LOG(LE, (_T("[Invalid nodeType][%d]"), type)); |
- return E_INVALIDARG; |
- } |
- |
- CComVariant node_value; |
- hr = child_node->get_nodeValue(&node_value); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[get_nodeValue failed][0x%x]"), hr)); |
- return hr; |
- } |
- |
- if (node_value.vt != VT_BSTR) { |
- CORE_LOG(LE, (_T("[node_value.vt != VT_BSTR][%d]"), node_value.vt)); |
- return E_INVALIDARG; |
- } |
- |
- *value = V_BSTR(&node_value); |
- return S_OK; |
-} |
- |
-} // namespace omaha |
- |