From d6e254cdf9a5f68b1cb3c4f718a00510662c306f Mon Sep 17 00:00:00 2001
From: "Unknown (roddey)" <dev-null@apache.org>
Date: Tue, 30 Nov 1999 20:28:05 +0000
Subject: [PATCH] New sample which shows how to enumerate the contents of a
 DTDValidator to get to the decl objects inside.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@171435 13f79535-47bb-0310-9956-ffa450edef68
---
 samples/EnumVal/EnumVal.cpp | 331 ++++++++++++++++++++++++++++++++++++
 1 file changed, 331 insertions(+)
 create mode 100644 samples/EnumVal/EnumVal.cpp

diff --git a/samples/EnumVal/EnumVal.cpp b/samples/EnumVal/EnumVal.cpp
new file mode 100644
index 000000000..09dc0509e
--- /dev/null
+++ b/samples/EnumVal/EnumVal.cpp
@@ -0,0 +1,331 @@
+/*
+ * (C) Copyright IBM Corp. 1999  All rights reserved.
+ *
+ * US Government Users Restricted Rights Use, duplication or
+ * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+ *
+ * The program is provided "as is" without any warranty express or
+ * implied, including the warranty of non-infringement and the implied
+ * warranties of merchantibility and fitness for a particular purpose.
+ * IBM will not be liable for any damages suffered by you as a result
+ * of using the Program. In no event will IBM be liable for any
+ * special, indirect or consequential damages or lost profits even if
+ * IBM has been advised of the possibility of their occurrence. IBM
+ * will not be liable for any third party claims against you.
+ */
+
+/**
+ * @version Revision: %M% %I% %W% %Q%
+ */
+
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <util/NameIdPool.hpp>
+#include <util/PlatformUtils.hpp>
+#include <framework/XMLValidator.hpp>
+#include <parsers/SAXParser.hpp>
+#include <validators/DTD/DTDValidator.hpp>
+#include <iostream.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+// ---------------------------------------------------------------------------
+//  Forward references
+// ---------------------------------------------------------------------------
+static void usage();
+
+
+
+// ---------------------------------------------------------------------------
+//  This is a simple class that lets us do easy (though not terribly efficient)
+//  trancoding of XMLCh data to local code page for display.
+// ---------------------------------------------------------------------------
+class StrX
+{
+public :
+    // -----------------------------------------------------------------------
+    //  Constructors and Destructor
+    // -----------------------------------------------------------------------
+	StrX(const XMLCh* const toTranscode, const unsigned int len = 0) :
+
+        fLocalForm(0)
+    {
+        // Call the private transcoding method
+        transcode(toTranscode, len);
+    }
+
+    ~StrX()
+    {
+        delete [] fLocalForm;
+    }
+
+
+    // -----------------------------------------------------------------------
+    //  Getter methods
+    // -----------------------------------------------------------------------
+    const char* localForm() const
+    {
+        return fLocalForm;
+    }
+
+
+private :
+    // -----------------------------------------------------------------------
+    //  Private helper methods
+    // -----------------------------------------------------------------------
+	void transcode (const XMLCh* const toTranscode, const unsigned int len);
+
+
+    // -----------------------------------------------------------------------
+    //  Private data members
+    //
+    //  fLocalForm
+    //      This is the local code page form of the string.
+    // -----------------------------------------------------------------------
+    char*   fLocalForm;
+};
+
+inline ostream& operator<<(ostream& target, const StrX& toDump)
+{
+    target << toDump.localForm();
+    return target;
+}
+
+
+// ---------------------------------------------------------------------------
+//  Program entry point
+// ---------------------------------------------------------------------------
+int main(int argc, char* args[])
+{
+    // Initialize the XML4C system
+    try
+    {
+         XMLPlatformUtils::Initialize();
+    }
+
+    catch (const XMLException& toCatch)
+    {
+         cerr   << "Error during initialization! Message:\n"
+                << StrX(toCatch.getMessage()) << endl;
+         return 1;
+    }
+
+    // We only have one required parameter, which is the file to process
+    if (argc < 2)
+    {
+        usage();
+        return -1;
+    }
+    const char* xmlFile = args[1];
+    bool  doValidation = false;
+
+    // Check for some special cases values of the parameter
+    if (!strncmp(xmlFile, "-?", 2))
+    {
+        usage();
+        return 0;
+    }
+     else if (!strncmp(xmlFile, "-v", 2))
+    {
+        doValidation = true;
+        if (argc < 3)
+        {
+            usage();
+            return -1;
+        }
+        xmlFile = args[2];
+    }
+     else if (xmlFile[0] == '-')
+    {
+        usage();
+        return -1;
+    }
+
+    //
+    //  Create a DTD validator to be used for our validation work. Then create
+    //  a SAX parser object and pass it our validator. Then, according to what
+    //  we were told on the command line, set it to validate or not. He owns
+    //  the validator, so we have to allocate it.
+    //
+    DTDValidator* valToUse = new DTDValidator;
+    SAXParser parser(valToUse);
+    parser.setDoValidation(doValidation);
+
+    //
+    //  Get the starting time and kick off the parse of the indicated
+    //  file. Catch any exceptions that might propogate out of it.
+    //
+    try
+    {
+        parser.parse(xmlFile);
+    }
+
+    catch (const XMLException& e)
+    {
+        cerr << "\nError during parsing: '" << xmlFile << "'\n"
+             << "Exception message is:  \n"
+             << StrX(e.getMessage()) << "\n" << endl;
+        return -1;
+    }
+
+    //
+    //  Now we will get an enumerator for the element pool from the validator
+    //  and enumerate the elements, printing them as we go. For each element
+    //  we get an enumerator for its attributes and print them also.
+    //
+    NameIdPoolEnumerator<DTDElementDecl> elemEnum = valToUse->getElemEnumerator();
+    if (elemEnum.hasMoreElements())
+    {
+        cout << "\nELEMENTS:\n----------------------------\n";
+        while(elemEnum.hasMoreElements())
+        {
+            const DTDElementDecl& curElem = elemEnum.nextElement();
+            cout << "  Name: " << StrX(curElem.getFullName()) << "\n";
+
+            cout << "  Content Model: "
+                 << StrX(curElem.getFormattedContentModel(*valToUse))
+                 << "\n";
+
+            // Get an enumerator for this guy's attributes if any
+            if (curElem.hasAttDefs())
+            {
+                cout << "  Attributes:\n";
+                XMLAttDefList& attList = curElem.getAttDefList();
+                while (attList.hasMoreElements())
+                {
+                    const XMLAttDef& curAttDef = attList.nextElement();
+                    cout << "    Name:" << StrX(curAttDef.getFullName())
+                         << ", Type: ";
+
+                    // Get the type and display it
+                    const XMLAttDef::AttTypes type = curAttDef.getType();
+                    switch(type)
+                    {
+                        case XMLAttDef::CData :
+                            cout << "CDATA";
+                            break;
+
+                        case XMLAttDef::ID :
+                            cout << "ID";
+                            break;
+
+                        case XMLAttDef::IDRef :
+                        case XMLAttDef::IDRefs :
+                            cout << "IDREF(S)";
+                            break;
+
+                        case XMLAttDef::Entity :
+                        case XMLAttDef::Entities :
+                            cout << "ENTITY(IES)";
+                            break;
+
+                        case XMLAttDef::NmToken :
+                        case XMLAttDef::NmTokens :
+                            cout << "NMTOKEN(S)";
+                            break;
+
+                        case XMLAttDef::Notation :
+                            cout << "NOTATION";
+                            break;
+
+                        case XMLAttDef::Enumeration :
+                            cout << "ENUMERATION";
+                            break;
+                    }
+
+                    cout << "\n";
+                }
+            }
+            cout << endl;
+        }
+    }
+     else
+    {
+        cout << "The validator has no elements to display\n" << endl;
+    }
+    return 0;
+}
+
+
+// ---------------------------------------------------------------------------
+//  Local helper methods
+// ---------------------------------------------------------------------------
+static void usage()
+{
+    cout << "\nUsage:\n"
+         "    EnumVal [-v] <XML file>\n"
+         "    -v  Do a validating parse. Defaults to non-validating.\n"
+         "This program parses a file, then shows how to enumerate the"
+         "contents of the validator pools\n" << endl;
+}
+
+
+// ---------------------------------------------------------------------------
+//  StrX: Private helper methods
+// ---------------------------------------------------------------------------
+void StrX::transcode(const XMLCh* const toTranscode, const unsigned int len)
+{
+    // Short circuit if its a null pointer
+    if (!toTranscode)
+    {
+        fLocalForm = new char[1];
+        fLocalForm[0] = 0;
+        return;
+	}
+
+    // See if our XMLCh and wchar_t as the same on this platform
+    const bool isSameSize = (sizeof(XMLCh) == sizeof(wchar_t));
+
+    //
+    //  Get the actual number of chars. If the passed len is zero, its null
+    //  terminated. Else we have to use the len.
+    //
+    wchar_t realLen = (wchar_t)len;
+    if (!realLen)
+    {
+        //
+        //  We cannot just assume we can use wcslen() because we don't know
+        //  if our XMLCh is the same as wchar_t on this platform.
+        //
+        const XMLCh* tmpPtr = toTranscode;
+        while (*(tmpPtr++))
+            realLen++;
+    }
+
+    //
+    //  If either the passed length was non-zero or our char sizes are not 
+    //  same, we have to use a temp buffer. Since this is common in these
+    //  samples, we just do it anyway.
+    //
+    wchar_t* tmpSource = new wchar_t[realLen + 1];
+    if (isSameSize)
+    {
+        memcpy(tmpSource, toTranscode, realLen * sizeof(wchar_t));
+    }
+     else
+    {
+        for (unsigned int index = 0; index < realLen; index++)
+            tmpSource[index] = (wchar_t)toTranscode[index];
+    }
+    tmpSource[realLen] = 0;
+
+    // See now many chars we need to transcode this guy
+    const unsigned int targetLen = ::wcstombs(0, tmpSource, 0);
+
+    // Allocate out storage member
+    fLocalForm = new char[targetLen + 1];
+
+    //
+    //  And transcode our temp source buffer to the local buffer. Cap it
+    //  off since the converter won't do it (because the null is beyond
+    //  where the target will fill up.)
+    //
+    ::wcstombs(fLocalForm, tmpSource, targetLen);
+    fLocalForm[targetLen] = 0;
+
+    // Don't forget to delete our temp buffer
+    delete [] tmpSource;
+}
-- 
GitLab