diff --git a/src/internal/ReaderMgr.cpp b/src/internal/ReaderMgr.cpp index 50ba1ae97585e4b8dd06cea88f054ca11fb99096..ea5caf8c926e7e6bb047c413b4d5f0b2b44f357f 100644 --- a/src/internal/ReaderMgr.cpp +++ b/src/internal/ReaderMgr.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.3 2000/01/12 00:15:03 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.2 1999/12/18 00:20:00 roddey * More changes to support the new, completely orthagonal, support for * intrinsic encodings. @@ -85,14 +89,14 @@ #include <util/URL.hpp> #include <util/XMLUni.hpp> #include <sax/InputSource.hpp> +#include <framework/LocalFileInputSource.hpp> +#include <framework/URLInputSource.hpp> #include <framework/XMLBuffer.hpp> #include <framework/XMLDocumentHandler.hpp> #include <framework/XMLEntityDecl.hpp> #include <framework/XMLEntityHandler.hpp> #include <internal/EndOfEntityException.hpp> #include <internal/ReaderMgr.hpp> -#include <internal/URLInputSource.hpp> - // --------------------------------------------------------------------------- @@ -100,8 +104,7 @@ // --------------------------------------------------------------------------- ReaderMgr::ReaderMgr() : - fBasePath(0) - , fCurEntity(0) + fCurEntity(0) , fCurReader(0) , fEntityHandler(0) , fEntityStack(0) @@ -119,7 +122,6 @@ ReaderMgr::~ReaderMgr() // does not own its elements either, so deleting it will not delete the // entities it still references!) // - delete [] fBasePath; delete fCurReader; delete fReaderStack; delete fEntityStack; @@ -520,8 +522,8 @@ XMLReader* ReaderMgr::createReader( const XMLCh* const sysId XMLBuffer expSysId; // - // Allow the entity handler to expand the system id. If we don't - // have one, or they don't do anything, then just use it as is. + // Allow the entity handler to expand the system id if they choose + // to do so. // if (fEntityHandler) { @@ -530,37 +532,7 @@ XMLReader* ReaderMgr::createReader( const XMLCh* const sysId } else { - // - // Try to parse it as a URL. If it succeeds, it must be a - // fully qualified path. Otherwise, its just a file name and - // could be partial so check and append it to the base path - // if so. - // - URL tmpURL; - try - { - tmpURL.setURL(sysId); - expSysId.set(tmpURL.getPath()); - } - - catch(const MalformedURLException&) - { - // Its just a file path - if (XMLPlatformUtils::isRelative(sysId)) - { - // Its relative so first store the base directory, if any - if (fBasePath) - expSysId.set(fBasePath); - - // And then append the relative path - expSysId.append(sysId); - } - else - { - // The path is not relative, so just set it directly - expSysId.set(sysId); - } - } + expSysId.set(sysId); } // Call the entity resolver interface to get an input source @@ -574,9 +546,31 @@ XMLReader* ReaderMgr::createReader( const XMLCh* const sysId ); } - // If they didn't give us anything, then make up a URL input source + // + // If they didn't create a source via the entity resolver, then we + // have to create one on our own. + // if (!srcToFill) - srcToFill = new URLInputSource(expSysId.getRawBuffer()); + { + LastExtEntityInfo lastInfo; + getLastExtEntityInfo(lastInfo); + + try + { + URL urlTmp(lastInfo.systemId, expSysId.getRawBuffer()); + srcToFill = new URLInputSource(urlTmp); + } + + catch(const MalformedURLException&) + { + // Its not a URL, so lets assume its a local file name. + srcToFill = new LocalFileInputSource + ( + lastInfo.systemId + , expSysId.getRawBuffer() + ); + } + } // Put a janitor on the input source Janitor<InputSource> janSrc(srcToFill); @@ -601,10 +595,7 @@ XMLReader* ReaderMgr::createReader( const XMLCh* const sysId if (!retVal) return 0; - // - // Give this reader the next available reader number. And let the input - // source live to be returned to the caller. - // + // Give this reader the next available reader number and return it retVal->setReaderNum(fNextReaderNum++); return retVal; } @@ -794,10 +785,6 @@ void ReaderMgr::reset() // Reset all of the flags fThrowEOE = false; - // Delete the base path, which has to be reset each time - delete [] fBasePath; - fBasePath = 0; - // Delete the current reader and flush the reader stack delete fCurReader; fCurReader = 0; diff --git a/src/internal/ReaderMgr.hpp b/src/internal/ReaderMgr.hpp index 098b90839bd6478570bf180fed1e350b3313a0e6..eab81e6eddbc317ccc5b9a5eb8c2d3324b01dbb7 100644 --- a/src/internal/ReaderMgr.hpp +++ b/src/internal/ReaderMgr.hpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.3 2000/01/12 00:15:04 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.2 1999/12/15 19:48:03 roddey * Changed to use new split of transcoder interfaces into XML transcoders and * LCP transcoders, and implementation of intrinsic transcoders as pluggable @@ -212,7 +216,6 @@ public : // ----------------------------------------------------------------------- // Setter methods // ----------------------------------------------------------------------- - void setBasePath(const XMLCh* const path); void setEntityHandler(XMLEntityHandler* const newHandler); void setThrowEOE(const bool newValue); @@ -228,10 +231,6 @@ private : // ----------------------------------------------------------------------- // Private data members // - // fBasePath - // This is the base path from which all other relative references - // are based. Its passed on to us from the scanner. - // // fCurEntity // This is the current top of stack entity. We pull it off the stack // and store it here for efficiency. @@ -266,7 +265,6 @@ private : // of entities in the int/ext subsets, so it will turn this flag off // until it gets into the content usually. // ----------------------------------------------------------------------- - XMLCh* fBasePath; XMLEntityDecl* fCurEntity; XMLReader* fCurReader; XMLEntityHandler* fEntityHandler; @@ -357,12 +355,6 @@ inline void ReaderMgr::skipPastChar(const XMLCh toSkipPast) } } -inline void ReaderMgr::setBasePath(const XMLCh* const path) -{ - delete [] fBasePath; - fBasePath = XMLString::replicate(path); -} - inline void ReaderMgr::setEntityHandler(XMLEntityHandler* const newHandler) { fEntityHandler = newHandler; diff --git a/src/internal/XMLScanner.cpp b/src/internal/XMLScanner.cpp index 764bad5f81ce2d229d7ccca00a97ab0a72c689be..127ff259967a2df6a4cf273d3030a81daa660c9a 100644 --- a/src/internal/XMLScanner.cpp +++ b/src/internal/XMLScanner.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.5 2000/01/12 00:15:04 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.4 1999/12/08 00:15:06 roddey * Some small last minute fixes to get into the 3.0.1 build that is going to be * going out anyway for platform fixes. @@ -87,6 +91,7 @@ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- +#include <util/Janitor.hpp> #include <util/Mutexes.hpp> #include <util/PlatformUtils.hpp> #include <util/RefVectorOf.hpp> @@ -97,6 +102,8 @@ #include <util/XMLUni.hpp> #include <sax/InputSource.hpp> #include <sax/SAXException.hpp> +#include <framework/LocalFileInputSource.hpp> +#include <framework/URLInputSource.hpp> #include <framework/XMLDocumentHandler.hpp> #include <framework/XMLElementDecl.hpp> #include <framework/XMLErrorReporter.hpp> @@ -204,6 +211,52 @@ XMLScanner::~XMLScanner() // --------------------------------------------------------------------------- // XMLScanner: Main entry point to scan a document // --------------------------------------------------------------------------- +void XMLScanner::scanDocument( const XMLCh* const systemId + , const bool reuseValidator) +{ + // + // First we try to parse it as a URL. If that fails, we assume its + // a file and try it that way. + // + InputSource* srcToUse = 0; + try + { + // + // Create a temporary URL. Since this is the primary document, + // it has to be fully qualified. If not, then assume we are just + // mistaking a file for a URL. + // + URL tmpURL(systemId); + if (tmpURL.isRelative()) + ThrowXML(MalformedURLException, XML4CExcepts::URL_NoProtocolPresent); + srcToUse = new URLInputSource(tmpURL); + } + + catch(const MalformedURLException&) + { + srcToUse = new LocalFileInputSource(systemId); + } + + catch(...) + { + // Just rethrow this, since its not our problem + throw; + } + + Janitor<InputSource> janSrc(srcToUse); + scanDocument(*srcToUse, reuseValidator); +} + +void XMLScanner::scanDocument( const char* const systemId + , const bool reuseValidator) +{ + // We just delegate this to the XMLCh version after transcoding + XMLCh* tmpBuf = XMLString::transcode(systemId); + ArrayJanitor<XMLCh> janBuf(tmpBuf); + scanDocument(tmpBuf, reuseValidator); +} + + void XMLScanner::scanDocument(const InputSource& src, const bool reuseValidator) { // @@ -359,6 +412,45 @@ void XMLScanner::scanDocument(const InputSource& src, const bool reuseValidator) // returns false, then the scan of the prolog failed and the token is not // going to work on subsequent scanNext() calls. // +bool XMLScanner::scanFirst( const XMLCh* const systemId + , XMLPScanToken& toFill + , const bool reuseValidator) +{ + // + // First we try to parse it as a URL. If that fails, we assume its + // a file and try it that way. + // + InputSource* srcToUse = 0; + try + { + srcToUse = new URLInputSource(XMLUni::fgZeroLenString, systemId); + } + + catch(const MalformedURLException&) + { + srcToUse = new LocalFileInputSource(systemId); + } + + catch(...) + { + // Just rethrow this, since its not our problem + throw; + } + + Janitor<InputSource> janSrc(srcToUse); + return scanFirst(*srcToUse, toFill, reuseValidator); +} + +bool XMLScanner::scanFirst( const char* const systemId + , XMLPScanToken& toFill + , const bool reuseValidator) +{ + // We just delegate this to the XMLCh version after transcoding + XMLCh* tmpBuf = XMLString::transcode(systemId); + ArrayJanitor<XMLCh> janBuf(tmpBuf); + return scanFirst(tmpBuf, toFill, reuseValidator); +} + bool XMLScanner::scanFirst( const InputSource& src , XMLPScanToken& toFill , const bool reuseValidator) diff --git a/src/internal/XMLScanner.hpp b/src/internal/XMLScanner.hpp index eb829e68f223758d316c56ecfe11cf196261e6f8..bb314aff03d7f317c9e224b6b4965f6f06c28a14 100644 --- a/src/internal/XMLScanner.hpp +++ b/src/internal/XMLScanner.hpp @@ -56,8 +56,12 @@ /** * $Log$ - * Revision 1.1 1999/11/09 01:08:23 twl - * Initial revision + * Revision 1.2 2000/01/12 00:15:04 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:08:23 twl + * Initial checkin * * Revision 1.4 1999/11/08 20:44:52 rahul * Swat for adding in Product name and CVS comment log variable. @@ -232,12 +236,36 @@ public : const InputSource& src , const bool reuseValidator = false ); + void scanDocument + ( + const XMLCh* const systemId + , const bool reuseValidator = false + ); + void scanDocument + ( + const char* const systemId + , const bool reuseValidator = false + ); + bool scanFirst ( const InputSource& src , XMLPScanToken& toFill , const bool reuseValidator = false ); + bool scanFirst + ( + const XMLCh* const systemId + , XMLPScanToken& toFill + , const bool reuseValidator = false + ); + bool scanFirst + ( + const char* const systemId + , XMLPScanToken& toFill + , const bool reuseValidator = false + ); + bool scanNext(XMLPScanToken& toFill); diff --git a/src/internal/XMLScanner2.cpp b/src/internal/XMLScanner2.cpp index a92136a4beeb74660a6e75eb295bf839e9346507..b2926d8a43e11c7d97901ff08ab9b6fd07a54acf 100644 --- a/src/internal/XMLScanner2.cpp +++ b/src/internal/XMLScanner2.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.4 2000/01/12 00:15:04 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.3 1999/12/18 00:20:24 roddey * Fixed a small reported memory leak * @@ -104,7 +108,7 @@ #include <framework/XMLValidator.hpp> #include <internal/XMLScanner.hpp> #include <internal/EndOfEntityException.hpp> -#include <internal/URLInputSource.hpp> + // --------------------------------------------------------------------------- @@ -752,41 +756,6 @@ void XMLScanner::scanReset(const InputSource& src) // Push this read onto the reader manager fReaderMgr.pushReader(newReader, 0); - - // - // We know that the file is legal now, so lets get the base directory - // off of it and store it. If there is no directory component on the - // path, then this returns a null. - // - // We have to assume it could be a URL so we create a temporary URL - // and ask it for the path part of itself. That will insure that if its - // relative we really see it as a relative path. - // - URL tmpURL; - - try - { - tmpURL.setURL(src.getSystemId()); - - // - // Its a valid URL so its assumed to be fully qualified. Get the - // base part of the path part of the URL. - // - XMLCh* basePath = XMLPlatformUtils::getBasePath(tmpURL.getPath()); - ArrayJanitor<XMLCh> pathJan(basePath); - fReaderMgr.setBasePath(basePath); - } - - catch(const MalformedURLException&) - { - // - // Its not a URL, so assume its just a plain file path and could - // be partial, so get the complete path. - // - XMLCh* basePath = XMLPlatformUtils::getBasePath(src.getSystemId()); - ArrayJanitor<XMLCh> pathJan(basePath); - fReaderMgr.setBasePath(basePath); - } } diff --git a/src/parsers/DOMParser.cpp b/src/parsers/DOMParser.cpp index 669ec83c3f16859028fb32cb7bf0aebc1869e626..758005573a8ffdfca1b6dbe81c18f959c657c9d3 100644 --- a/src/parsers/DOMParser.cpp +++ b/src/parsers/DOMParser.cpp @@ -61,6 +61,10 @@ * are created and added to the DOM tree. * * $Log$ + * Revision 1.3 2000/01/12 00:15:22 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.2 2000/01/05 01:16:11 andyh * DOM Level 2 core, namespace support added. * @@ -82,7 +86,6 @@ #include <sax/SAXParseException.hpp> #include <framework/XMLNotationDecl.hpp> #include <util/IOException.hpp> -#include <internal/URLInputSource.hpp> #include <internal/XMLScanner.hpp> #include <validators/DTD/DTDValidator.hpp> #include <parsers/DOMParser.hpp> @@ -210,29 +213,51 @@ void DOMParser::parse(const InputSource& source, const bool reuseValidator) fParseInProgress = false; } - catch(const SAXException&) + catch(...) { fParseInProgress = false; throw; } +} + +void DOMParser::parse(const XMLCh* const systemId, const bool reuseValidator) +{ + // Avoid multiple entrance + if (fParseInProgress) + ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); - catch(const XMLException&) + try + { + fParseInProgress = true; + fScanner->scanDocument(systemId, reuseValidator); + fParseInProgress = false; + } + + catch(...) { fParseInProgress = false; throw; } } -void DOMParser::parse(const XMLCh* const systemId, const bool reuseValidator) -{ - // Just call the URL input source version - parse(URLInputSource(systemId), reuseValidator); -} - void DOMParser::parse(const char* const systemId, const bool reuseValidator) { - // Just call the URL input source version - parse(URLInputSource(systemId), reuseValidator); + // Avoid multiple entrance + if (fParseInProgress) + ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); + + try + { + fParseInProgress = true; + fScanner->scanDocument(systemId, reuseValidator); + fParseInProgress = false; + } + + catch(...) + { + fParseInProgress = false; + throw; + } } @@ -244,16 +269,28 @@ bool DOMParser::parseFirst( const XMLCh* const systemId , XMLPScanToken& toFill , const bool reuseValidator) { - // Call the other version with a URL input source - return parseFirst(URLInputSource(systemId), toFill, reuseValidator); + // + // Avoid multiple entrance. We cannot enter here while a regular parse + // is in progress. + // + if (fParseInProgress) + ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); + + return fScanner->scanFirst(systemId, toFill, reuseValidator); } bool DOMParser::parseFirst( const char* const systemId , XMLPScanToken& toFill , const bool reuseValidator) { - // Call the other version with a URL input source - return parseFirst(URLInputSource(systemId), toFill, reuseValidator); + // + // Avoid multiple entrance. We cannot enter here while a regular parse + // is in progress. + // + if (fParseInProgress) + ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); + + return fScanner->scanFirst(systemId, toFill, reuseValidator); } bool DOMParser::parseFirst( const InputSource& source diff --git a/src/parsers/SAXParser.cpp b/src/parsers/SAXParser.cpp index c413d384276fb5756c559bdb411065fb9bad01d2..4b8720310e928c8a37b3876e43cc16b68617dc35 100644 --- a/src/parsers/SAXParser.cpp +++ b/src/parsers/SAXParser.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.3 2000/01/12 00:15:22 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.2 1999/12/15 19:57:48 roddey * Got rid of redundant 'const' on boolean return value. Some compilers choke * on this and its useless. @@ -78,7 +82,6 @@ #include <sax/ErrorHandler.hpp> #include <sax/EntityResolver.hpp> #include <sax/SAXParseException.hpp> -#include <internal/URLInputSource.hpp> #include <internal/XMLScanner.hpp> #include <parsers/SAXParser.hpp> #include <validators/DTD/DTDValidator.hpp> @@ -258,19 +261,13 @@ void SAXParser::parse(const InputSource& source, const bool reuseValidator) ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); try - { + { fParseInProgress = true; fScanner->scanDocument(source, reuseValidator); fParseInProgress = false; } - catch (const SAXException&) - { - fParseInProgress = false; - throw; - } - - catch (const XMLException&) + catch (...) { fParseInProgress = false; throw; @@ -279,18 +276,42 @@ void SAXParser::parse(const InputSource& source, const bool reuseValidator) void SAXParser::parse(const XMLCh* const systemId, const bool reuseValidator) { + // Avoid multiple entrance if (fParseInProgress) ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); - parse(URLInputSource(systemId), reuseValidator); + try + { + fParseInProgress = true; + fScanner->scanDocument(systemId, reuseValidator); + fParseInProgress = false; + } + + catch (...) + { + fParseInProgress = false; + throw; + } } void SAXParser::parse(const char* const systemId, const bool reuseValidator) { + // Avoid multiple entrance if (fParseInProgress) ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); - parse(URLInputSource(systemId), reuseValidator); + try + { + fParseInProgress = true; + fScanner->scanDocument(systemId, reuseValidator); + fParseInProgress = false; + } + + catch (...) + { + fParseInProgress = false; + throw; + } } void SAXParser::setDocumentHandler(DocumentHandler* const handler) @@ -365,16 +386,28 @@ bool SAXParser::parseFirst( const XMLCh* const systemId , XMLPScanToken& toFill , const bool reuseValidator) { - // Call the other version with a URL input source - return parseFirst(URLInputSource(systemId), toFill, reuseValidator); + // + // Avoid multiple entrance. We cannot enter here while a regular parse + // is in progress. + // + if (fParseInProgress) + ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); + + return fScanner->scanFirst(systemId, toFill, reuseValidator); } bool SAXParser::parseFirst( const char* const systemId , XMLPScanToken& toFill , const bool reuseValidator) { - // Call the other version with a URL input source - return parseFirst(URLInputSource(systemId), toFill, reuseValidator); + // + // Avoid multiple entrance. We cannot enter here while a regular parse + // is in progress. + // + if (fParseInProgress) + ThrowXML(IOException, XML4CExcepts::Gen_ParseInProgress); + + return fScanner->scanFirst(systemId, toFill, reuseValidator); } bool SAXParser::parseFirst( const InputSource& source diff --git a/src/sax/InputSource.cpp b/src/sax/InputSource.cpp index 7821f74fe8b1014d518d5f892d48e7f5896afb02..f9db9f8e2dc8420d5ca0872ac56a191677cbe57d 100644 --- a/src/sax/InputSource.cpp +++ b/src/sax/InputSource.cpp @@ -56,8 +56,12 @@ /** * $Log$ - * Revision 1.1 1999/11/09 01:07:45 twl - * Initial revision + * Revision 1.2 2000/01/12 00:15:39 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:07:45 twl + * Initial checkin * * Revision 1.2 1999/11/08 20:45:01 rahul * Swat for adding in Product name and CVS comment log variable. @@ -74,8 +78,52 @@ // --------------------------------------------------------------------------- -// InputSource: Constructors and Destructor +// InputSource: Destructor +// --------------------------------------------------------------------------- +InputSource::~InputSource() +{ + delete [] fEncoding; + delete [] fPublicId; + delete [] fSystemId; +} + + // --------------------------------------------------------------------------- +// InputSource: Setter methods +// --------------------------------------------------------------------------- +void InputSource::setEncoding(const XMLCh* const encodingStr) +{ + delete [] fEncoding; + fEncoding = XMLString::replicate(encodingStr); +} + + +void InputSource::setPublicId(const XMLCh* const publicId) +{ + delete [] fPublicId; + fPublicId = XMLString::replicate(publicId); +} + + +void InputSource::setSystemId(const XMLCh* const systemId) +{ + delete [] fSystemId; + fSystemId = XMLString::replicate(systemId); +} + + + +// --------------------------------------------------------------------------- +// InputSource: Hidden Constructors +// --------------------------------------------------------------------------- +InputSource::InputSource() : + + fEncoding(0) + , fPublicId(0) + , fSystemId(0) +{ +} + InputSource::InputSource(const XMLCh* const systemId) : fEncoding(0) @@ -109,34 +157,3 @@ InputSource::InputSource(const char* const systemId , fSystemId(XMLString::transcode(systemId)) { } - -InputSource::~InputSource() -{ - delete [] fEncoding; - delete [] fPublicId; - delete [] fSystemId; -} - - -// --------------------------------------------------------------------------- -// InputSource: Setter methods -// --------------------------------------------------------------------------- -void InputSource::setEncoding(const XMLCh* const encodingStr) -{ - delete [] fEncoding; - fEncoding = XMLString::replicate(encodingStr); -} - - -void InputSource::setPublicId(const XMLCh* const publicId) -{ - delete [] fPublicId; - fPublicId = XMLString::replicate(publicId); -} - - -void InputSource::setSystemId(const XMLCh* const systemId) -{ - delete [] fSystemId; - fSystemId = XMLString::replicate(systemId); -} diff --git a/src/sax/InputSource.hpp b/src/sax/InputSource.hpp index 1f504490b0a0d3beb3c4d9e7527fcea2dba0c5a4..4f3cc779872638cf8768db543c61dc370db5fb5d 100644 --- a/src/sax/InputSource.hpp +++ b/src/sax/InputSource.hpp @@ -56,8 +56,12 @@ /** * $Log$ - * Revision 1.1 1999/11/09 01:07:46 twl - * Initial revision + * Revision 1.2 2000/01/12 00:15:39 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:07:46 twl + * Initial checkin * * Revision 1.2 1999/11/08 20:45:01 rahul * Swat for adding in Product name and CVS comment log variable. @@ -101,8 +105,12 @@ class BinInputStream; * around beyond the call.</p> * * $Log$ - * Revision 1.1 1999/11/09 01:07:46 twl - * Initial revision + * Revision 1.2 2000/01/12 00:15:39 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:07:46 twl + * Initial checkin * * Revision 1.2 1999/11/08 20:45:01 rahul * Swat for adding in Product name and CVS comment log variable. @@ -230,6 +238,7 @@ protected : // ----------------------------------------------------------------------- // Hidden constructors // ----------------------------------------------------------------------- + InputSource(); InputSource(const XMLCh* const systemId); InputSource ( diff --git a/src/util/PlatformUtils.hpp b/src/util/PlatformUtils.hpp index 99977a5c5b6ad9c7ebca7d256b1a26fc1ba24428..46be8c764237b675c5a66282d98c7da2ce689923 100644 --- a/src/util/PlatformUtils.hpp +++ b/src/util/PlatformUtils.hpp @@ -56,8 +56,12 @@ /** * $Log$ - * Revision 1.1 1999/11/09 01:04:55 twl - * Initial revision + * Revision 1.2 2000/01/12 00:16:22 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:04:55 twl + * Initial checkin * * Revision 1.3 1999/11/08 20:45:11 rahul * Swat for adding in Product name and CVS comment log variable. @@ -185,8 +189,13 @@ public : // ----------------------------------------------------------------------- // File system methods // ----------------------------------------------------------------------- - static XMLCh* getBasePath(const XMLCh* const srcPath); + static XMLCh* getFullPath(const XMLCh* const srcPath); static bool isRelative(const XMLCh* const toCheck); + static XMLCh* weavePaths + ( + const XMLCh* const basePath + , const XMLCh* const relativePath + ); // ----------------------------------------------------------------------- diff --git a/src/util/Platforms/Win32/Win32PlatformUtils.cpp b/src/util/Platforms/Win32/Win32PlatformUtils.cpp index b4afa1fcf3f00af81bac090e8ad798af02a28063..0dcdbefd40fdef472ac75668ca2d324728adbf8f 100644 --- a/src/util/Platforms/Win32/Win32PlatformUtils.cpp +++ b/src/util/Platforms/Win32/Win32PlatformUtils.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.3 2000/01/12 00:16:47 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.2 1999/11/22 20:41:26 abagchi * Changed 'intlFiles/Locales' to 'icu/data' * @@ -450,7 +454,7 @@ void XMLPlatformUtils::writeToStdOut(const char* const toWrite) // --------------------------------------------------------------------------- // XMLPlatformUtils: File system methods // --------------------------------------------------------------------------- -XMLCh* XMLPlatformUtils::getBasePath(const XMLCh* const srcPath) +XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath) { // // NOTE: THe path provided has always already been opened successfully, @@ -470,10 +474,6 @@ XMLCh* XMLPlatformUtils::getBasePath(const XMLCh* const srcPath) if (!::GetFullPathNameW(srcPath, bufSize, tmpPath, &namePart)) return 0; - // Cap it off at the name part, leaving just the full path - if (namePart) - *namePart = 0; - // Return a copy of the path return XMLString::replicate(tmpPath); } @@ -491,10 +491,6 @@ XMLCh* XMLPlatformUtils::getBasePath(const XMLCh* const srcPath) if (!::GetFullPathNameA(tmpSrcPath, bufSize, tmpPath, &namePart)) return 0; - // Cap it off at the name part, leaving just the full path - if (namePart) - *namePart = 0; - // Return a transcoded copy of the path return XMLString::transcode(tmpPath); } @@ -533,6 +529,114 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck) } +XMLCh* XMLPlatformUtils::weavePaths(const XMLCh* const basePath + , const XMLCh* const relativePath) + +{ + // Create a buffer as large as both parts and empty it + XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath) + + XMLString::stringLen(relativePath) + + 2]; + *tmpBuf = 0; + + // + // If we have no base path, then just take the relative path as + // is. + // + if (!basePath) + { + XMLString::copyString(tmpBuf, relativePath); + return tmpBuf; + } + + if (!*basePath) + { + XMLString::copyString(tmpBuf, relativePath); + return tmpBuf; + } + + const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1); + if ((*basePtr != chForwardSlash) + && (*basePtr != chBackSlash)) + { + while ((basePtr >= basePath) + && ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash))) + { + basePtr--; + } + } + + // There is no relevant base path, so just take the relative part + if (basePtr < basePath) + { + XMLString::copyString(tmpBuf, relativePath); + return tmpBuf; + } + + // After this, make sure the buffer gets handled if we exit early + ArrayJanitor<XMLCh> janBuf(tmpBuf); + + // + // We have some path part, so we need to check to see if we ahve to + // weave any of the parts together. + // + const XMLCh* pathPtr = relativePath; + while (true) + { + // If it does not start with some period, then we are done + if (*pathPtr != chPeriod) + break; + + unsigned int periodCount = 1; + pathPtr++; + if (*pathPtr == chPeriod) + { + pathPtr++; + periodCount++; + } + + // Has to be followed by a \ or / or the null to mean anything + if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash) + && *pathPtr) + { + break; + } + if (*pathPtr) + pathPtr++; + + // If its one period, just eat it, else move backwards in the base + if (periodCount == 2) + { + basePtr--; + while ((basePtr >= basePath) + && ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash))) + { + basePtr--; + } + + if (basePtr < basePath) + { + // The base cannot provide enough levels, so its in error + // <TBD> + } + } + } + + // Copy the base part up to the base pointer + XMLCh* bufPtr = tmpBuf; + const XMLCh* tmpPtr = basePath; + while (tmpPtr <= basePtr) + *bufPtr++ = *tmpPtr++; + + // And then copy on the rest of our path + XMLString::copyString(bufPtr, pathPtr); + + // Orphan the buffer and return it + janBuf.orphan(); + return tmpBuf; +} + + // --------------------------------------------------------------------------- // XMLPlatformUtils: Timing Methods diff --git a/src/util/URL.cpp b/src/util/URL.cpp index 90a2bbd17c3170abc3e8c0f9d7432c47ad065fc7..00dcfdfaba79bb1c2adaa3982c02b0ee8074bd4f 100644 --- a/src/util/URL.cpp +++ b/src/util/URL.cpp @@ -56,8 +56,12 @@ /** * $Log$ - * Revision 1.1 1999/11/09 01:04:20 twl - * Initial revision + * Revision 1.2 2000/01/12 00:16:22 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:04:20 twl + * Initial checkin * * Revision 1.3 1999/11/08 20:45:16 rahul * Swat for adding in Product name and CVS comment log variable. @@ -72,7 +76,9 @@ #include <util/Janitor.hpp> #include <util/PlatformUtils.hpp> #include <util/RuntimeException.hpp> +#include <util/TransService.hpp> #include <util/URL.hpp> +#include <util/XMLNetAccessor.hpp> #include <util/XMLString.hpp> #include <util/XMLUni.hpp> @@ -89,7 +95,6 @@ struct TypeEntry { URL::Protocols protocol; const XMLCh* prefix; - bool supported; }; @@ -112,26 +117,17 @@ struct TypeEntry // --------------------------------------------------------------------------- static const XMLCh gFileString[] = { - chLatin_f, chLatin_i, chLatin_l, chLatin_e, chColon - , chForwardSlash, chForwardSlash, chNull + chLatin_f, chLatin_i, chLatin_l, chLatin_e, chNull }; static const XMLCh gFTPString[] = { - chLatin_f, chLatin_t, chLatin_p, chColon, chForwardSlash - , chForwardSlash, chNull -}; - -static const XMLCh gGopherString[] = -{ - chLatin_g, chLatin_o, chLatin_p, chLatin_h, chLatin_e - , chLatin_r, chColon, chForwardSlash, chForwardSlash, chNull + chLatin_f, chLatin_t, chLatin_p, chNull }; static const XMLCh gHTTPString[] = { - chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon - , chForwardSlash, chForwardSlash, chNull + chLatin_h, chLatin_t, chLatin_t, chLatin_p, chNull }; static const XMLCh gLocalHostString[] = @@ -140,60 +136,17 @@ static const XMLCh gLocalHostString[] = , chLatin_h, chLatin_o, chLatin_s, chLatin_t, chNull }; -static const XMLCh gMailToString[] = -{ - chLatin_m, chLatin_a, chLatin_i, chLatin_l, chLatin_t - , chLatin_o, chColon, chForwardSlash, chForwardSlash, chNull -}; - -static const XMLCh gNewsString[] = -{ - chLatin_n, chLatin_e, chLatin_w, chLatin_s, chColon - , chForwardSlash, chForwardSlash, chNull -}; - -static const XMLCh gNNTPString[] = -{ - chLatin_n, chLatin_n, chLatin_t, chLatin_p, chColon - , chForwardSlash, chForwardSlash, chNull -}; - -static const XMLCh gTelnetString[] = -{ - chLatin_t, chLatin_e, chLatin_l, chLatin_n, chLatin_e - , chLatin_t, chColon, chForwardSlash, chForwardSlash, chNull -}; - -static const XMLCh gWaisString[] = -{ - chLatin_w, chLatin_a, chLatin_i, chLatin_s, chColon - , chForwardSlash, chForwardSlash, chNull -}; - -static const XMLCh gProsperoString[] = -{ - chLatin_p, chLatin_r, chLatin_o, chLatin_s, chLatin_p - , chLatin_e, chLatin_r, chLatin_o, chColon, chForwardSlash - , chForwardSlash, chNull -}; - static TypeEntry gTypeList[URL::Protocols_Count] = { - { URL::File , gFileString , true } - , { URL::HTTP , gHTTPString , false } - , { URL::FTP , gFTPString , false } - , { URL::Gopher , gGopherString , false } - , { URL::MailTo , gMailToString , false } - , { URL::News , gNewsString , false } - , { URL::NNTP , gNNTPString , false } - , { URL::Telnet , gTelnetString , false } - , { URL::Wais , gWaisString , false } - , { URL::Prospero , gProsperoString , false } + { URL::File , gFileString } + , { URL::HTTP , gHTTPString } + , { URL::FTP , gFTPString } }; +static const unsigned int gTypeListSize = sizeof(gTypeList) / sizeof(gTypeList[0]); // !!! Keep these up to date with list above! -static const unsigned int gMaxProtoLen = 11; -static const unsigned int gMaxColonPos = gMaxProtoLen - 3; +static const unsigned int gMaxProtoLen = 4; + // --------------------------------------------------------------------------- @@ -223,24 +176,141 @@ static unsigned int xlatHexDigit(const XMLCh toXlat) +// --------------------------------------------------------------------------- +// URL: Public, static methods +// --------------------------------------------------------------------------- +URL::Protocols URL::lookupByName(const XMLCh* const protoName) +{ + for (unsigned int index = 0; index < gTypeListSize; index++) + { + if (!XMLString::compareIString(gTypeList[index].prefix, protoName)) + return gTypeList[index].protocol; + } + return URL::Unknown; +} + + + // --------------------------------------------------------------------------- // URL: Constructors and Destructor // --------------------------------------------------------------------------- URL::URL() : - fFullURL(0) + fFragment(0) , fHost(0) + , fPassword(0) , fPath(0) - , fProtocol(URL::File) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) { } +URL::URL(const XMLCh* const baseURL + , const XMLCh* const relativeURL) : + + fFragment(0) + , fHost(0) + , fPassword(0) + , fPath(0) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) +{ + setURL(baseURL, relativeURL); +} + +URL::URL(const XMLCh* const baseURL + , const char* const relativeURL) : + + fFragment(0) + , fHost(0) + , fPassword(0) + , fPath(0) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) +{ + XMLCh* tmpRel = XMLString::transcode(relativeURL); + ArrayJanitor<XMLCh> janRel(tmpRel); + setURL(baseURL, tmpRel); +} + +URL::URL(const URL& baseURL + , const XMLCh* const relativeURL) : + + fFragment(0) + , fHost(0) + , fPassword(0) + , fPath(0) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) +{ + setURL(baseURL, relativeURL); +} + +URL::URL(const URL& baseURL + , const char* const relativeURL) : + + fFragment(0) + , fHost(0) + , fPassword(0) + , fPath(0) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) +{ + XMLCh* tmpRel = XMLString::transcode(relativeURL); + ArrayJanitor<XMLCh> janRel(tmpRel); + setURL(baseURL, tmpRel); +} + +URL::URL(const XMLCh* const urlText) : + + fFragment(0) + , fHost(0) + , fPassword(0) + , fPath(0) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) +{ + setURL(urlText); +} + +URL::URL(const char* const urlText) : + + fFragment(0) + , fHost(0) + , fPassword(0) + , fPath(0) + , fProtocol(URL::Unknown) + , fQuery(0) + , fUser(0) + , fURLText(0) +{ + XMLCh* tmpText = XMLString::transcode(urlText); + ArrayJanitor<XMLCh> janRel(tmpText); + setURL(tmpText); +} + URL::URL(const URL& toCopy) : - fFullURL(XMLString::replicate(toCopy.fFullURL)) + fFragment(XMLString::replicate(toCopy.fFragment)) , fHost(XMLString::replicate(toCopy.fHost)) + , fPassword(XMLString::replicate(toCopy.fPassword)) , fPath(XMLString::replicate(toCopy.fPath)) , fProtocol(toCopy.fProtocol) + , fQuery(XMLString::replicate(toCopy.fQuery)) + , fUser(XMLString::replicate(toCopy.fUser)) + , fURLText(XMLString::replicate(toCopy.fURLText)) { } @@ -262,29 +332,26 @@ URL& URL::operator=(const URL& toAssign) cleanup(); // And copy his stuff - fFullURL = XMLString::replicate(toAssign.fFullURL); + fFragment = XMLString::replicate(toAssign.fFragment); fHost = XMLString::replicate(toAssign.fHost); + fPassword = XMLString::replicate(toAssign.fPassword); fPath = XMLString::replicate(toAssign.fPath); fProtocol = toAssign.fProtocol; + fQuery = XMLString::replicate(toAssign.fQuery); + fUser = XMLString::replicate(toAssign.fUser); + fURLText = XMLString::replicate(toAssign.fURLText); return *this; } bool URL::operator==(const URL& toCompare) const { - // Test the obvious one first - if (fProtocol != toCompare.fProtocol) - return false; - // - // Oh well, we have to test the components. Don't test the original - // URLs, because normalization might have occured that would have made - // them equal even though actual text of the full URLs is not. + // Compare the two complete URLs (which have been processed the same + // way so they should now be the same even if they came in via different + // relative parts. // - if (XMLString::compareString(fPath, toCompare.fPath)) - return false; - - if (XMLString::compareString(fHost, toCompare.fHost)) + if (XMLString::compareString(getURLText(), toCompare.getURLText())) return false; return true; @@ -295,8 +362,12 @@ bool URL::operator==(const URL& toCompare) const // --------------------------------------------------------------------------- // URL: Getter methods // --------------------------------------------------------------------------- -const XMLCh* URL::getProtocol() const +const XMLCh* URL::getProtocolName() const { + // Check to see if its ever been set + if (fProtocol == Unknown) + ThrowXML(MalformedURLException, XML4CExcepts::URL_NoProtocolPresent); + return gTypeList[fProtocol].prefix; } @@ -306,10 +377,14 @@ const XMLCh* URL::getProtocol() const // --------------------------------------------------------------------------- void URL::setURL(const XMLCh* const urlText) { - fFullURL = XMLString::replicate(urlText); + // + // Try to parse the URL. If this fails, we just give up, cleanup and + // rethrow out of here. + // + cleanup(); try { - parse(); + parse(urlText); } catch(...) @@ -319,13 +394,27 @@ void URL::setURL(const XMLCh* const urlText) } } -void URL::setURL(const char* const urlText) +void URL::setURL(const XMLCh* const baseURL + , const XMLCh* const relativeURL) { - // Transcode the passed string to Unicode - fFullURL = XMLString::transcode(urlText); + cleanup(); try { - parse(); + // Parse our URL string + parse(relativeURL); + + // + // If its relative and the base is non-null and non-empty, then + // parse the base URL string and conglomerate them. + // + if (isRelative() && baseURL) + { + if (*baseURL) + { + URL basePart(baseURL); + conglomerateWithBase(basePart); + } + } } catch(...) @@ -335,293 +424,655 @@ void URL::setURL(const char* const urlText) } } +void URL::setURL(const URL& baseURL + , const XMLCh* const relativeURL) +{ + cleanup(); + try + { + // Parse our URL string + parse(relativeURL); + + // If its relative, then conglomerate with the base URL + if (isRelative()) + conglomerateWithBase(baseURL); + } + + catch(...) + { + cleanup(); + throw; + } +} // --------------------------------------------------------------------------- // URL: Miscellaneous methods // --------------------------------------------------------------------------- +bool URL::isRelative() const +{ + // If no protocol then relative + if (fProtocol == Unknown) + return true; + + // If no path, or the path is not absolute, then relative + if (!fPath) + return true; + + if (*fPath != chForwardSlash) + return true; + + return false; +} + + BinInputStream* URL::makeNewStream() const { - switch(fProtocol) + // + // If its a local host, then we short circuit it and use our own file + // stream support. Otherwise, we just let it fall through and let the + // installed network access object provide a stream. + // + if (fProtocol == URL::File) { - case URL::File : + if (!fHost || !XMLString::compareIString(fHost, L"localhost")) { - BinFileInputStream* retStrm = new BinFileInputStream(getPath()); + // + // We have to play a little trick here. If its really a Windows + // style fully qualified path, we have to toss the leading / + // character. + // + const XMLCh* realPath = fPath; + if (*fPath == chForwardSlash) + { + if (XMLString::stringLen(fPath) > 3) + { + if (*(fPath + 2) == chColon) + { + const XMLCh chDrive = *(fPath + 1); + if (((chDrive >= chLatin_A) && (chDrive <= chLatin_Z)) + || ((chDrive >= chLatin_a) && (chDrive <= chLatin_z))) + { + realPath = fPath + 3; + } + } + } + } + + BinFileInputStream* retStrm = new BinFileInputStream(realPath); if (!retStrm->getIsOpen()) { delete retStrm; return 0; } return retStrm; - break; } - - default : - ThrowXML(MalformedURLException, XML4CExcepts::URL_UnsupportedProto); - break; } - return 0; + + // + // If we don't have have an installed net accessor object, then we + // have to just throw here. + // + if (!XMLPlatformUtils::fgNetAccessor) + ThrowXML(MalformedURLException, XML4CExcepts::URL_UnsupportedProto); + + // Else ask the net accessor to create the stream + return XMLPlatformUtils::fgNetAccessor->makeNew(*this); +} + +void URL::makeRelativeTo(const XMLCh* const baseURLText) +{ + // If this one is not relative, don't bother + if (!isRelative()) + return; + + URL baseURL(baseURLText); + conglomerateWithBase(baseURL); } +void URL::makeRelativeTo(const URL& baseURL) +{ + // If this one is not relative, don't bother + if (!isRelative()) + return; + conglomerateWithBase(baseURL); +} + + + // --------------------------------------------------------------------------- // URL: Private helper methods // --------------------------------------------------------------------------- +// +// This method will take the broken out parts of the URL and build up the +// full text. We don't do this unless someone asks us to, since its often +// never required. +// +void URL::buildFullText() +{ + // Calculate the worst case size of the buffer required + unsigned int bufSize = gMaxProtoLen + 1 + + XMLString::stringLen(fFragment) + 1 + + XMLString::stringLen(fHost) + 2 + + XMLString::stringLen(fPassword) + 1 + + XMLString::stringLen(fPath) + + XMLString::stringLen(fQuery) + 1 + + XMLString::stringLen(fUser) + 1 + + 16; + + // Clean up the existing buffer and allocate another + delete [] fURLText; + fURLText = new XMLCh[bufSize]; + *fURLText = 0; + + XMLCh* outPtr = fURLText; + if (fProtocol != Unknown) + { + XMLString::catString(fURLText, getProtocolName()); + outPtr += XMLString::stringLen(fURLText); + *outPtr++ = chColon; + *outPtr++ = chForwardSlash; + *outPtr++ = chForwardSlash; + } + + if (fHost) + { + XMLString::copyString(outPtr, fHost); + outPtr += XMLString::stringLen(fHost); + + if (fUser) + { + *outPtr++ = chAt; + XMLString::copyString(outPtr, fUser); + outPtr += XMLString::stringLen(fUser); + + if (fPassword) + { + *outPtr++ = chColon; + XMLString::copyString(outPtr, fPassword); + outPtr += XMLString::stringLen(fPassword); + } + } + } + + if (fPath) + { + XMLString::copyString(outPtr, fPath); + outPtr += XMLString::stringLen(fPath); + } + + if (fQuery) + { + *outPtr++ = chQuestion; + XMLString::copyString(outPtr, fQuery); + outPtr += XMLString::stringLen(fQuery); + } + + if (fFragment) + { + *outPtr++ = chPound; + XMLString::copyString(outPtr, fFragment); + outPtr += XMLString::stringLen(fFragment); + } +} + + // // Just a central place to handle cleanup, since its done from a number // of different spots. // void URL::cleanup() { - delete [] fFullURL; - fFullURL = 0; + delete [] fFragment; delete [] fHost; - fHost = 0; + delete [] fPassword; delete [] fPath; + delete [] fQuery; + delete [] fUser; + delete [] fURLText; + + fFragment = 0; + fHost = 0; + fPassword = 0; fPath = 0; + fQuery = 0; + fUser = 0; + fURLText = 0; + + fProtocol = Unknown; } -// -// This method searches our list of protocols and sees if the passed text -// starts with one of them. The prefix is the whole thing up to the second -// forward slash. The length of the text is passed so that obvious failures -// can be found quickly. -// -URL::Protocols URL::findType(unsigned int& curPos) const +void URL::conglomerateWithBase(const URL& baseURL) { - XMLCh tmpStr[gMaxProtoLen+1]; + // The base URL cannot be relative + if (baseURL.isRelative()) + { + // <TBD> Add an error for this + // ThrowXML(MalformedURLException, XML4CExcepts::URL_BaseWasRelative); + } // - // Remember the current position so we can do exploratory reads from - // the URL. Then look forward for a colon. + // Check a special case. If all we have is a fragment, then we want + // to just take the base host and path, plus our fragment. // - const unsigned int orgPos = curPos; - unsigned int tmpPos = curPos; - unsigned int tmpIndex = 0; - while (true) + if ((fProtocol == Unknown) + && !fHost + && !fPath + && fFragment) { - // Get another char from the source URL. Indicate end of text is ok - const XMLCh nextCh = getNextCh(tmpPos, true); - - // If we hit the end, then no good - if (!nextCh) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); - - // Store this new character - tmpStr[tmpIndex++] = nextCh; - - // If we hit the colon, break out - if (nextCh == chColon) - break; - - // If we exceed the max colon pos without finding a colon, then no good - if (tmpIndex > gMaxColonPos) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); + fProtocol = baseURL.fProtocol; + fHost = XMLString::replicate(baseURL.fHost); + fUser = XMLString::replicate(baseURL.fUser); + fPassword = XMLString::replicate(baseURL.fPassword); + fPath = XMLString::replicate(baseURL.fPath); + return; } // - // See if the next two chars are forward slashes, If not, then undo - // our read and return local. Else store them and compare against - // the list. Indicate that end of input is ok here. + // All we have to do is run up through our fields and, for each one + // that we don't have, use the based URL's. Once we hit one field + // that we have, we stop. // - const bool gotSlashes = (getNextCh(tmpPos, true) == chForwardSlash) - && (getNextCh(tmpPos, true) == chForwardSlash); - if (!gotSlashes) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); + if (fProtocol != Unknown) + return; + fProtocol = baseURL.fProtocol; + + if (fHost || !baseURL.fHost) + return; + fHost = XMLString::replicate(baseURL.fHost); + if (baseURL.fUser) + fUser = XMLString::replicate(baseURL.fUser); + if (baseURL.fPassword) + fPassword = XMLString::replicate(baseURL.fPassword); + + // If we have a path and its absolute, then we are done + const bool hadPath = (fPath != 0); + if (hadPath) + { + if (*fPath == chForwardSlash) + return; + } - // Store the slashes in our temp string too - tmpStr[tmpIndex++] = chForwardSlash; - tmpStr[tmpIndex++] = chForwardSlash; + // Its a relative path, so weave them together. + if (baseURL.fPath) + weavePaths(baseURL.fPath); - // Update the caller's position and cap off our string - curPos = tmpPos; - tmpStr[tmpIndex] = chNull; + // If we had any original path, then we are done + if (hadPath) + return; - // - // Ok, lets see if tmpStr matches any of the prefixes in our list of - // protocols. - // - for (unsigned int index = 0; index < Protocols_Count; index++) - { - if (!XMLString::compareString(tmpStr, gTypeList[index].prefix)) - return gTypeList[index].protocol; - } + if (fQuery || !baseURL.fQuery) + return; + fQuery = XMLString::replicate(baseURL.fQuery); - // Cannot be a supported URL protocol - ThrowXML(MalformedURLException, XML4CExcepts::URL_UnsupportedProto); + if (fFragment || !baseURL.fFragment) + return; + fFragment = XMLString::replicate(baseURL.fFragment); } -// -// This method is used during the parse. It gets the next character out of -// the source URL (in fFullURL, which is a copy of the original text) and -// returns it. It updates the passed position with the new position. -// -// The primary job of this method is to handle escaped characters, by reading -// them in and converting them to a Unicode char. -// -XMLCh URL::getNextCh(unsigned int& pos, const bool endOk) const +void URL::parse(const XMLCh* const urlText) { + // Simplify things by checking for the psycho scenarios first + if (!*urlText) + ThrowXML(MalformedURLException, XML4CExcepts::URL_NoProtocolPresent); + // - // If we are at the end of the URL, then either return a zero or - // throw if end of URL is not legal here. + // The first thing we will do is to check for a file name, so that + // we don't waste time thinking its a URL. If its in the form x:\ + // or x:/ and x is an ASCII letter, then assume that's the deal. // - if (!fFullURL[pos]) + if (((*urlText >= chLatin_A) && (*urlText <= chLatin_Z)) + || ((*urlText >= chLatin_a) && (*urlText <= chLatin_z))) { - if (!endOk) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); - return chNull; + if (*(urlText + 1) == chColon) + { + if (((*urlText + 2) == chForwardSlash) + || ((*urlText + 2) == chBackSlash)) + { + ThrowXML(MalformedURLException, XML4CExcepts::URL_NoProtocolPresent); + } + } } + // Get a copy of the URL that we can modify + XMLCh* srcCpy = XMLString::replicate(urlText); + ArrayJanitor<XMLCh> janSrcCopy(srcCpy); + // - // See if the current character is a '%'. If so, then we need to - // deal with an escaped character. + // Get a pointer now that we can run up thrown the source as we parse + // bits and pieces out of it. // - if (fFullURL[pos] == chPercent) - { - XMLCh escapedChar = 0; + XMLCh* srcPtr = srcCpy; - // There must be at least two more characters - if (!fFullURL[pos+1] || !fFullURL[pos+2]) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); - - // Get them out and test them - const XMLCh test1 = fFullURL[pos+1]; - const XMLCh test2 = fFullURL[pos+2]; + // Run up past any spaces + while (*srcPtr) + { + if (!XMLPlatformUtils::fgTransService->isSpace(*srcPtr)) + break; + } - if (!isHexDigit(test1) || !isHexDigit(test2)) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); + // Make sure it wasn't all space + if (!*srcPtr) + ThrowXML(MalformedURLException, XML4CExcepts::URL_NoProtocolPresent); - // Convert these to a character - escapedChar = XMLCh((xlatHexDigit(test1) << 4) + xlatHexDigit(test2)); + // + // Ok, the next thing we have to do is to find either a / or : character. + // If the : is first, we assume we have a protocol. If the / is first, + // then we skip to the host processing. + // + static const XMLCh listOne[] = { chColon, chForwardSlash, chNull }; + static const XMLCh listTwo[] = { chAt, chForwardSlash, chNull }; + static const XMLCh listThree[] = { chColon, chForwardSlash, chNull }; + static const XMLCh listFour[] = { chForwardSlash, chNull }; + static const XMLCh listFive[] = { chPound, chQuestion, chNull }; + static const XMLCh listSix[] = { chPound, chNull }; + XMLCh* ptr1 = XMLString::findAny(srcPtr, listOne); + XMLCh* ptr2; + + // If we found a protocol, then deal with it + if (ptr1) + { + if (*ptr1 == chColon) + { + // Cap the string at the colon + *ptr1 = 0; - // Bump the position up - pos += 3; + // And try to find it in our list of protocols + fProtocol = lookupByName(srcPtr); - return escapedChar; + if (fProtocol == Unknown) + { + ThrowXML1 + ( + MalformedURLException + , XML4CExcepts::URL_UnsupportedProto1 + , srcPtr + ); + } + + // And move our source pointer up past what we've processed + srcPtr = (ptr1 + 1); + } } - // Else just return the current char and bump the position - return fFullURL[pos++]; -} - - -// -// This method is called to parse the text into its components and validate -// that the URL is legal. It uses getNextCh() to pull characters out of the -// URL. -// -void URL::parse() -{ - // This is the current position that we track during the parse - unsigned int curPos = 0; - XMLCh nextCh; - const unsigned int bufSize = 2047; - XMLCh tmpBuf[bufSize + 1]; - unsigned int bufIndex; + // + // Ok, next we need to see if we have any host part. If the next + // two characters are //, then we need to check, else move on. + // + if ((*srcPtr == chForwardSlash) && (*(srcPtr + 1) == chForwardSlash)) + { + // Move up past the slashes + srcPtr += 2; + + // + // If we aren't at the end of the string, then there has to be a + // host name at this point. + // + if (*srcPtr) + { + // Search from here for either a @ or / character + ptr1 = XMLString::findAny(srcPtr, listTwo); + + // + // If we found something, then the host is between where + // we are and what we found. Else the host is the rest of + // the content and we are done. If its empty, leave it null. + // + if (ptr1) + { + if (ptr1 != srcPtr) + { + fHost = new XMLCh[(ptr1 - srcPtr) + 1]; + ptr2 = fHost; + while (srcPtr < ptr1) + *ptr2++ = *srcPtr++; + *ptr2 = 0; + } + + // + // If we found a @, then we have to parse out a user name + // and optional password. + // + if (*srcPtr == chAt) + { + // Move up past the @ and look for a / or : character + srcPtr++; + ptr1 = XMLString::findAny(srcPtr, listThree); + + // + // If we found something, then the user name is between + // where we are and what we found. Else the user name + // is the rest of the string and we are done. + // + if (ptr1) + { + fUser = new XMLCh[(ptr1 - srcPtr) + 1]; + ptr2 = fUser; + while (srcPtr < ptr1) + *ptr2++ = *srcPtr++; + *ptr2 = 0; + + // + // If we found a : character, then everything from + // after that to the end or a / character is the + // password. + // + if (*srcPtr == chColon) + { + srcPtr++; + ptr1 = XMLString::findAny(srcPtr, listFour); + + // + // If we found one, then the password is everything + // from where we are to there. Else, the password + // is the rest of the string. + // + if (ptr1) + { + fPassword = new XMLCh[(ptr1 - srcPtr) + 1]; + ptr2 = fPassword; + while (srcPtr < ptr1) + *ptr2++ = *srcPtr++; + *ptr2 = 0; + } + else + { + fPassword = XMLString::replicate(srcPtr); + return; + } + } + } + else + { + fUser = XMLString::replicate(srcPtr); + return; + } + } + } + else + { + fHost = XMLString::replicate(srcPtr); + return; + } + } + } // - // Search the text for a prefix. We will get back the type of the prefix - // and the current position will be updated. + // Next is the path part. It can be absolute, i.e. starting with a + // forward slash character, or relative. Its basically everything up + // to the end of the string or to any trailing query or fragment. // - fProtocol = findType(curPos); + ptr1 = XMLString::findAny(srcPtr, listFive); + if (!ptr1) + { + fPath = XMLString::replicate(srcPtr); + return; + } + + // Everything from where we are to what we found is the path + if (ptr1 > srcPtr) + { + fPath = new XMLCh[(ptr1 - srcPtr) + 1]; + ptr2 = fPath; + while (srcPtr < ptr1) + *ptr2++ = *srcPtr++; + *ptr2 = 0; + } - // In order to distinguish between a malformed URL and an unsupported - // URL, we watch here for the types that we support. If its not supported - // we throw a runtime exception. // - if (!gTypeList[fProtocol].supported) - ThrowXML(MalformedURLException, XML4CExcepts::URL_UnsupportedProto); + // If we found a fragment, then it is the rest of the string and we + // are done. + // + if (*srcPtr == chPound) + { + srcPtr++; + fFragment = XMLString::replicate(srcPtr); + return; + } // - // Check the next char. It must be either a forward slash or it will - // be the first char of the host name. We don't allow end of input - // here so it will cause an exception if we hit it. + // The query is either the rest of the string, or up to the fragment + // separator. // - nextCh = getNextCh(curPos); - if (nextCh == chForwardSlash) + srcPtr++; + ptr1 = XMLString::findAny(srcPtr, listSix); + if (!ptr1) { - // There is no host so make an empty one - fHost = new XMLCh[1]; - fHost[0] = chNull; + fQuery = XMLString::replicate(srcPtr); + return; } else { - // Put in the lookahead char we did above before we enter the loop - bufIndex = 0; - tmpBuf[bufIndex++] = nextCh; - - // And now read up to the slash separator - while (true) - { - // Get the next char, end of input is not valid here - const XMLCh nextCh = getNextCh(curPos); - - // Break out on the forward slash - if (nextCh == chForwardSlash) - break; + fQuery = new XMLCh[(ptr1 - srcPtr) + 1]; + ptr2 = fQuery; + while (srcPtr < ptr1) + *ptr2++ = *srcPtr++; + *ptr2 = 0; + } - // Otherwise, save it - tmpBuf[bufIndex++] = nextCh; + // If we are not at the end now, then everything else is the fragment + if (*srcPtr == chPound) + { + srcPtr++; + fFragment = XMLString::replicate(srcPtr); + } +} - // If we max out on the temp buffer, definitely bad - if (bufIndex >= bufSize) - ThrowXML(MalformedURLException, XML4CExcepts::URL_MalformedURL); - } - // Cap the temp buffer and replicate to our host member - tmpBuf[bufIndex] = chNull; - fHost = XMLString::replicate(tmpBuf); - } +void URL::weavePaths(const XMLCh* const basePart) +{ + // Watch for stupid stuff + if (!basePart) + return; + if (!*basePart) + return; // - // Now we need to get the path part of the URL. This should be the - // rest of the content. So we just go until we get a null char back - // from the character spooler. This gets rid of all escaped chars - // in the URL. + // Ok, lets start at the end of the base path and work backwards and + // our path part and work forwards. For each leading . we see, we just + // eat it. For each leading .. we see, we eat it and throw away one + // level in the source URL. // - bufIndex = 0; - while (true) - { - // Tell it that end of input is ok - const XMLCh nextCh = getNextCh(curPos, true); - tmpBuf[bufIndex++] = nextCh; + // If the last character in the base part is a forward slash, back + // up one first before we look for the last slash. + // + const XMLCh* basePtr = basePart + (XMLString::stringLen(basePart) - 1); + if (*basePtr == chForwardSlash) + basePtr--; - // Break out at the end - if (!nextCh) - break; + while ((basePtr >= basePart) + && ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash))) + { + basePtr--; } + if (basePtr < basePart) + return; + + // Create a buffer as large as both parts + XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(fPath) + + XMLString::stringLen(basePart) + + 2]; // - // And get our own copy of the temp buffer as the path. If the path - // does not start with 'x:', then assume that its a Unix style path - // and put in a leading '/'. + // If we have no path part, then copy the base part up to the + // base pointer // - tmpBuf[bufIndex] = chNull; - if ((((tmpBuf[0] >= chLatin_A) && (tmpBuf[0] <= chLatin_Z)) - || ((tmpBuf[0] >= chLatin_a) && (tmpBuf[0] <= chLatin_z))) - && (tmpBuf[1] == chColon)) - { - fPath = XMLString::replicate(tmpBuf); - } - else + if (!fPath) { - fPath = new XMLCh[XMLString::stringLen(tmpBuf) + 2]; - fPath[0] = chForwardSlash; - XMLString::copyString(&fPath[1], tmpBuf); + XMLCh* bufPtr = tmpBuf; + const XMLCh* tmpPtr = basePart; + while (tmpPtr <= basePtr) + *bufPtr++ = *tmpPtr++; + *bufPtr = 0; + + fPath = tmpBuf; + return; } + // After this, make sure the buffer gets handled if we exit early + ArrayJanitor<XMLCh> janBuf(tmpBuf); + // - // <TBD> When we have more complete support, get rid of this. But for - // now we only support file:// (which is checked above) and for files - // we only support an empty host or "localhost" which means the same - // thing. + // We have some path part, so we need to check to see if we ahve to + // weave any of the parts together. // - if (fHost[0]) + XMLCh* pathPtr = fPath; + while (true) { - if (XMLString::compareString(fHost, gLocalHostString)) - ThrowXML(MalformedURLException, XML4CExcepts::URL_OnlyLocalHost); + // If it does not start with some period, then we are done + if (*pathPtr != chPeriod) + break; + + unsigned int periodCount = 1; + pathPtr++; + if (*pathPtr == chPeriod) + { + pathPtr++; + periodCount++; + } + + // Has to be followed by a / or \ or the null to mean anything + if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash) + && *pathPtr) + { + break; + } + if (*pathPtr) + pathPtr++; + + // If its one period, just eat it, else move backwards in the base + if (periodCount == 2) + { + basePtr--; + while ((basePtr >= basePart) + && ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash))) + { + basePtr--; + } + + if (basePtr < basePart) + { + // The base cannot provide enough levels, so its in error + // <TBD> + } + } } + + // Copy the base part up to the base pointer + XMLCh* bufPtr = tmpBuf; + const XMLCh* tmpPtr = basePart; + while (tmpPtr <= basePtr) + *bufPtr++ = *tmpPtr++; + + // And then copy on the rest of our path + XMLString::copyString(bufPtr, pathPtr); + + // Now delete our path and make the new buffer our path + delete [] fPath; + janBuf.orphan(); + fPath = tmpBuf; } diff --git a/src/util/URL.hpp b/src/util/URL.hpp index 1c5b5822182f5cc745a180d92d8dcc998e037f7b..ee8559b037153b163503aa8b3ddd343fc6b17bc7 100644 --- a/src/util/URL.hpp +++ b/src/util/URL.hpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.3 2000/01/12 00:16:22 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.2 1999/11/23 01:49:56 rahulj * Cannot use class qualifier in class defn. CC under HPUX is happy. * @@ -90,8 +94,8 @@ MakeXML4CException(MalformedURLException, XMLUTIL_EXPORT) // -// This class provides a minimal URL implementation to be able to deal -// with file:// protocol URLs. It will be fleshed out in the future. +// This class supports file, http, and ftp style URLs. All others are +// rejected // class XMLUTIL_EXPORT URL { @@ -99,30 +103,58 @@ public: // ----------------------------------------------------------------------- // Class types // - // Local MUST be the last one in the list! And they must remain in this - // order because they are indexes into an array internally! + // And they must remain in this order because they are indexes into an + // array internally! // ----------------------------------------------------------------------- enum Protocols { File , HTTP , FTP - , Gopher - , MailTo - , News - , NNTP - , Telnet - , Wais - , Prospero , Protocols_Count + , Unknown }; + // ----------------------------------------------------------------------- + // Public static methods + // ----------------------------------------------------------------------- + Protocols lookupByName(const XMLCh* const protoName); + + // ----------------------------------------------------------------------- // Constructors and Destructor // ----------------------------------------------------------------------- URL(); + URL + ( + const XMLCh* const baseURL + , const XMLCh* const relativeURL + ); + URL + ( + const XMLCh* const baseURL + , const char* const relativeURL + ); + URL + ( + const URL& baseURL + , const XMLCh* const relativeURL + ); + URL + ( + const URL& baseURL + , const char* const relativeURL + ); + URL + ( + const XMLCh* const urlText + ); + URL + ( + const char* const urlText + ); URL(const URL& toCopy); virtual ~URL(); @@ -138,58 +170,96 @@ public: // ----------------------------------------------------------------------- // Getter methods // ----------------------------------------------------------------------- + const XMLCh* getFragment() const; const XMLCh* getHost() const; - const XMLCh* getProtocol() const; + const XMLCh* getPassword() const; const XMLCh* getPath() const; - Protocols getType() const; - const XMLCh* getURL() const; + Protocols getProtocol() const; + const XMLCh* getProtocolName() const; + const XMLCh* getQuery() const; + const XMLCh* getURLText() const; + const XMLCh* getUser() const; // ----------------------------------------------------------------------- - // Getter methods + // Setter methods // ----------------------------------------------------------------------- void setURL(const XMLCh* const urlText); - void setURL(const char* const urlText); + void setURL + ( + const XMLCh* const baseURL + , const XMLCh* const relativeURL + ); + void setURL + ( + const URL& baseURL + , const XMLCh* const relativeURL + ); // ----------------------------------------------------------------------- // Miscellaneous methods // ----------------------------------------------------------------------- + bool isRelative() const; BinInputStream* makeNewStream() const; + void makeRelativeTo(const XMLCh* const baseURLText); + void makeRelativeTo(const URL& baseURL); private: // ----------------------------------------------------------------------- // Private helper methods // ----------------------------------------------------------------------- + void buildFullText(); void cleanup(); - Protocols findType(unsigned int& curPos) const; - XMLCh getNextCh(unsigned int& pos, const bool endOk = false) const; - XMLCh peekNextCh(unsigned int pos) const; - void parse(); + void conglomerateWithBase(const URL& baseURL); + void parse + ( + const XMLCh* const urlText + ); + void weavePaths(const XMLCh* const basePart); // ----------------------------------------------------------------------- // Data members // - // fFullURL - // This is a copy of the original URL. + // fFragment + // The fragment part of the URL, if any. If none, its a null. // // fHost // The host part of the URL that was parsed out. This one will often - // be empty (or "localhost", which also means the current machine.) + // be null (or "localhost", which also means the current machine.) + // + // fPassword + // The password found, if any. If none then its a null. // // fPath - // The path part of the URL that was parsed out. + // The path part of the URL that was parsed out, if any. If none, + // then its a null. // // fProtocol // Indicates the type of the URL's source. The text of the prefix // can be gotten from this. + // + // fQuery + // The query part of the URL, if any. If none, then its a null. + // + // fUser + // The username found, if any. If none, then its a null. + // + // fURLText + // This is a copy of the URL text, after it has been taken apart, + // made relative if needed, canonicalized, and then put back + // together. Its only created upon demand. // ----------------------------------------------------------------------- - XMLCh* fFullURL; + XMLCh* fFragment; XMLCh* fHost; + XMLCh* fPassword; XMLCh* fPath; Protocols fProtocol; + XMLCh* fQuery; + XMLCh* fUser; + XMLCh* fURLText; }; @@ -205,25 +275,52 @@ inline bool URL::operator!=(const URL& toCompare) const // --------------------------------------------------------------------------- // URL: Getter methods // --------------------------------------------------------------------------- +inline const XMLCh* URL::getFragment() const +{ + return fFragment; +} + inline const XMLCh* URL::getHost() const { return fHost; } +inline const XMLCh* URL::getPassword() const +{ + return fPassword; +} + inline const XMLCh* URL::getPath() const { return fPath; } -inline URL::Protocols URL::getType() const +inline URL::Protocols URL::getProtocol() const { return fProtocol; } -inline const XMLCh* URL::getURL() const +inline const XMLCh* URL::getQuery() const +{ + return fQuery; +} + +inline const XMLCh* URL::getUser() const { - return fFullURL; + return fUser; } +inline const XMLCh* URL::getURLText() const +{ + // + // Fault it in if not already. Since this is a const method and we + // can't use mutable members due the compilers we have to support, + // we have to cast off the constness. + // + if (!fURLText) + ((URL*)this)->buildFullText(); + + return fURLText; +} #endif diff --git a/src/util/XMLNetAccessor.hpp b/src/util/XMLNetAccessor.hpp index 8159e22cacaf66ac3ffd7ae74044a9e585d44d37..0799786c181410f6dca6383166f7fb0fd0864753 100644 --- a/src/util/XMLNetAccessor.hpp +++ b/src/util/XMLNetAccessor.hpp @@ -56,8 +56,12 @@ /** * $Log$ - * Revision 1.1 1999/11/09 01:05:50 twl - * Initial revision + * Revision 1.2 2000/01/12 00:16:23 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * + * Revision 1.1.1.1 1999/11/09 01:05:50 twl + * Initial checkin * * Revision 1.2 1999/11/08 20:45:20 rahul * Swat for adding in Product name and CVS comment log variable. @@ -101,8 +105,7 @@ public : // ----------------------------------------------------------------------- virtual BinInputStream* makeNew ( - const XMLCh* const urlSource - , XML4CExcepts::Codes& failReason + const URL& urlSrc ) = 0; diff --git a/src/util/XMLString.cpp b/src/util/XMLString.cpp index f19cc38495f4269f6cf7a5f6955b56264b2f5373..3296c7a02d89a43d9222017ee28739046b555ed9 100644 --- a/src/util/XMLString.cpp +++ b/src/util/XMLString.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.4 2000/01/12 00:16:23 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.3 1999/12/18 00:18:10 roddey * More changes to support the new, completely orthagonal support for * intrinsic encodings. @@ -846,7 +850,46 @@ unsigned int XMLString::hash( const XMLCh* const tohash } -unsigned int XMLString::hashN( const XMLCh* const tohash +const XMLCh* XMLString::findAny(const XMLCh* const toSearch + , const XMLCh* const searchList) +{ + const XMLCh* srcPtr = toSearch; + while (*srcPtr) + { + const XMLCh* listPtr = searchList; + const XMLCh curCh = *srcPtr; + + while (*listPtr) + { + if (curCh == *listPtr++) + return srcPtr; + } + srcPtr++; + } + return 0; +} + +XMLCh* XMLString::findAny( XMLCh* const toSearch + , const XMLCh* const searchList) +{ + XMLCh* srcPtr = toSearch; + while (*srcPtr) + { + const XMLCh* listPtr = searchList; + const XMLCh curCh = *srcPtr; + + while (*listPtr) + { + if (curCh == *listPtr++) + return srcPtr; + } + srcPtr++; + } + return 0; +} + + +unsigned int XMLString::hashN( const XMLCh* const tohash , const unsigned int n , const unsigned int hashModulus) { diff --git a/src/util/XMLString.hpp b/src/util/XMLString.hpp index 336c7d7dc45ba28dd2d563ce7088b31bf8999b4b..76059bce8a863cf1b55ac0bdae7f4baeb47184d2 100644 --- a/src/util/XMLString.hpp +++ b/src/util/XMLString.hpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.4 2000/01/12 00:16:23 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.3 1999/12/18 00:18:10 roddey * More changes to support the new, completely orthagonal support for * intrinsic encodings. @@ -295,6 +299,18 @@ public: , const unsigned int maxChars ); + static const XMLCh* findAny + ( + const XMLCh* const toSearch + , const XMLCh* const searchList + ); + + static XMLCh* findAny + ( + XMLCh* const toSearch + , const XMLCh* const searchList + ); + static unsigned int hash ( const XMLCh* const toHash diff --git a/src/validators/DTD/DTDValidator2.cpp b/src/validators/DTD/DTDValidator2.cpp index 17ef241c6526ddbae5fc162e4880e3a2a7aa06f3..5018b7fec61f854828819996a3f7f4fcf01e42f1 100644 --- a/src/validators/DTD/DTDValidator2.cpp +++ b/src/validators/DTD/DTDValidator2.cpp @@ -56,6 +56,10 @@ /** * $Log$ + * Revision 1.4 2000/01/12 00:17:07 roddey + * Changes to deal with multiply nested, relative pathed, entities and to deal + * with the new URL class changes. + * * Revision 1.3 1999/12/04 01:13:16 roddey * Fixed the logic for checking for PIs that start with 'xml'. It was doing doing "if (stringICompare()) " * instead of "if (!stringICompare()). @@ -83,12 +87,12 @@ #include <util/UnexpectedEOFException.hpp> #include <util/URL.hpp> #include <util/XMLUni.hpp> +#include <sax/InputSource.hpp> #include <framework/XMLBufferMgr.hpp> #include <framework/XMLDocumentHandler.hpp> #include <framework/XMLElementDecl.hpp> #include <framework/XMLEntityHandler.hpp> #include <framework/XMLNotationDecl.hpp> -#include <internal/URLInputSource.hpp> #include <internal/EndOfEntityException.hpp> #include <internal/ReaderMgr.hpp> #include <internal/XMLScanner.hpp>