4#include "Stroika/Foundation/StroikaPreComp.h"
8#include <xercesc/validators/schema/identity/XPathException.hpp>
11#include "Stroika/Foundation/DataExchange/BadFormatException.h"
15#include "Stroika/Foundation/Execution/Exceptions.h"
16#include "Stroika/Foundation/Execution/Throw.h"
19#include "Stroika/Foundation/Memory/Common.h"
29using namespace Stroika::Foundation::DataExchange::XML;
30using namespace Stroika::Foundation::DataExchange::XML::DOM;
31using namespace Stroika::Foundation::DataExchange::XML::Schema;
32using namespace Stroika::Foundation::DataExchange::XML::Providers::Xerces;
33using namespace Stroika::Foundation::Debug;
35using namespace Stroika::Foundation::Streams;
37XERCES_CPP_NAMESPACE_USE;
41using Memory::MakeSharedPtr;
46static_assert (qStroika_HasComponent_xerces,
"Don't compile this file if qStroika_HasComponent_xerces not set");
57 constexpr auto kUseURIEncodingFlag_ = URI::StringPCTEncodedFlag::eDecoded;
62#define START_LIB_EXCEPTION_MAPPER_ try {
63#define END_LIB_EXCEPTION_MAPPER_ \
65 catch (const xercesc::OutOfMemoryException&) \
67 Execution::Throw (bad_alloc{}, "xerces OutOfMemoryException - throwing bad_alloc"); \
71 Execution::ReThrow (); \
74#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
81 struct MyXercesMemMgr_ :
public MemoryManager {
84 : fAllocator{fBaseAllocator}
89#if qStroika_Foundation_Debug_AssertionsChecked
90 auto snapshot = fAllocator.GetSnapshot ();
91 Assert (snapshot.fAllocations.empty ());
98 mutex fLastSnapshot_CritSection;
99 Memory::LeakTrackingGeneralPurposeAllocator::Snapshot fLastSnapshot;
102 void DUMPCurMemStats ()
105 [[maybe_unused]] lock_guard critSec{fLastSnapshot_CritSection};
106 fAllocator.DUMPCurMemStats (fLastSnapshot);
108 fLastSnapshot = fAllocator.GetSnapshot ();
112 virtual MemoryManager* getExceptionMemoryManager ()
override
116 virtual void* allocate (XMLSize_t size)
override
119 return fAllocator.Allocate (size);
123 throw (OutOfMemoryException{});
126 virtual void deallocate (
void* p)
override
129 return fAllocator.Deallocate (p);
137 struct MySchemaResolver_ :
public XMLEntityResolver {
143 : fResolver_{resolver}
146 virtual InputSource* resolveEntity (XMLResourceIdentifier* resourceIdentifier)
override
152 if (fResolver_ !=
nullptr) {
154 auto optionalString = [] (
const XMLCh* s) {
return s ==
nullptr ? optional<String>{} : xercesString2String (s); };
155 optional<String> ns = optionalString (resourceIdentifier->getNameSpace ());
156 if (
auto o = fResolver_.Lookup (
Resource::Name{.fNamespace = ns ? optional<URI>{*ns} : nullopt,
157 .fPublicID = optionalString (resourceIdentifier->getPublicId ()),
158 .fSystemID = optionalString (resourceIdentifier->getSystemId ())})) {
159 return mkMemInputSrc_ (o->fData);
166 static InputSource* mkMemInputSrc_ (
const Memory::BLOB& schemaData)
168 if (schemaData.
empty ()) [[unlikely]] {
170 return new MemBufInputSource{
nullptr, 0,
"",
true};
173 XMLByte* useBuf =
new XMLByte[schemaData.
GetSize ()];
174 memcpy (useBuf, schemaData.
begin (), schemaData.
GetSize ());
175 return new MemBufInputSource{useBuf, schemaData.
GetSize (),
"",
true};
182 void SetupCommonParserFeatures_ (SAX2XMLReader& reader)
184 reader.setFeature (XMLUni::fgSAX2CoreNameSpaces,
true);
185 reader.setFeature (XMLUni::fgXercesDynamic,
false);
186 reader.setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes,
false);
188 void SetupCommonParserFeatures_ (SAX2XMLReader& reader,
bool validatingWithSchema)
190 reader.setFeature (XMLUni::fgXercesSchema, validatingWithSchema);
191 reader.setFeature (XMLUni::fgSAX2CoreValidation, validatingWithSchema);
197 reader.setFeature (XMLUni::fgXercesSchemaFullChecking, validatingWithSchema);
198 reader.setFeature (XMLUni::fgXercesUseCachedGrammarInParse, validatingWithSchema);
199 reader.setFeature (XMLUni::fgXercesIdentityConstraintChecking, validatingWithSchema);
203 reader.setFeature (XMLUni::fgXercesCacheGrammarFromParse,
false);
208 struct Map2StroikaExceptionsErrorReporter_ :
public XMLErrorReporter,
public ErrorHandler {
210 virtual void error ([[maybe_unused]]
const unsigned int errCode, [[maybe_unused]]
const XMLCh*
const errDomain,
211 [[maybe_unused]]
const ErrTypes type,
const XMLCh*
const errorText, [[maybe_unused]]
const XMLCh*
const systemId,
212 [[maybe_unused]]
const XMLCh*
const publicId,
const XMLFileLoc lineNum,
const XMLFileLoc colNum)
override
214 Execution::Throw (
BadFormatException{errorText,
static_cast<unsigned int> (lineNum),
static_cast<unsigned int> (colNum), 0});
216 virtual void resetErrors ()
override
219 virtual void warning ([[maybe_unused]]
const SAXParseException& exc)
override
223 virtual void error (
const SAXParseException& exc)
override
225 Execution::Throw (
BadFormatException{exc.getMessage (),
static_cast<unsigned int> (exc.getLineNumber ()),
226 static_cast<unsigned int> (exc.getColumnNumber ()), 0});
228 virtual void fatalError (
const SAXParseException& exc)
override
230 Execution::Throw (
BadFormatException{exc.getMessage (),
static_cast<unsigned int> (exc.getLineNumber ()),
231 static_cast<unsigned int> (exc.getColumnNumber ()), 0});
237 struct SchemaRep_ : IXercesSchemaRep {
238#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
239 static inline atomic<unsigned int> sLiveCnt{0};
244 , fResolver{resolver}
245 , fSchemaData{schemaData.ReadAll ()}
248 XMLGrammarPoolImpl* grammarPool =
new (XMLPlatformUtils::fgMemoryManager) XMLGrammarPoolImpl{XMLPlatformUtils::fgMemoryManager};
250 Require (not fSchemaData.empty ());
251 MemBufInputSource mis{
reinterpret_cast<const XMLByte*
> (fSchemaData.begin ()), fSchemaData.GetSize (), u
""};
253 MySchemaResolver_ mySchemaResolver{resolver};
258 shared_ptr<SAX2XMLReaderImpl> reader = shared_ptr<SAX2XMLReaderImpl> (
259 new (XMLPlatformUtils::fgMemoryManager) SAX2XMLReaderImpl{XMLPlatformUtils::fgMemoryManager, grammarPool});
260 reader->setXMLEntityResolver (&mySchemaResolver);
262 SetupCommonParserFeatures_ (*reader,
true);
265 reader->setFeature (XMLUni::fgXercesCacheGrammarFromParse,
true);
266 reader->setErrorHandler (&fErrorReporter_);
267 xercesc::Grammar* g = reader->loadGrammar (mis, Grammar::SchemaGrammarType,
true);
269 const XMLCh* ts = g->getTargetNamespace ();
271 fTargetNamespace =
URI{xercesString2String (ts)};
276 Execution::ReThrow ();
281 grammarPool->lockPool ();
282 fCachedGrammarPool = grammarPool;
283#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
287 SchemaRep_ (
const SchemaRep_&) =
delete;
288 virtual ~SchemaRep_ ()
290 delete fCachedGrammarPool;
291#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
292 Assert (sLiveCnt > 0);
296 shared_ptr<const void> fLibrary_;
297 optional<URI> fTargetNamespace;
300 xercesc::XMLGrammarPool* fCachedGrammarPool{
nullptr};
301 Map2StroikaExceptionsErrorReporter_ fErrorReporter_;
303 virtual const Providers::ISchemaProvider* GetProvider ()
const override
305 return &XML::Providers::Xerces::kDefaultProvider;
307 virtual optional<URI> GetTargetNamespace ()
const override
309 return fTargetNamespace;
320 virtual xercesc::XMLGrammarPool* GetCachedGrammarPool ()
override
322 return fCachedGrammarPool;
328 class StdIStream_InputSource_ :
public InputSource {
330 class StdIStream_InputStream :
public XERCES_CPP_NAMESPACE_QUALIFIER BinInputStream {
336 ~StdIStream_InputStream () =
default;
339 virtual XMLFilePos curPos ()
const override
343 virtual XMLSize_t readBytes (XMLByte*
const toFill,
const XMLSize_t maxToRead)
override
345 return fSource.ReadBlocking (span{
reinterpret_cast<byte*
> (toFill), maxToRead}).size ();
347 virtual const XMLCh* getContentType ()
const override
362 virtual BinInputStream* makeStream ()
const override
364 return new (getMemoryManager ()) StdIStream_InputStream{fSource};
373 class SAX2PrintHandlers_ :
public DefaultHandler {
379 : fCallback_{callback}
384 virtual void startDocument ()
override
386 if (fCallback_ !=
nullptr) {
390 virtual void endDocument ()
override
392 if (fCallback_ !=
nullptr) {
396 virtual void startElement (
const XMLCh*
const uri,
const XMLCh*
const localName,
const XMLCh*
const ,
const Attributes& attributes)
override
398 Require (uri !=
nullptr);
399 Require (localName !=
nullptr);
400 if (fCallback_ !=
nullptr) {
403 size_t attributesLen = attributes.getLength ();
404 for (XMLSize_t i = 0; i < attributesLen; ++i) {
405 Name attrName{xercesString2String (attributes.getURI (i)), xercesString2String (attributes.getLocalName (i)), Name::eAttribute};
406 useAttrs.
Add (attrName, xercesString2String (attributes.getValue (i)));
408 fCallback_->
StartElement (Name{xercesString2String (uri), xercesString2String (localName)}, useAttrs);
411 virtual void endElement (
const XMLCh*
const uri,
const XMLCh*
const localName, [[maybe_unused]]
const XMLCh*
const qname)
override
413 Require (uri !=
nullptr);
414 Require (localName !=
nullptr);
415 Require (qname !=
nullptr);
416 if (fCallback_ !=
nullptr) {
420 virtual void characters (
const XMLCh*
const chars,
const XMLSize_t length)
override
422 Require (chars !=
nullptr);
423 Require (length != 0);
424 if (fCallback_ !=
nullptr) {
436 class SubNodeIterator_ {
441 virtual ~Rep () =
default;
444 virtual bool IsAtEnd ()
const = 0;
445 virtual void Next () = 0;
447 virtual size_t GetLength ()
const = 0;
449 explicit SubNodeIterator_ (
const shared_ptr<Rep>& from)
455 nonvirtual
bool NotDone ()
const
457 return not fRep->IsAtEnd ();
459 nonvirtual
bool IsAtEnd ()
const
461 return fRep->IsAtEnd ();
463 nonvirtual
void Next ()
469 return fRep->Current ();
471 nonvirtual
size_t GetLength ()
const
473 return fRep->GetLength ();
475 nonvirtual
void operator++ ()
479 nonvirtual
void operator++ (
int)
489 shared_ptr<Rep> fRep;
494 template <
class TYPE>
497 AutoRelease_ (TYPE* p)
501 AutoRelease_ (
const AutoRelease_<TYPE>&) =
delete;
502 AutoRelease_<TYPE>& operator= (
const AutoRelease_<TYPE>&) =
delete;
509 TYPE& operator* ()
const
513 TYPE* operator->()
const
517 operator TYPE*()
const
550 DOMImplementation& GetDOMIMPL_ ()
552 static constexpr XMLCh kDOMImplFeatureDeclaration_[] = u
"Core";
555 static DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation (kDOMImplFeatureDeclaration_);
562#if qStroika_Foundation_Debug_AssertionsChecked
563 bool ValidNewNodeName_ (
const String& n)
568 if (n.
find (
':') != wstring::npos) {
579 AutoRelease_<DOMLSOutput> theOutputDesc = GetDOMIMPL_ ().createLSOutput ();
580 theOutputDesc->setEncoding (XMLUni::fgUTF8EncodingString);
581 AutoRelease_<DOMLSSerializer> writer = GetDOMIMPL_ ().createLSSerializer ();
582 DOMConfiguration* dc = writer->getDomConfig ();
583 dc->setParameter (XMLUni::fgDOMWRTFormatPrettyPrint, options.
fPrettyPrint);
585 dc->setParameter (XMLUni::fgDOMWRTBOM,
false);
586 class myOutputter :
public XMLFormatTarget {
593 virtual void writeChars (
const XMLByte*
const toWrite,
const XMLSize_t count, [[maybe_unused]] XMLFormatter*
const formatter)
override
595 fOut.
Write (span<const byte>{
reinterpret_cast<const byte*
> (toWrite), count});
597 virtual void flush ()
override
602 myOutputter dest{to};
603 theOutputDesc->setByteStream (&dest);
604 writer->write (node2Write, theOutputDesc);
607 DOMNode* RecursivelySetNamespace_ (DOMNode* n,
const XMLCh* namespaceURI)
611 switch (n->getNodeType ()) {
612 case DOMNode::ELEMENT_NODE: {
613 xercesc::DOMDocument* doc = n->getOwnerDocument ();
615 n = doc->renameNode (n, namespaceURI, n->getNodeName ());
617 for (DOMNode* child = n->getFirstChild (); child !=
nullptr; child = child->getNextSibling ()) {
618 child = RecursivelySetNamespace_ (child, namespaceURI);
624 constexpr XMLCh* kXerces2XMLDBDocumentKey_ =
nullptr;
627 String GetTextForDOMNode_ (
const DOMNode* node)
630 if (node->getNodeType () == DOMNode::COMMENT_NODE) {
646 using xercesc::DOMNode;
647 using xercesc::DOMText;
649 for (DOMNode* n = node->getFirstChild (); n !=
nullptr; n = n->getNextSibling ()) {
650 switch (n->getNodeType ()) {
651 case DOMNode::TEXT_NODE:
652 case DOMNode::CDATA_SECTION_NODE: {
653 DOMText* t (
static_cast<DOMText*
> (n));
658 case DOMNode::ELEMENT_NODE: {
669 DbgTrace (
"WARNING: GetTextForDOMNode_::BackupMode used"_f);
670 return node->getTextContent ();
673 Node::Ptr WrapXercesNodeInStroikaNode_ (DOMNode* n);
674 Element::Ptr WrapXercesNodeInStroikaNode_ (DOMElement* n);
675#if qStroika_Foundation_Debug_AssertionsChecked
676 weak_ptr<Document::IRep> DocumentOf_ (DOMNode* n);
681 class SubNodeIteratorOver_SiblingList_Rep_ :
public SubNodeIterator_::Rep,
685 SubNodeIteratorOver_SiblingList_Rep_ (DOMNode* nodeParent)
686 : fParentNode{nodeParent}
687 , fCachedMainListLen{static_cast<size_t> (-1)}
690 START_LIB_EXCEPTION_MAPPER_
692 fCurNode_ = nodeParent->getFirstChild ();
694 END_LIB_EXCEPTION_MAPPER_
696 virtual bool IsAtEnd ()
const override
698 return fCurNode_ ==
nullptr;
700 virtual void Next ()
override
702 Require (not IsAtEnd ());
704 START_LIB_EXCEPTION_MAPPER_
706 fCurNode_ = fCurNode_->getNextSibling ();
708 END_LIB_EXCEPTION_MAPPER_
710 virtual Node::Ptr Current ()
const override
712 return WrapXercesNodeInStroikaNode_ (fCurNode_);
714 virtual size_t GetLength ()
const override
716 if (fCachedMainListLen ==
static_cast<size_t> (-1)) {
718 START_LIB_EXCEPTION_MAPPER_
720 for (DOMNode* i = fParentNode->getFirstChild (); i !=
nullptr; (i = i->getNextSibling ()), ++n)
723 END_LIB_EXCEPTION_MAPPER_
724 fCachedMainListLen = n;
726 return fCachedMainListLen;
730 DOMNode* fParentNode{
nullptr};
731 DOMNode* fCurNode_{
nullptr};
732 mutable size_t fCachedMainListLen{};
738 NodeRep_ (DOMNode* n)
741 , fOwningDoc_{DocumentOf_ (n)}
746#if qStroika_Foundation_Debug_AssertionsChecked
752 Require (not fOwningDoc_.expired ());
755 virtual const Providers::IDOMProvider* GetProvider ()
const override
757 return &Providers::Xerces::kDefaultProvider;
759 virtual bool Equals (
const IRep* rhs)
const override
763 return fNode_ ==
dynamic_cast<const NodeRep_*
> (rhs)->fNode_;
765 virtual Node::Type GetNodeType ()
const override
768 START_LIB_EXCEPTION_MAPPER_
770 switch (fNode_->getNodeType ()) {
771 case DOMNode::ELEMENT_NODE:
772 return Node::eElementNT;
773 case DOMNode::ATTRIBUTE_NODE:
774 return Node::eAttributeNT;
775 case DOMNode::TEXT_NODE:
776 return Node::eTextNT;
777 case DOMNode::COMMENT_NODE:
778 return Node::eCommentNT;
780 return Node::eOtherNT;
783 END_LIB_EXCEPTION_MAPPER_
788 Require (GetNodeType () == Node::eElementNT or GetNodeType () == Node::eAttributeNT);
789 START_LIB_EXCEPTION_MAPPER_
792 const XMLCh* n = fNode_->getNamespaceURI ();
800 const XMLCh* localName = fNode_->getLocalName ();
802 localName ==
nullptr ? fNode_->getNodeName () : localName};
804 END_LIB_EXCEPTION_MAPPER_
809#if qStroika_Foundation_Debug_AssertionsChecked
810 Require (ValidNewNodeName_ (name.
fName));
812 START_LIB_EXCEPTION_MAPPER_
814 xercesc::DOMDocument* doc = fNode_->getOwnerDocument ();
816 fNode_ = doc->renameNode (
817 fNode_, name.
fNamespace == nullopt ?
nullptr : name.fNamespace->As<
String> (kUseURIEncodingFlag_).As<u16string> ().c_str (),
818 name.fName.As<u16string> ().c_str ());
821 END_LIB_EXCEPTION_MAPPER_
823 virtual String GetValue ()
const override
826 START_LIB_EXCEPTION_MAPPER_
828 return GetTextForDOMNode_ (fNode_);
830 END_LIB_EXCEPTION_MAPPER_
832 virtual void SetValue (
const String& v)
override
835 START_LIB_EXCEPTION_MAPPER_
837 fNode_->setTextContent (v.empty () ?
nullptr : v.As<u16string> ().c_str ());
839 END_LIB_EXCEPTION_MAPPER_
841 virtual void DeleteNode ()
override
843 START_LIB_EXCEPTION_MAPPER_
845 DOMNode* selNode = fNode_;
847 DOMNode* parentNode = selNode->getParentNode ();
848 if (parentNode ==
nullptr) {
850 if (fNode_ !=
nullptr) {
851 const XMLCh* ln = selNode->getNodeName ();
853 DOMElement* de =
dynamic_cast<DOMElement*
> (fNode_);
854 de->removeAttribute (ln);
858 (void)parentNode->removeChild (selNode);
861 END_LIB_EXCEPTION_MAPPER_
863 virtual Node::Ptr GetParentNode ()
const override
866 START_LIB_EXCEPTION_MAPPER_
868 auto p = fNode_->getParentNode ();
869 return p ==
nullptr ? nullptr : WrapXercesNodeInStroikaNode_ (p);
871 END_LIB_EXCEPTION_MAPPER_
875 START_LIB_EXCEPTION_MAPPER_
877 DoWrite2Stream_ (fNode_, to, options);
879 END_LIB_EXCEPTION_MAPPER_
881 virtual xercesc::DOMNode* GetInternalTRep ()
override
887#if qStroika_Foundation_Debug_AssertionsChecked
888 weak_ptr<Document::IRep> fOwningDoc_;
895 struct ElementRep_ : Element::
IRep, Memory::InheritAndUseBlockAllocationIfAppropriate<ElementRep_, NodeRep_> {
897 ElementRep_ (DOMNode* n)
901 Require (n->getNodeType () == DOMNode::ELEMENT_NODE);
903 virtual Node::Type GetNodeType ()
const override
906 Assert (fNode_->getNodeType () == DOMNode::ELEMENT_NODE);
907 return Node::eElementNT;
909 virtual optional<String> GetAttribute (
const NameWithNamespace& attrName)
const override
912 START_LIB_EXCEPTION_MAPPER_
914 if (fNode_->getNodeType () == DOMNode::ELEMENT_NODE) {
915 DOMElement* elt = Debug::UncheckedDynamicCast<DOMElement*> (fNode_);
917 ? elt->getAttributeNS (attrName.
fNamespace->As<
String> (kUseURIEncodingFlag_).
As<u16string> ().c_str (),
918 attrName.
fName.
As<u16string> ().c_str ())
919 : elt->getAttribute (attrName.
fName.
As<u16string> ().c_str ());
927 END_LIB_EXCEPTION_MAPPER_
929 virtual void SetAttribute (
const NameWithNamespace& attrName,
const optional<String>& v)
override
931 Require (GetNodeType () == Node::eElementNT);
933 START_LIB_EXCEPTION_MAPPER_
935 DOMElement* element =
dynamic_cast<DOMElement*
> (fNode_);
963 u16string qName = attrName.
fName.
As<u16string> ();
965 qName = u
"xmlns:" + qName;
967 element->setAttributeNS (attrName.
fNamespace->As<
String> (kUseURIEncodingFlag_).
As<u16string> ().c_str (),
968 qName.c_str (), v->As<u16string> ().c_str ());
977 u16string ns16 = attrName.
fNamespace->As<
String> (kUseURIEncodingFlag_).As<u16string> ();
978 const XMLCh* had = element->lookupPrefix (ns16.c_str ());
980 if (had !=
nullptr and *had != u
'\0') {
984 for (
char16_t p = u
'a'; prefix.empty (); ++p) {
985 u16string candidate{p};
986 if (element->lookupNamespaceURI (candidate.c_str ()) ==
nullptr) {
990 static const u16string kXMLNSNamespace_{u
"http://www.w3.org/2000/xmlns/"};
991 element->setAttributeNS (kXMLNSNamespace_.c_str (), (u16string{u
"xmlns:"} + prefix).c_str (), ns16.c_str ());
993 element->setAttributeNS (ns16.c_str (), (prefix + u
":" + attrName.
fName.
As<u16string> ()).c_str (),
994 v->As<u16string> ().c_str ());
997 element->setAttributeNS (
nullptr, attrName.
fName.
As<u16string> ().c_str (), v->As<u16string> ().c_str ());
1001 element->removeAttributeNS (
1003 attrName.fName.As<u16string> ().c_str ());
1006 END_LIB_EXCEPTION_MAPPER_
1010#if qStroika_Foundation_Debug_AssertionsChecked
1011 Require (ValidNewNodeName_ (eltName.
fName));
1013 START_LIB_EXCEPTION_MAPPER_
1015 xercesc::DOMDocument* doc = fNode_->getOwnerDocument ();
1018 u16string ns16, qName;
1019 const XMLCh* useNS = ElementNS2Use_ (fNode_, eltName, &ns16, &qName);
1020 DOMNode* child = doc->createElementNS (useNS, qName.c_str ());
1021 DOMNode* refChildNode =
nullptr;
1022 if (afterNode ==
nullptr) {
1025 refChildNode = fNode_->getFirstChild ();
1028 refChildNode =
dynamic_cast<NodeRep_&
> (*afterNode.
GetRep ()).GetInternalTRep ()->getNextSibling ();
1030 DOMNode* childx = fNode_->insertBefore (child, refChildNode);
1032 return WrapXercesNodeInStroikaNode_ (childx);
1034 END_LIB_EXCEPTION_MAPPER_
1040 static const XMLCh* ElementNS2Use_ (DOMNode* parent,
const NameWithNamespace& eltName, u16string* buf, u16string* qName)
1044 *qName = eltName.
fName.
As<u16string> ();
1054 if (
const XMLCh* parentPrefix = parent->getPrefix (); parentPrefix !=
nullptr and *parentPrefix != u
'\0') {
1055 *qName = u16string{parentPrefix} + u
":" + *qName;
1057 return parent->getNamespaceURI ();
1059 *buf = eltName.
fNamespace->As<
String> (kUseURIEncodingFlag_).As<u16string> ();
1061 if (
const XMLCh* had = parent->lookupPrefix (buf->c_str ()); had !=
nullptr and *had != u
'\0') {
1062 *qName = u16string{had} + u
":" + *qName;
1064 return buf->c_str ();
1068#if qStroika_Foundation_Debug_AssertionsChecked
1069 Require (ValidNewNodeName_ (eltName.
fName));
1071 START_LIB_EXCEPTION_MAPPER_
1073 xercesc::DOMDocument* doc = fNode_->getOwnerDocument ();
1075 u16string ns16, qName;
1076 const XMLCh* useNS = ElementNS2Use_ (fNode_, eltName, &ns16, &qName);
1077 child = doc->createElementNS (useNS, qName.c_str ());
1078 DOMNode* childx = fNode_->appendChild (child);
1080 return WrapXercesNodeInStroikaNode_ (childx);
1082 END_LIB_EXCEPTION_MAPPER_
1088 DOMNode* CloneIntoThisDocument_ (
const Node::Ptr& cloneFrom)
1091 NodeRep_* fromRep =
dynamic_cast<NodeRep_*
> (cloneFrom.
GetRep ().get ());
1092 Require (fromRep !=
nullptr);
1093 DOMNode* copy = fNode_->getOwnerDocument ()->importNode (fromRep->GetInternalTRep (),
true );
1099 START_LIB_EXCEPTION_MAPPER_
1101 DOMNode* childx = fNode_->appendChild (CloneIntoThisDocument_ (cloneFrom));
1103 return WrapXercesNodeInStroikaNode_ (childx);
1105 END_LIB_EXCEPTION_MAPPER_
1109 Require (afterNode ==
nullptr or this->GetChildren ().Contains (afterNode));
1110 START_LIB_EXCEPTION_MAPPER_
1112 DOMNode* copy = CloneIntoThisDocument_ (cloneFrom);
1113 DOMNode* refChildNode = afterNode ==
nullptr
1114 ? fNode_->getFirstChild ()
1115 :
dynamic_cast<NodeRep_&
> (*afterNode.
GetRep ()).GetInternalTRep ()->getNextSibling ();
1116 DOMNode* childx = fNode_->insertBefore (copy, refChildNode);
1118 return WrapXercesNodeInStroikaNode_ (childx);
1120 END_LIB_EXCEPTION_MAPPER_
1125 START_LIB_EXCEPTION_MAPPER_
1127 return Traversal::CreateGenerator<Node::Ptr> (
1128 [sni = SubNodeIterator_{MakeSharedPtr<SubNodeIteratorOver_SiblingList_Rep_> (fNode_)}] ()
mutable -> optional<Node::Ptr> {
1129 if (sni.IsAtEnd ()) {
1130 return optional<Node::Ptr>{};
1137 END_LIB_EXCEPTION_MAPPER_
1139 struct XPathQueryHelper_ {
1140 optional<AutoRelease_<DOMXPathNSResolver>> resolver;
1141 DOMXPathResult::ResultType rt{};
1142 optional<AutoRelease_<DOMXPathExpression>> expr;
1145 xercesc::DOMDocument* doc = n->getOwnerDocument ();
1146 resolver.emplace (doc->createNSResolver (
nullptr));
1147 auto namespaceDefs = e.
GetOptions ().fNamespaces;
1148 if (namespaceDefs.GetDefaultNamespace ()) {
1149 (*resolver)->addNamespaceBinding (
1150 u
"", namespaceDefs.GetDefaultNamespace ()->As<
String> (kUseURIEncodingFlag_).
As<u16string> ().c_str ());
1153 (*resolver)->addNamespaceBinding (ni.fKey.As<u16string> ().c_str (),
1154 ni.fValue.As<
String> (kUseURIEncodingFlag_).
As<u16string> ().c_str ());
1157 expr.emplace (doc->createExpression (e.
GetExpression ().
As<u16string> ().c_str (), *resolver));
1159 catch (
const xercesc::DOMXPathException&) {
1161 Execution::Throw (XPath::XPathExpressionNotSupported::kThe);
1163 switch (e.
GetOptions ().fResultTypeIndex.value_or (DOMXPathResult::ANY_TYPE)) {
1164 case XPath::ResultTypeIndex_v<Node::Ptr>: {
1167 rt = e.
GetOptions ().fOrdered ? DOMXPathResult::FIRST_ORDERED_NODE_TYPE : DOMXPathResult::ANY_UNORDERED_NODE_TYPE;
1169 else if (o.fSnapshot) {
1170 rt = e.
GetOptions ().fOrdered ? DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE : DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE;
1175 rt = e.
GetOptions ().fOrdered ? DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE : DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE;
1182 static optional<XPath::Result> ToResult_ (
const xercesc::DOMXPathResult* r)
1185 switch (r->getResultType ()) {
1186 case DOMXPathResult::NUMBER_TYPE:
1187 return XPath::Result{r->getNumberValue ()};
1188 case DOMXPathResult::BOOLEAN_TYPE:
1189 return XPath::Result{r->getBooleanValue ()};
1190 case DOMXPathResult::STRING_TYPE:
1191 return XPath::Result{xercesString2String (r->getStringValue ())};
1192 case DOMXPathResult::ANY_UNORDERED_NODE_TYPE:
1193 case DOMXPathResult::FIRST_ORDERED_NODE_TYPE:
1194 case DOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE:
1195 case DOMXPathResult::ORDERED_NODE_ITERATOR_TYPE:
1196 case DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE:
1197 case DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE: {
1198 auto n = r->getNodeValue ();
1199 return n ==
nullptr ? optional<XPath::Result>{} : XPath::Result{
Node::Ptr{WrapXercesNodeInStroikaNode_ (n)}};
1209 if constexpr (
false) {
1211 for (
auto i : Lookup (e)) {
1216 START_LIB_EXCEPTION_MAPPER_
1218 XPathQueryHelper_ xpHelp{fNode_, e,
true};
1219 AutoRelease_<xercesc::DOMXPathResult> r = (*xpHelp.expr)->evaluate (fNode_, xpHelp.rt,
nullptr);
1220 return XPathQueryHelper_::ToResult_ (r);
1222 END_LIB_EXCEPTION_MAPPER_
1227 XPath::Expression::Options e2o = e.
GetOptions ();
1228 e2o.fSnapshot =
false;
1231 shared_ptr<XPathQueryHelper_> xpHelp = MakeSharedPtr<XPathQueryHelper_> (fNode_, e,
false);
1232 shared_ptr<AutoRelease_<xercesc::DOMXPathResult>> r =
1233 MakeSharedPtr<AutoRelease_<xercesc::DOMXPathResult>> ((*xpHelp->expr)->evaluate (fNode_, xpHelp->rt,
nullptr));
1235 if (xpHelp->rt == DOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE or xpHelp->rt == DOMXPathResult::ORDERED_NODE_ITERATOR_TYPE) [[unlikely]] {
1236 return Traversal::CreateGenerator<XPath::Result> ([xpHelp, r, firstTime =
true] ()
mutable -> optional<XPath::Result> {
1239 return XPathQueryHelper_::ToResult_ (*r);
1241 if ((*r)->iterateNext () ==
false) {
1244 return XPathQueryHelper_::ToResult_ (*r);
1247 if (xpHelp->rt == DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE or xpHelp->rt == DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE) [[likely]] {
1248 return Traversal::CreateGenerator<XPath::Result> ([xpHelp, r, snapIdx = 0] ()
mutable -> optional<XPath::Result> {
1249 if (not(*r)->snapshotItem (snapIdx)) {
1253 return XPathQueryHelper_::ToResult_ (*r);
1262 START_LIB_EXCEPTION_MAPPER_
1264 for (DOMNode* i = fNode_->getFirstChild (); i !=
nullptr; i = i->getNextSibling ()) {
1265 if (i->getNodeType () == DOMNode::ELEMENT_NODE) {
1266 DOMElement* elt = Debug::UncheckedDynamicCast<DOMElement*> (i);
1267 const XMLCh* s = elt->getAttribute (u
"id");
1269 if (CString::Equals (s,
id.As<u16string> ().c_str ())) {
1270 return WrapXercesNodeInStroikaNode_ (elt);
1276 END_LIB_EXCEPTION_MAPPER_
1279 DISABLE_COMPILER_MSC_WARNING_END (4250)
1283 inline void MakeXMLDoc_ (shared_ptr<xercesc::DOMDocument>& newXMLDoc)
1285 Require (newXMLDoc ==
nullptr);
1286 newXMLDoc = shared_ptr<xercesc::DOMDocument> (GetDOMIMPL_ ().createDocument (0,
nullptr, 0));
1287 newXMLDoc->setXmlStandalone (
true);
1292 class MyMaybeSchemaDOMParser_ {
1294 Map2StroikaExceptionsErrorReporter_ myErrReporter;
1295 shared_ptr<XercesDOMParser> fParser;
1298 MyMaybeSchemaDOMParser_ () =
delete;
1299 MyMaybeSchemaDOMParser_ (
const MyMaybeSchemaDOMParser_&) =
delete;
1300 MyMaybeSchemaDOMParser_ (
const Schema::Ptr& schema)
1304 Require (schema ==
nullptr or schema.GetRep ()->GetProvider () == &Providers::Xerces::kDefaultProvider);
1305 shared_ptr<IXercesSchemaRep> accessSchema = dynamic_pointer_cast<IXercesSchemaRep> (schema.GetRep ());
1306 if (accessSchema !=
nullptr) {
1307 fParser = MakeSharedPtr<XercesDOMParser> (
nullptr, XMLPlatformUtils::fgMemoryManager, accessSchema->GetCachedGrammarPool ());
1308 fParser->cacheGrammarFromParse (
false);
1309 fParser->useCachedGrammarInParse (
true);
1310 fParser->setDoSchema (
true);
1311 fParser->setValidationScheme (AbstractDOMParser::Val_Always);
1312 fParser->setValidationSchemaFullChecking (
true);
1313 fParser->setIdentityConstraintChecking (
true);
1316 fParser = MakeSharedPtr<XercesDOMParser> ();
1318 fParser->setDoNamespaces (
true);
1319 fParser->setErrorHandler (&myErrReporter);
1327 fParser->setLoadExternalDTD (
false);
1331 fParser->setLoadSchema (
false);
1338 Element::Ptr WrapXercesNodeInStroikaNode_ (DOMElement* n);
1344 struct DocRep_ : DataExchange::XML::DOM::Document::IRep
1345#if qStroika_Foundation_Debug_AssertionsChecked
1347 enable_shared_from_this<DocRep_>
1350#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1351 static inline atomic<unsigned int> sLiveCnt{0};
1360 : fLibrary_{library}
1362 [[maybe_unused]]
int ignoreMe = 0;
1363 START_LIB_EXCEPTION_MAPPER_
1365 MakeXMLDoc_ (fXMLDoc);
1366 fXMLDoc->setUserData (kXerces2XMLDBDocumentKey_,
this,
nullptr);
1367 if (in !=
nullptr) {
1368 MyMaybeSchemaDOMParser_ myDOMParser{schema};
1369 myDOMParser.fParser->parse (StdIStream_InputSource_{in, u
"XMLDB"});
1371 fXMLDoc = shared_ptr<xercesc::DOMDocument>{myDOMParser.fParser->adoptDocument ()};
1372 fXMLDoc->setXmlStandalone (
true);
1373 fXMLDoc->setUserData (kXerces2XMLDBDocumentKey_,
this,
nullptr);
1376 END_LIB_EXCEPTION_MAPPER_
1377#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1381 DocRep_ (
const DocRep_& from)
1382 : fLibrary_{from.fLibrary_}
1384 START_LIB_EXCEPTION_MAPPER_
1386 fXMLDoc = shared_ptr<xercesc::DOMDocument> (
dynamic_cast<xercesc::DOMDocument*
> (from.fXMLDoc->cloneNode (
true)));
1387 fXMLDoc->setXmlStandalone (
true);
1388 fXMLDoc->setUserData (kXerces2XMLDBDocumentKey_,
this,
nullptr);
1390 END_LIB_EXCEPTION_MAPPER_
1392#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1398#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1399 Assert (sLiveCnt > 0);
1403 virtual const Providers::IDOMProvider* GetProvider ()
const override
1405 return &Providers::Xerces::kDefaultProvider;
1407 virtual bool GetStandalone ()
const override
1410 return fXMLDoc->getXmlStandalone ();
1412 virtual void SetStandalone (
bool standalone)
override
1415 fXMLDoc->setXmlStandalone (standalone);
1421 START_LIB_EXCEPTION_MAPPER_
1422 return Traversal::CreateGenerator<Node::Ptr> (
1423 [sni = SubNodeIterator_{MakeSharedPtr<SubNodeIteratorOver_SiblingList_Rep_> (fXMLDoc.get ())}] ()
mutable -> optional<Node::Ptr> {
1424 if (sni.IsAtEnd ()) {
1425 return optional<Node::Ptr>{};
1431 END_LIB_EXCEPTION_MAPPER_
1437 u16string qName = newEltName.
fName.
As<u16string> ();
1438 if (namespacePrefix) {
1439 qName = namespacePrefix->As<u16string> () + u
":" + qName;
1441 DOMElement* n = newEltName.
fNamespace == nullopt
1442 ? fXMLDoc->createElement (qName.c_str ())
1443 : fXMLDoc->createElementNS (newEltName.fNamespace->As<
String> (kUseURIEncodingFlag_).As<u16string> ().c_str (),
1446 DOMElement* oldRoot = fXMLDoc->getDocumentElement ();
1447 if (oldRoot ==
nullptr) {
1448 (void)fXMLDoc->insertBefore (n,
nullptr);
1451 (void)fXMLDoc->replaceChild (n, oldRoot);
1470 Assert (fXMLDoc->getDocumentElement () == n);
1475 newEltName.fNamespace->As<
String> ());
1484 START_LIB_EXCEPTION_MAPPER_
1486 DoWrite2Stream_ (fXMLDoc.get (), to, options);
1488 END_LIB_EXCEPTION_MAPPER_
1490#if qCompilerAndStdLib_arm_asan_FaultStackUseAfterScope_Buggy
1491 Stroika_Foundation_Debug_ATTRIBUTE_NO_SANITIZE_ADDRESS
1493 virtual void Validate (
const Schema::Ptr& schema)
const override
1498 Require (schema.GetRep ()->GetProvider () == &Providers::Xerces::kDefaultProvider);
1499 START_LIB_EXCEPTION_MAPPER_
1506 DOMNode* docNode = fXMLDoc->getDocumentElement ();
1507 if (docNode ==
nullptr) [[unlikely]] {
1510 optional<URI> docURI = docNode->getNamespaceURI () ==
nullptr ? optional<URI>{} : docNode->getNamespaceURI ();
1513 Format (
"Wrong document namespace (found '{}' and expected '{}')"_f, docURI, schema.
GetTargetNamespace ()), 0, 0, 0});
1518 MemBufFormatTarget destination;
1520 AutoRelease_<DOMLSOutput> theOutputDesc = GetDOMIMPL_ ().createLSOutput ();
1521 theOutputDesc->setEncoding (XMLUni::fgUTF8EncodingString);
1522 AutoRelease_<DOMLSSerializer> writer = GetDOMIMPL_ ().createLSSerializer ();
1523 theOutputDesc->setByteStream (&destination);
1524 theOutputDesc->setEncoding (XMLUni::fgUTF8EncodingString);
1525 Assert (fXMLDoc->getXmlStandalone ());
1526 writer->write (fXMLDoc.get (), theOutputDesc);
1528 MemBufInputSource readReadSrc{destination.getRawBuffer (), destination.getLen (), u
"tmp"};
1529 readReadSrc.setEncoding (XMLUni::fgUTF8EncodingString);
1530 shared_ptr<IXercesSchemaRep> accessSchema = dynamic_pointer_cast<IXercesSchemaRep> (schema.GetRep ());
1533 shared_ptr<SAX2XMLReader> parser = shared_ptr<SAX2XMLReader> (
1534 XMLReaderFactory::createXMLReader (XMLPlatformUtils::fgMemoryManager, accessSchema->GetCachedGrammarPool ()));
1535 SetupCommonParserFeatures_ (*parser,
true);
1536 Map2StroikaExceptionsErrorReporter_ myErrorReporter;
1537 parser->setErrorHandler (&myErrorReporter);
1538 parser->parse (readReadSrc);
1543 if constexpr (qDumpXMLOnValidationError_) {
1544#if !qCompilerAndStdLib_arm_asan_FaultStackUseAfterScope_Buggy
1550 DbgTrace (
"Error validating - so writing out temporary file = '{}'"_f, tmpFileName);
1553 ValidateFile (tmpFileName, schema);
1557 size_t idx = tmpFileNameStr.
find (
".xml");
1558 String newTmpFile = tmpFileNameStr.
substr (0, idx) +
"_MSG.txt";
1560 msgOut <<
"Reason:" << vf.GetDetails () << endl;
1561 optional<unsigned int> lineNum;
1562 optional<unsigned int> colNumber;
1563 optional<uint64_t> fileOffset;
1564 vf.GetPositionInfo (&lineNum, &colNumber, &fileOffset);
1566 msgOut <<
"Line:" << *lineNum << endl;
1569 msgOut <<
"Col: " << *colNumber << endl;
1572 msgOut <<
"FilePos: " << *fileOffset << endl;
1579 Execution::ReThrow ();
1582 END_LIB_EXCEPTION_MAPPER_
1584 shared_ptr<const void> fLibrary_;
1585 shared_ptr<xercesc::DOMDocument> fXMLDoc;
1591#if qStroika_Foundation_Debug_AssertionsChecked
1593 weak_ptr<Document::IRep> DocumentOf_ (DOMNode* n)
1596 xercesc::DOMDocument* doc = n->getNodeType () == DOMNode::DOCUMENT_NODE ?
dynamic_cast<xercesc::DOMDocument*
> (n) : n->getOwnerDocument ();
1597 auto wrapper = doc ==
nullptr ? nullptr :
static_cast<DocRep_*
> (doc->getUserData (kXerces2XMLDBDocumentKey_));
1598 return wrapper ==
nullptr ? weak_ptr<Document::IRep>{} : wrapper->weak_from_this ();
1602 Node::Ptr WrapXercesNodeInStroikaNode_ (DOMNode* n)
1605 if (n->getNodeType () == DOMNode::ELEMENT_NODE) {
1606 return Node::Ptr{MakeSharedPtr<ElementRep_> (n)};
1609 return Node::Ptr{MakeSharedPtr<NodeRep_> (n)};
1612 Element::Ptr WrapXercesNodeInStroikaNode_ (DOMElement* n)
1624String Providers::Xerces::xercesString2String (
const XMLCh* s,
const XMLCh* e)
1626 if constexpr (same_as<XMLCh, char16_t>) {
1627 return String{span{s, e}};
1631 if constexpr (
sizeof (XMLCh) ==
sizeof (
char16_t)) {
1632 return String{span{
reinterpret_cast<const char16_t*
> (s),
reinterpret_cast<const char16_t*
> (e)}};
1634 else if constexpr (
sizeof (XMLCh) ==
sizeof (
char32_t)) {
1635 return String{span{
reinterpret_cast<const char32_t*
> (s),
reinterpret_cast<const char32_t*
> (e)}};
1643String Providers::Xerces::xercesString2String (
const XMLCh* t)
1645 if constexpr (same_as<XMLCh, char16_t>) {
1650 if constexpr (
sizeof (XMLCh) ==
sizeof (
char16_t)) {
1651 return String{
reinterpret_cast<const char16_t*
> (t)};
1653 else if constexpr (
sizeof (XMLCh) ==
sizeof (
char32_t)) {
1654 return String{
reinterpret_cast<const char32_t*
> (t)};
1673#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1674 XMLPlatformUtils::Initialize (XMLUni::fgXercescDefaultLocale, 0, 0, &fMemoryManager_);
1676 XMLPlatformUtils::Initialize (XMLUni::fgXercescDefaultLocale, 0, 0);
1679 Library_ (
const Library_&) =
delete;
1683 XMLPlatformUtils::Terminate ();
1684#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1685 Assert (SchemaRep_::sLiveCnt == 0);
1686 Assert (DocRep_::sLiveCnt == 0);
1689#if qStroika_Foundation_DataExchange_XML_DebugMemoryAllocations
1690 MyXercesMemMgr_ fMemoryManager_;
1695Providers::Xerces::Provider::Provider ()
1699#if qStroika_Foundation_Debug_AssertionsChecked
1700 static unsigned int sNProvidersCreated_{0};
1701 Assert (++sNProvidersCreated_ == 1);
1707 return MakeSharedPtr<SchemaRep_> (fLibrary_, schemaData, resolver);
1711 const Schema::Ptr& schemaToValidateAgainstWhileReading)
const
1713 return MakeSharedPtr<DocRep_> (fLibrary_, in, schemaToValidateAgainstWhileReading);
1721 Require (schema ==
nullptr or schema.GetRep ()->GetProvider () == &Providers::Xerces::kDefaultProvider);
1722 SAX2PrintHandlers_ handler{callback};
1723 shared_ptr<IXercesSchemaRep> accessSchema;
1724 if (schema !=
nullptr) {
1725 accessSchema = dynamic_pointer_cast<IXercesSchemaRep> (schema.GetRep ());
1727 shared_ptr<SAX2XMLReader> parser{XMLReaderFactory::createXMLReader (
1728 XMLPlatformUtils::fgMemoryManager, accessSchema ==
nullptr ?
nullptr : accessSchema->GetCachedGrammarPool ())};
1729 SetupCommonParserFeatures_ (*parser, accessSchema !=
nullptr);
1730 parser->setContentHandler (&handler);
1731 Map2StroikaExceptionsErrorReporter_ mErrorReproter_;
1732 parser->setErrorHandler (&mErrorReproter_);
1733 parser->parse (StdIStream_InputSource_{in});
#define AssertNotImplemented()
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
#define AssertNotReached()
auto MakeSharedPtr(ARGS_TYPE &&... args) -> shared_ptr< T >
same as make_shared, but if type T has block allocation, then use block allocation for the 'shared pa...
conditional_t< qStroika_Foundation_Memory_PreferBlockAllocation and andTrueCheck, BlockAllocationUseHelper< T >, Common::Empty > UseBlockAllocationIfAppropriate
Use this to enable block allocation for a particular class. Beware of subclassing.
bool Equals(const T *lhs, const T *rhs)
strcmp or wsccmp() as appropriate == 0
#define CompileTimeFlagChecker_SOURCE(NS_PREFIX, NAME, VALUE)
#define Stroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE
[[msvc::no_unique_address]] isn't always broken in MSVC. Annotate with this on things where its not b...
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
nonvirtual String str() const
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual string AsNarrowSDKString() const
nonvirtual String substr(size_t from, size_t count=npos) const
nonvirtual size_t find(Character c, size_t startAt=0) const
A Mapping uniquely associates two elements: a key and a value (use Assocation to allow multiple value...
nonvirtual bool Add(ArgByValueType< key_type > key, ArgByValueType< mapped_type > newElt, AddReplaceMode addReplaceMode=AddReplaceMode::eAddReplaces)
A generalization of a vector: a container whose elements are keyed by the natural numbers.
virtual void EndDocument()
virtual void StartDocument()
virtual void TextInsideElement(const String &text)
virtual void EndElement(const Name &name)
virtual void StartElement(const Name &name, const Mapping< Name, String > &attributes)
nonvirtual void SetAttribute(const NameWithNamespace &attrName, const optional< String > &v)
nonvirtual shared_ptr< IRep > GetRep() const
return the associated shared_ptr (cannot be nullptr)
Node::Ptr is a smart pointer to a Node::IRep.
nonvirtual shared_ptr< IRep > GetRep() const
return the associated shared_ptr (cannot be nullptr)
nonvirtual String GetExpression() const
nonvirtual Options GetOptions() const
nonvirtual optional< URI > GetTargetNamespace() const
NOT a real mutex - just a debugging infrastructure support tool so in debug builds can be assured thr...
shared_lock< const AssertExternallySynchronizedChecker > ReadContext
Instantiate AssertExternallySynchronizedChecker::ReadContext to designate an area of code where prote...
nonvirtual filesystem::path GetTmpFile(const String &fileBaseName)
static AppTmpFileManager sThe
nonvirtual bool empty() const
nonvirtual const byte * begin() const
nonvirtual size_t GetSize() const
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
nonvirtual void Write(span< ELEMENT_TYPE2, EXTENT_2 > elts) const
nonvirtual void Flush() const
forces any data contained in this stream to be written.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
DISABLE_COMPILER_MSC_WARNING_START(4996)
void ThrowIfNull(const Private_::ConstVoidStar &p, const HRESULT &hr)
Template specialization for ThrowIfNull (), for thing being thrown HRESULT - really throw HRESULTErro...
An element's or attribute's name (local-name, not including a prefix), plus the namespace that name i...
String fName
The LOCAL name - "Why" for <x:Why>
optional< URI > fNamespace
The namespace fName is in, however the document said so - nullopt for a name in no namespace.