dbertoni 00/05/11 12:09:27
Modified: c/src/XSLT XSLTEngineImpl.cpp
Log:
More URI parsing features.
Revision Changes Path
1.33 +75 -110 xml-xalan/c/src/XSLT/XSLTEngineImpl.cpp
Index: XSLTEngineImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTEngineImpl.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- XSLTEngineImpl.cpp 2000/05/08 17:29:36 1.32
+++ XSLTEngineImpl.cpp 2000/05/11 19:09:26 1.33
@@ -3571,146 +3571,116 @@
-XMLURL*
-XSLTEngineImpl::getURLFromString(const XalanDOMString& urlString) const
+#if !defined(WIN32)
+inline constXalanDOMString&
+NormalizeURI(const XalanDOMString& uriString)
{
-#if !defined(XALAN_NO_NAMESPACES)
- using std::auto_ptr;
-#endif
-
- auto_ptr<XMLURL> url(new XMLURL);
-
- try
- {
- // Let's see what sort of URI we have...
- const unsigned int index = indexOf(urlString, ':');
+ return uriString;
+}
+#else
+XalanDOMString
+NormalizeURI(const XalanDOMString& uriString)
+{
+ using std::vector;
- if (index == 1 || index == length(urlString))
- {
- // OK, it's some sort of file specification,
- // so prepend "file:///"
- XalanDOMString fullpath("file:///");
+ XalanDOMString theResult;
- fullpath += urlString;
+ // OK, look for a quick, cheap exit...
+ const unsigned int len = length(uriString);
+ const unsigned int index = indexOf(uriString, '\\');
- url->setURL(c_wstr(fullpath));
- }
- else
- {
- // OK, assume it's already got a protocol
- url->setURL(c_wstr(urlString));
- }
+ if (index == len)
+ {
+ // Nothing to normalize, so we're done...
+ theResult = uriString;
}
- catch (...)
+ else
{
- diag("Error! Cannot create url for: " + urlString);
+ vector<XalanDOMChar> theBuffer(c_wstr(uriString),
c_wstr(uriString) + len);
- throw;
+ std::replace(theBuffer.begin(), theBuffer.end(), '\\', '/');
+
+ theResult = XalanDOMString(&theBuffer[0], theBuffer.size());
}
- return url.release();
+ return theResult;
}
+#endif
-XalanDOMString
-NormalizeURI(
- const XalanDOMString& uriString,
- XalanDOMChar theOldSeparator,
- XalanDOMChar theNewSeparator)
+XMLURL*
+XSLTEngineImpl::getURLFromString(const XalanDOMString& urlString) const
{
#if !defined(XALAN_NO_NAMESPACES)
- using std::vector;
+ using std::auto_ptr;
#endif
-
- vector<XalanDOMChar> theBuffer;
- const unsigned int theLength = length(uriString);
-
- // Reserve enough characters in the buffer...
- theBuffer.reserve(theLength);
+ auto_ptr<XMLURL> url(new XMLURL);
- // See if we have a hybrid DOS-style URI, like
- // file:///c:\foo\foo.xml
- const unsigned int i1 = indexOf(uriString, ':');
- const unsigned int i2 = lastIndexOf(uriString, ':');
+ try
+ {
+ XalanDOMString theNormalizedURI;
- bool fHybrid = i1 == i2 ? false : true;
- assert(fHybrid == false || theNewSeparator == '\\');
+ // Let's see what sort of URI we have...
+ const unsigned int len = length(urlString);
+ const unsigned int index = indexOf(urlString, ':');
- for(unsigned int i = 0; i < theLength; ++i)
- {
- const XalanDOMChar theChar = charAt(uriString, i);
+#if !defined(WIN32)
+ const bool protocolPresent = index != len;
+#else
+ // This test will fail if someone uses the form v:/foo/foo.xsl,
+ // so I hope they don't do that...
+ const bool protocolPresent = index != len
&&
+ !(index
== 1 && charAt(urlString, index + 1) == '\\');
+#endif
- if (fHybrid == true)
- {
- if (theChar == theOldSeparator && i > i2)
- {
- theBuffer.push_back(theNewSeparator);
- }
- else
- {
- theBuffer.push_back(theChar);
- }
- }
- else if (theChar == theOldSeparator)
+ if (protocolPresent == true)
{
- theBuffer.push_back(theNewSeparator);
+ theNormalizedURI = NormalizeURI(urlString);
}
else
{
- theBuffer.push_back(theChar);
+ // Assume it's a file specification...
+ array_auto_ptr<XMLCh>
theFullPath(XMLPlatformUtils::getFullPath(c_wstr(urlString)));
+ assert(theFullPath.get() != 0);
+
+ theNormalizedURI =
+#if defined(WIN32)
+ XALAN_STATIC_UCODE_STRING("file:///")
+#else
+ XALAN_STATIC_UCODE_STRING("file://")
+#endif
+ + NormalizeURI(theFullPath.get());
}
+
+ url->setURL(c_wstr(theNormalizedURI));
}
+ catch (...)
+ {
+ diag("Error! Cannot create url for: " + urlString);
- return XalanDOMString(&theBuffer[0], theBuffer.size());
+ throw;
+ }
+
+ return url.release();
}
XMLURL* XSLTEngineImpl::getURLFromString(const XalanDOMString&
urlString, const XalanDOMString& base) const
{
- XalanDOMString context;
+ XalanDOMString context(NormalizeURI(base));
- bool fNormalizeToSlash = false;
- bool fNormalizeToBackslash = false;
-
- if (isEmpty(base) == false)
+ if (isEmpty(context) == false)
{
- // We'll only do the really simple case for now:
- // base is a complete file URL and urlString is a forward
relative path, i.e.
- // in the same directory as the urlString or a subdirectory
-
- // just to be robust, we'll accept a forward or back slash
const unsigned int theLength = length(base);
- const unsigned int i1 = lastIndexOf(base,'/');
- const unsigned int i2 = lastIndexOf(base,'\\');
+ const unsigned int index = lastIndexOf(base,'/');
- unsigned int i = 0;
-
- if (i1 > i2 && i1 < theLength)
- {
- i = i1;
-
- fNormalizeToSlash = true;
- }
- else if (i2 < theLength)
- {
- i = i2;
-
- fNormalizeToBackslash = true;
- }
- else
- {
- i = i1;
-
- assert(i2 == theLength);
- }
-
- if (i < theLength)
+ if (index < theLength)
{
- context = substring(base, 0, i + 1);
+ context = substring(context, 0, index + 1);
}
}
@@ -3725,11 +3695,15 @@
// No colon, so just use the urlString as is...
context += urlString;
}
- else if (theColonIndex == 1)
+#if defined(WIN32)
+ else if (theColonIndex == 1 && charAt(urlString, theColonIndex + 1) ==
'\\')
{
// Ahh, it's a drive letter, so ignore the context...
+ // $$$ ToDo: This is not quite right. Perhaps a
+ // protocol can be one character?
context = urlString;
}
+#endif
else
{
// Assume it's a protocol...
@@ -3745,15 +3719,6 @@
// OK, not the same protocol, so what can we do???
context = urlString;
}
- }
-
- if (fNormalizeToSlash == true)
- {
- context = NormalizeURI(context, '\\', '/');
- }
- else if (fNormalizeToBackslash == true)
- {
- context = NormalizeURI(context, '/', '\\');
}
return getURLFromString(context);