From b927b467a3d372b6de7e1cb6193ec7a64ec24912 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 17 Mar 2016 12:25:22 +0100 Subject: [PATCH] XML helpers added --- build/wxExtend.vcxproj | 2 + build/wxExtend.vcxproj.filters | 6 ++ include/wxex/common.h | 9 +-- include/wxex/xml.h | 116 +++++++++++++++++++++++++++++++ src/stdafx.h | 1 + src/xml.cpp | 120 +++++++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+), 4 deletions(-) create mode 100644 include/wxex/xml.h create mode 100644 src/xml.cpp diff --git a/build/wxExtend.vcxproj b/build/wxExtend.vcxproj index 799c4c6..8359984 100644 --- a/build/wxExtend.vcxproj +++ b/build/wxExtend.vcxproj @@ -27,11 +27,13 @@ Create Create + + diff --git a/build/wxExtend.vcxproj.filters b/build/wxExtend.vcxproj.filters index f0c0f71..68925a3 100644 --- a/build/wxExtend.vcxproj.filters +++ b/build/wxExtend.vcxproj.filters @@ -28,6 +28,9 @@ Source Files + + Source Files + @@ -42,6 +45,9 @@ Header Files + + Header Files + diff --git a/include/wxex/common.h b/include/wxex/common.h index 3030c02..4798e47 100644 --- a/include/wxex/common.h +++ b/include/wxex/common.h @@ -79,10 +79,11 @@ inline bool wxGetDoWndAnimation() /// /// Modifies window extended style. /// -/// \param[in] hWnd Handle of the window to modify. -/// \param[in] dwRemove Set of extended styles to remove. -/// \param[in] dwAdd Set of extended styles to add. -/// \param[in] nFlags Additional SWP_ flags to pass to SetWindowPos(). If zero, SetWindowPos() is not called. +/// \param[in] hWnd Handle of the window to modify. +/// \param[in] dwRemove Set of extended styles to remove. +/// \param[in] dwAdd Set of extended styles to add. +/// \param[in] nFlags Additional SWP_ flags to pass to SetWindowPos(). If zero, SetWindowPos() is not called. +/// /// \returns /// - true when the window extended style was modified /// - false if the window extended style was not neccessary diff --git a/include/wxex/xml.h b/include/wxex/xml.h new file mode 100644 index 0000000..0dba1c4 --- /dev/null +++ b/include/wxex/xml.h @@ -0,0 +1,116 @@ +/* + Copyright 2016 Amebis + + This file is part of wxExtend. + + wxExtend is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + wxExtend is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with wxExtend. If not, see . +*/ + +#pragma once + +#include "common.h" + +#include +#include + + +/// +/// Escapes text string for XML insertion +/// +/// \param[in] str Text string +/// \returns Escaped string +/// +inline wxString wxXmlEscapeText(_In_ const wxString& str) +{ + wxString escaped; + escaped.reserve(str.length()); + + for (wxString::const_iterator i = str.begin(); i != str.end(); ++i) { + const wxChar c = *i; + switch (c) { + case wxS('<'): + escaped.append(wxS("<")); + break; + case wxS('>'): + escaped.append(wxS(">")); + break; + case wxS('&'): + escaped.append(wxS("&")); + break; + case wxS('\r'): + escaped.append(wxS(" ")); + break; + default: + escaped.append(c); + } + } + + return escaped; +} + + +/// +/// Escapes attribute value string for XML insertion +/// +/// \param[in] str Attribute value +/// +/// \returns Escaped string +/// +inline wxString wxXmlEscapeAttr(_In_ const wxString& str) +{ + wxString escaped; + escaped.reserve(str.length()); + + for (wxString::const_iterator i = str.begin(); i != str.end(); ++i) { + const wxChar c = *i; + switch (c) { + case wxS('<'): + escaped.append(wxS("<")); + break; + case wxS('>'): + escaped.append(wxS(">")); + break; + case wxS('&'): + escaped.append(wxS("&")); + break; + case wxS('\r'): + escaped.append(wxS(" ")); + break; + case wxS('"'): + escaped.append(wxS(""")); + break; + case wxS('\t'): + escaped.append(wxS(" ")); + break; + case wxS('\n'): + escaped.append(wxS(" ")); + break; + default: + escaped.append(c); + } + } + + return escaped; +} + + + +/// +/// Calculates hash of the node and all its children +/// +/// \param[in] hash Handle of a hash object +/// \param[in] node Root node +/// +/// +void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node); diff --git a/src/stdafx.h b/src/stdafx.h index 7ab1a0c..29d9677 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -25,5 +25,6 @@ #include "../include/wxex/appbar.h" #include "../include/wxex/comutils.h" +#include "../include/wxex/xml.h" #include "../include/wxex/common.h" diff --git a/src/xml.cpp b/src/xml.cpp new file mode 100644 index 0000000..e7d8e73 --- /dev/null +++ b/src/xml.cpp @@ -0,0 +1,120 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of wxExtend. + + wxExtend is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + wxExtend is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with wxExtend. If not, see . +*/ + +#include "stdafx.h" + + +static inline BOOL CryptHashData(__in HCRYPTHASH hHash, __in const wxString &str, __in DWORD dwFlags) +{ + const wxScopedCharBuffer buf(str.ToUTF8()); + return ::CryptHashData(hHash, (const BYTE*)buf.data(), buf.length(), dwFlags); +} + + +void WXEXTEND_API wxXmlHashNode(_In_ HCRYPTHASH hash, const wxXmlNode *node) +{ + wxASSERT_MSG(node, wxT("invalid parameter")); + + switch (node->GetType()) { + case wxXML_ELEMENT_NODE: + { + { + static const BYTE element_in [] = "<"; + + // Hash the open tag. + wxVERIFY(::CryptHashData(hash, element_in, _countof(element_in) - 1, 0)); + wxVERIFY(::CryptHashData(hash, node->GetName(), 0)); + for (wxXmlAttribute *attr = node->GetAttributes(); attr; attr = attr->GetNext()) { + static const BYTE attrib_sep[] = " "; + + wxVERIFY(::CryptHashData(hash, attrib_sep, _countof(attrib_sep) - 1, 0)); + wxVERIFY(::CryptHashData(hash, attr->GetName(), 0)); + wxString value = attr->GetValue(); + if (!value.IsEmpty()) { + static const BYTE + attrval_in [] = "=\"", + attrval_out[] = "\""; + + wxVERIFY(::CryptHashData(hash, attrval_in, _countof(attrval_in) - 1, 0)); + wxVERIFY(::CryptHashData(hash, wxXmlEscapeAttr(value), 0)); + wxVERIFY(::CryptHashData(hash, attrval_out, _countof(attrval_out) - 1, 0)); + } + } + } + + wxXmlNode *child = node->GetChildren(); + if (child) { + static const BYTE + element_out [] = ">", + elemclose_in[] = "GetNext()) + wxXmlHashNode(hash, child); + + // Hash the closing tag. + wxVERIFY(::CryptHashData(hash, elemclose_in, _countof(elemclose_in) - 1, 0)); + wxVERIFY(::CryptHashData(hash, node->GetName(), 0)); + wxVERIFY(::CryptHashData(hash, element_out, _countof(element_out) - 1, 0)); + } else { + static const BYTE element_out [] = "/>"; + + // Hash the childless element tag closing. + wxVERIFY(::CryptHashData(hash, element_out, _countof(element_out) - 1, 0)); + } + + break; + } + + case wxXML_TEXT_NODE: + { + wxVERIFY(::CryptHashData(hash, wxXmlEscapeText(node->GetContent()), 0)); + break; + } + + case wxXML_CDATA_SECTION_NODE: + { + static const BYTE + cdata_in [] = ""; + + wxVERIFY(::CryptHashData(hash, cdata_in, _countof(cdata_in) - 1, 0)); + wxVERIFY(::CryptHashData(hash, node->GetContent(), 0)); + wxVERIFY(::CryptHashData(hash, cdata_out, _countof(cdata_out) - 1, 0)); + + break; + } + + case wxXML_COMMENT_NODE: + { + wxVERIFY(::CryptHashData(hash, node->GetContent(), 0)); + break; + } + + case wxXML_DOCUMENT_NODE: + { + // Hash the children. + for (wxXmlNode *child = node->GetChildren(); child; child = child->GetNext()) + wxXmlHashNode(hash, child); + } + } +}