/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Id$
 */


// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/BinFileInputStream.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/TransService.hpp>
#include <xercesc/util/XMLURL.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/util/XMLUri.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/util/XMLChar.hpp>

XERCES_CPP_NAMESPACE_BEGIN



// ---------------------------------------------------------------------------
//  Local types
//
//  TypeEntry
//      This structure defines a single entry in the list of URL types. Each
//      entry indicates the prefix for that type of URL, and the SourceTypes
//      value it maps to.
// ---------------------------------------------------------------------------
struct ProtoEntry
{
    XMLURL::Protocols   protocol;
    const XMLCh*        prefix;
    unsigned int        defPort;
};


// ---------------------------------------------------------------------------
//  Local data
//
//  gXXXString
//      These are the strings for our prefix types. They all have to be
//      Unicode strings all the time, so we can't just do regular strings.
//
//  gProtoList
//      The list of URL types that we support and some info related to each
//      one.
//
//  gMaxProtoLen
//      The length of the longest protocol string
//
//      NOTE:!!! Be sure to keep this up to date if new protocols are added!
// ---------------------------------------------------------------------------
static const XMLCh  gFileString[] =
{
        chLatin_f, chLatin_i, chLatin_l, chLatin_e, chNull
};

static const XMLCh gFTPString[]  =
{
        chLatin_f, chLatin_t, chLatin_p, chNull
};

static const XMLCh gHTTPString[] =
{
        chLatin_h, chLatin_t, chLatin_t, chLatin_p, chNull
};

static const XMLCh gHTTPSString[] =
{
        chLatin_h, chLatin_t, chLatin_t, chLatin_p, chLatin_s, chNull
};

static ProtoEntry gProtoList[XMLURL::Protocols_Count] =
{
        { XMLURL::File     , gFileString    , 0  }
    ,   { XMLURL::HTTP     , gHTTPString    , 80 }
    ,   { XMLURL::FTP      , gFTPString     , 21 }
    ,   { XMLURL::HTTPS    , gHTTPSString   , 443 }
};

// !!! Keep these up to date with list above!
static const unsigned int gMaxProtoLen = 5;

static const XMLCh gListOne[]    = { chColon, chForwardSlash, chNull };
static const XMLCh gListTwo[]    = { chAt, chNull };
static const XMLCh gListThree[]  = { chColon, chNull };
static const XMLCh gListFour[]   = { chForwardSlash, chNull };
static const XMLCh gListFive[]   = { chPound, chQuestion, chNull };
static const XMLCh gListSix[]    = { chPound, chNull };

// ---------------------------------------------------------------------------
//  Local methods
// ---------------------------------------------------------------------------
static bool isHexDigit(const XMLCh toCheck)
{
    if (((toCheck >= chDigit_0) && (toCheck <= chDigit_9))
    ||  ((toCheck >= chLatin_A) && (toCheck <= chLatin_F))
    ||  ((toCheck >= chLatin_a) && (toCheck <= chLatin_f)))
    {
        return true;
    }
    return false;
}

static unsigned int xlatHexDigit(const XMLCh toXlat)
{
    if ((toXlat >= chDigit_0) && (toXlat <= chDigit_9))
        return (unsigned int)(toXlat - chDigit_0);

    if ((toXlat >= chLatin_A) && (toXlat <= chLatin_F))
        return (unsigned int)(toXlat - chLatin_A) + 10;

    return (unsigned int)(toXlat - chLatin_a) + 10;
}



// ---------------------------------------------------------------------------
//  XMLURL: Public, static methods
// ---------------------------------------------------------------------------
XMLURL::Protocols XMLURL::lookupByName(const XMLCh* const protoName)
{
    for (unsigned int index = 0; index < XMLURL::Protocols_Count; index++)
    {
        if (!XMLString::compareIStringASCII(protoName, gProtoList[index].prefix))
            return gProtoList[index].protocol;
    }
    return XMLURL::Unknown;
}



// ---------------------------------------------------------------------------
//  XMLURL: Constructors and Destructor
// ---------------------------------------------------------------------------
XMLURL::XMLURL(MemoryManager* const manager) :

    fMemoryManager(manager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
}

typedef JanitorMemFunCall<XMLURL>   CleanupType;

XMLURL::XMLURL(const XMLCh* const    baseURL
             , const XMLCh* const    relativeURL
             , MemoryManager* const manager) :

    fMemoryManager(manager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

	try
	{
        setURL(baseURL, relativeURL);
	}
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::XMLURL(const XMLCh* const  baseURL
             , const char* const   relativeURL
             , MemoryManager* const manager) :

    fMemoryManager(manager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

    XMLCh* tmpRel = XMLString::transcode(relativeURL, fMemoryManager);
    ArrayJanitor<XMLCh> janRel(tmpRel, fMemoryManager);
	try
	{
		setURL(baseURL, tmpRel);
	}
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::XMLURL(const XMLURL&         baseURL
             , const XMLCh* const    relativeURL) :

    fMemoryManager(baseURL.fMemoryManager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

	try
	{
		setURL(baseURL, relativeURL);
	}
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::XMLURL(const  XMLURL&        baseURL
             , const char* const     relativeURL) :

    fMemoryManager(baseURL.fMemoryManager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

    XMLCh* tmpRel = XMLString::transcode(relativeURL, fMemoryManager);
    ArrayJanitor<XMLCh> janRel(tmpRel, fMemoryManager);
	try
	{
		setURL(baseURL, tmpRel);
	}
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::XMLURL(const XMLCh* const urlText,
               MemoryManager* const manager) :

    fMemoryManager(manager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

	try
	{
	    setURL(urlText);
	}
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::XMLURL(const char* const urlText,
               MemoryManager* const manager) :

    fMemoryManager(manager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(0)
    , fProtocol(XMLURL::Unknown)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(false)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

    XMLCh* tmpText = XMLString::transcode(urlText, fMemoryManager);
    ArrayJanitor<XMLCh> janRel(tmpText, fMemoryManager);
	try
	{
	    setURL(tmpText);
	}
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::XMLURL(const XMLURL& toCopy) :
    XMemory(toCopy)
    , fMemoryManager(toCopy.fMemoryManager)
    , fFragment(0)
    , fHost(0)
    , fPassword(0)
    , fPath(0)
    , fPortNum(toCopy.fPortNum)
    , fProtocol(toCopy.fProtocol)
    , fQuery(0)
    , fUser(0)
    , fURLText(0)
    , fHasInvalidChar(toCopy.fHasInvalidChar)
{
    CleanupType cleanup(this, &XMLURL::cleanUp);

    try
    {
        fFragment = XMLString::replicate(toCopy.fFragment, fMemoryManager);
        fHost = XMLString::replicate(toCopy.fHost, fMemoryManager);
        fPassword = XMLString::replicate(toCopy.fPassword, fMemoryManager);
        fPath = XMLString::replicate(toCopy.fPath, fMemoryManager);
        fQuery = XMLString::replicate(toCopy.fQuery, fMemoryManager);
        fUser = XMLString::replicate(toCopy.fUser, fMemoryManager);
        fURLText = XMLString::replicate(toCopy.fURLText, fMemoryManager);
    }
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XMLURL::~XMLURL()
{
    cleanUp();
}


// ---------------------------------------------------------------------------
//  XMLURL: Public operators
// ---------------------------------------------------------------------------
XMLURL& XMLURL::operator=(const XMLURL& toAssign)
{
    if (this == &toAssign)
        return *this;

    // Clean up our stuff
    cleanUp();

    // And copy his stuff
    fMemoryManager = toAssign.fMemoryManager;
    fFragment = XMLString::replicate(toAssign.fFragment, fMemoryManager);
    fHost = XMLString::replicate(toAssign.fHost, fMemoryManager);
    fPassword = XMLString::replicate(toAssign.fPassword, fMemoryManager);
    fPath = XMLString::replicate(toAssign.fPath, fMemoryManager);
    fPortNum = toAssign.fPortNum;
    fProtocol = toAssign.fProtocol;
    fQuery = XMLString::replicate(toAssign.fQuery, fMemoryManager);
    fUser = XMLString::replicate(toAssign.fUser, fMemoryManager);
    fURLText = XMLString::replicate(toAssign.fURLText, fMemoryManager);
    fHasInvalidChar = toAssign.fHasInvalidChar;

    return *this;
}

bool XMLURL::operator==(const XMLURL& toCompare) const
{
    //
    //  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::equals(getURLText(), toCompare.getURLText()))
        return false;

    return true;
}



// ---------------------------------------------------------------------------
//  XMLURL: Getter methods
// ---------------------------------------------------------------------------
unsigned int XMLURL::getPortNum() const
{
    //
    //  If it was not provided explicitly, then lets return the default one
    //  for the protocol.
    //
    if (!fPortNum)
    {
        if (fProtocol == Unknown)
            return 0;
        return gProtoList[fProtocol].defPort;
    }
    return fPortNum;
}


const XMLCh* XMLURL::getProtocolName() const
{
    // Check to see if its ever been set
    if (fProtocol == Unknown)
        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);

    return gProtoList[fProtocol].prefix;
}


// ---------------------------------------------------------------------------
//  XMLURL: Setter methods
// ---------------------------------------------------------------------------
void XMLURL::setURL(const XMLCh* const urlText)
{
    //
    //  Try to parse the URL.
    //
    cleanUp();
    parse(urlText);
}

void XMLURL::setURL(const XMLCh* const    baseURL
                  , const XMLCh* const    relativeURL)
{
    cleanUp();

    // 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)
		{
			XMLURL basePart(baseURL, fMemoryManager);
			if (!conglomerateWithBase(basePart, false))
			{
				cleanUp();
				ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_RelativeBaseURL, fMemoryManager);
			}
		}
	}
}

// this version of setURL doesn't throw a malformedurl exception
// instead it returns false when it failed (or when it would of
// thrown a malformedurl exception)
bool XMLURL::setURL(const XMLCh* const    baseURL
                  , const XMLCh* const    relativeURL
                  , XMLURL& xmlURL)
{
    cleanUp();

    // Parse our URL string
    if (parse(relativeURL, xmlURL))
    {
	    //  If its relative and the base is non-null and non-empty, then
	    //  parse the base URL string and conglomerate them.
	    //
	    if (isRelative() && baseURL && *baseURL)
	    {
	        XMLURL basePart(fMemoryManager);
            if (parse(baseURL, basePart)  && conglomerateWithBase(basePart, false))
            {
		        return true;
		    }
	    }
        else
            return true;
    }
    return false;
}

void XMLURL::setURL(const XMLURL&         baseURL
                  , const XMLCh* const    relativeURL)
{
    cleanUp();

	// Parse our URL string
    parse(relativeURL);

    // If its relative, then conglomerate with the base URL
    if (isRelative())
		conglomerateWithBase(baseURL);
}


// ---------------------------------------------------------------------------
//  XMLURL: Miscellaneous methods
// ---------------------------------------------------------------------------
bool XMLURL::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;
}


bool XMLURL::hasInvalidChar() const {
    return fHasInvalidChar;
}


BinInputStream* XMLURL::makeNewStream() const
{
    //
    //  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 == XMLURL::File)
    {
        if (!fHost || !XMLString::compareIStringASCII(fHost, XMLUni::fgLocalHostString))
        {

            XMLCh* realPath = XMLString::replicate(fPath, fMemoryManager);
            ArrayJanitor<XMLCh> basePathName(realPath, fMemoryManager);

            //
            // Need to manually replace any character reference %xx first
            // HTTP protocol will be done automatically by the netaccessor
            //
            XMLSize_t end = XMLString::stringLen(realPath);
            int percentIndex = XMLString::indexOf(realPath, chPercent, 0, fMemoryManager);

            while (percentIndex != -1) {

            	// Isolate the length/boundary check so we don't try and copy off the end.
                if (percentIndex+2 >= (int)end)
                {
                    XMLCh value1[3];
                    value1[1] = chNull;
                    value1[2] = chNull;
					XMLString::moveChars(value1, &(realPath[percentIndex]), (percentIndex + 1 >= (int)end ? 1 : 2));
                    ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                            , realPath
                            , value1
                            , fMemoryManager);
                }
                else if (!isHexDigit(realPath[percentIndex+1]) || !isHexDigit(realPath[percentIndex+2]))
                {
                    XMLCh value1[4];
                    XMLString::moveChars(value1, &(realPath[percentIndex]), 3);
                    value1[3] = chNull;
                    ThrowXMLwithMemMgr2(MalformedURLException
                            , XMLExcepts::XMLNUM_URI_Component_Invalid_EscapeSequence
                            , realPath
                            , value1
                            , fMemoryManager);
                }

                unsigned int value = (xlatHexDigit(realPath[percentIndex+1]) * 16) + xlatHexDigit(realPath[percentIndex+2]);

                realPath[percentIndex] = XMLCh(value);

                XMLSize_t i =0;
                for (i = percentIndex + 1; i < end - 2 ; i++)
                    realPath[i] = realPath[i+2];
                realPath[i] = chNull;
                end = i;

                if (((XMLSize_t)(percentIndex + 1)) < end)
                  percentIndex = XMLString::indexOf(realPath, chPercent, percentIndex + 1, fMemoryManager);
                else
                  percentIndex = -1;
            }


            BinFileInputStream* retStrm = new (fMemoryManager) BinFileInputStream(realPath, fMemoryManager);
            if (!retStrm->getIsOpen())
            {
                delete retStrm;
                return 0;
            }
            return retStrm;
        }
    }

    //
    //  If we don't have have an installed net accessor object, then we
    //  have to just throw here.
    //
    if (!XMLPlatformUtils::fgNetAccessor)
        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_UnsupportedProto, fMemoryManager);

    // Else ask the net accessor to create the stream
    return XMLPlatformUtils::fgNetAccessor->makeNew(*this);
}

void XMLURL::makeRelativeTo(const XMLCh* const baseURLText)
{
    // If this one is not relative, don't bother
    if (!isRelative())
        return;

    XMLURL baseURL(baseURLText, fMemoryManager);
    conglomerateWithBase(baseURL);
}

void XMLURL::makeRelativeTo(const XMLURL& baseURL)
{
    // If this one is not relative, don't bother
    if (!isRelative())
        return;
    conglomerateWithBase(baseURL);
}




// ---------------------------------------------------------------------------
//  XMLURL: 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 XMLURL::buildFullText()
{
    // Calculate the worst case size of the buffer required
    XMLSize_t 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
                           + 32;

    // Clean up the existing buffer and allocate another
    fMemoryManager->deallocate(fURLText);//delete [] fURLText;
    fURLText = (XMLCh*) fMemoryManager->allocate((bufSize) * sizeof(XMLCh));//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 (fUser)
    {
        XMLString::copyString(outPtr, fUser);
        outPtr += XMLString::stringLen(fUser);

        if (fPassword)
        {
            *outPtr++ = chColon;
            XMLString::copyString(outPtr, fPassword);
            outPtr += XMLString::stringLen(fPassword);
        }

        *outPtr++ = chAt;
    }

    if (fHost)
    {
        XMLString::copyString(outPtr, fHost);
        outPtr += XMLString::stringLen(fHost);

        //
        //  If the port is zero, then we don't put it in. Else we need
        //  to because it was explicitly provided.
        //
        if (fPortNum)
        {
            *outPtr++ = chColon;

            XMLCh tmpBuf[17];
            XMLString::binToText(fPortNum, tmpBuf, 16, 10, fMemoryManager);
            XMLString::copyString(outPtr, tmpBuf);
            outPtr += XMLString::stringLen(tmpBuf);
        }
    }

    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);
    }

    // Cap it off in case the last op was not a string copy
    *outPtr = 0;
}


//
//  Just a central place to handle cleanup, since its done from a number
//  of different spots.
//
void XMLURL::cleanUp()
{
    fMemoryManager->deallocate(fFragment);//delete [] fFragment;
    fMemoryManager->deallocate(fHost);//delete [] fHost;
    fMemoryManager->deallocate(fPassword);//delete [] fPassword;
    fMemoryManager->deallocate(fPath);//delete [] fPath;
    fMemoryManager->deallocate(fQuery);//delete [] fQuery;
    fMemoryManager->deallocate(fUser);//delete [] fUser;
    fMemoryManager->deallocate(fURLText);//delete [] fURLText;

    fFragment = 0;
    fHost = 0;
    fPassword = 0;
    fPath = 0;
    fQuery = 0;
    fUser = 0;
    fURLText = 0;

    fProtocol = Unknown;
    fPortNum = 0;
    fHasInvalidChar = false;
}


//This function  has been modified to take a bool parameter and the
//functionality inside looks irrational but is only to make
//solaris 2.7 CC 5.0 optimized build happy.

bool XMLURL::conglomerateWithBase(const XMLURL& baseURL, bool useExceptions)
{
    // The base URL cannot be relative
    if (baseURL.isRelative())
    {
        if (useExceptions)
			ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_RelativeBaseURL, fMemoryManager);
        else
            return false;
    }

    //
    //  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.
    //
    if ((fProtocol == Unknown)
    &&  !fHost
    &&  !fPath
    &&  fFragment)
    {
        // Just in case, make sure we don't leak the user or password values
        fMemoryManager->deallocate(fUser);//delete [] fUser;
        fUser = 0;
        fMemoryManager->deallocate(fPassword);//delete [] fPassword;
        fPassword = 0;

        // Copy over the protocol and port number as is
        fProtocol = baseURL.fProtocol;
        fPortNum = baseURL.fPortNum;

        // Replicate the base fields that are provided
        fHost = XMLString::replicate(baseURL.fHost, fMemoryManager);
        fUser = XMLString::replicate(baseURL.fUser, fMemoryManager);
        fPassword = XMLString::replicate(baseURL.fPassword, fMemoryManager);
        fPath = XMLString::replicate(baseURL.fPath, fMemoryManager);
        return true;
    }

    //
    //  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.
    //
    if (fProtocol != Unknown)
        return true;
    fProtocol = baseURL.fProtocol;

    //
    //  If the protocol is not file, and we either already have our own
    //  host, or the base does not have one, then we are done.
    //
    if (fProtocol != File)
    {
        if (fHost || !baseURL.fHost)
            return true;
    }

    // Replicate all of the hosty stuff if the base has one
    if (baseURL.fHost)
    {
        // Just in case, make sure we don't leak a user or password field
        fMemoryManager->deallocate(fUser);//delete [] fUser;
        fUser = 0;
        fMemoryManager->deallocate(fPassword);//delete [] fPassword;
        fPassword = 0;
        fMemoryManager->deallocate(fHost);//delete [] fHost;
        fHost = 0;

        fHost = XMLString::replicate(baseURL.fHost, fMemoryManager);
        fUser = XMLString::replicate(baseURL.fUser, fMemoryManager);
        fPassword = XMLString::replicate(baseURL.fPassword, fMemoryManager);

        fPortNum = baseURL.fPortNum;
    }

    // If we have a path and its absolute, then we are done
    const bool hadPath = (fPath != 0);
    if (hadPath)
    {
        if (*fPath == chForwardSlash)
            return true;
    }

    // Its a relative path, so weave them together.
    if (baseURL.fPath) {
        XMLCh* temp = XMLPlatformUtils::weavePaths(baseURL.fPath, fPath ,fMemoryManager);
        fMemoryManager->deallocate(fPath);//delete [] fPath;
        fPath = temp;
    }

    // If we had any original path, then we are done
    if (hadPath)
        return true;

    // We had no original path, so go on to deal with the query/fragment parts
    if (fQuery || !baseURL.fQuery)
        return true;
    fQuery = XMLString::replicate(baseURL.fQuery, fMemoryManager);

    if (fFragment || !baseURL.fFragment)
        return true;
    fFragment = XMLString::replicate(baseURL.fFragment, fMemoryManager);
	return true;
}


void XMLURL::parse(const XMLCh* const urlText)
{
    // Simplify things by checking for the psycho scenarios first
    if (!*urlText)
        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);

    // Before we start, check if this urlText contains valid uri characters
    if (!XMLUri::isURIString(urlText))
        fHasInvalidChar = true;
    else
        fHasInvalidChar = false;

    //
    //  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 (((*urlText >= chLatin_A) && (*urlText <= chLatin_Z))
    ||  ((*urlText >= chLatin_a) && (*urlText <= chLatin_z)))
    {
        if (*(urlText + 1) == chColon)
        {
            if ((*(urlText + 2) == chForwardSlash)
            ||  (*(urlText + 2) == chBackSlash))
            {
                ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);
            }
        }
    }

    // Get a copy of the URL that we can modify
    XMLCh* srcCpy = XMLString::replicate(urlText, fMemoryManager);
    ArrayJanitor<XMLCh> janSrcCopy(srcCpy, fMemoryManager);

    //
    //  Get a pointer now that we can run up thrown the source as we parse
    //  bits and pieces out of it.
    //
    XMLCh* srcPtr = srcCpy;

    // Run up past any spaces
    while (*srcPtr)
    {
        if (!XMLChar1_0::isWhitespace(*srcPtr))
            break;
        srcPtr++;
    }

    // Make sure it wasn't all space
    if (!*srcPtr)
        ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_NoProtocolPresent, fMemoryManager);

    //
    //  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.
    //
    XMLCh* ptr1 = XMLString::findAny(srcPtr, gListOne);
    XMLCh* ptr2;

    // If we found a protocol, then deal with it
    if (ptr1)
    {
        if (*ptr1 == chColon)
        {
            // Cap the string at the colon
            *ptr1 = 0;

            // And try to find it in our list of protocols
            fProtocol = lookupByName(srcPtr);

            if (fProtocol == Unknown)
            {
                ThrowXMLwithMemMgr1
                (
                    MalformedURLException
                    , XMLExcepts::URL_UnsupportedProto1
                    , srcPtr
                    , fMemoryManager
                );
            }

            // And move our source pointer up past what we've processed
            srcPtr = (ptr1 + 1);
        }
    }

    //
    //  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 part at this point. we will just look for the next / char
        //  or end of string and make all of that the host for now.
        //
        if (*srcPtr)
        {
            // Search from here for a / character
            ptr1 = XMLString::findAny(srcPtr, gListFour);

            //
            //  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)
                {
                    fMemoryManager->deallocate(fHost);//delete [] fHost;
                    fHost = (XMLCh*) fMemoryManager->allocate
                    (
                        ((ptr1 - srcPtr) + 1) * sizeof(XMLCh)
                    );//new XMLCh[(ptr1 - srcPtr) + 1];
                    ptr2 = fHost;
                    while (srcPtr < ptr1)
                        *ptr2++ = *srcPtr++;
                    *ptr2 = 0;
                }
            }
             else
            {
                fMemoryManager->deallocate(fHost);//delete [] fHost;
                fHost = XMLString::replicate(srcPtr, fMemoryManager);

                // Update source pointer to the end
                srcPtr += XMLString::stringLen(fHost);
            }
        }
    }
    else
    {
        //
        // http protocol requires two forward slashes
        // we didn't get them, so throw an exception
        //
        if (fProtocol == HTTP) {
            ThrowXMLwithMemMgr
                (
                    MalformedURLException
                    , XMLExcepts::URL_ExpectingTwoSlashes
                    , fMemoryManager
                );
        }
    }

    //
    //  If there was a host part, then we have to grovel through it for
    //  all the bits and pieces it can hold.
    //
    if (fHost)
    {
        //
        //  Look for a '@' character, which indicates a user name. If we
        //  find one, then everything between the start of the host data
        //  and the character is the user name.
        //
        ptr1 = XMLString::findAny(fHost, gListTwo);
        if (ptr1)
        {
            // Get this info out as the user name
            *ptr1 = 0;
            fMemoryManager->deallocate(fUser);//delete [] fUser;
            fUser = XMLString::replicate(fHost, fMemoryManager);
            ptr1++;

            // And now cut these chars from the host string
            XMLString::cut(fHost, ptr1 - fHost);

            // Is there a password inside the user string?
            ptr2 = XMLString::findAny(fUser, gListThree);
            if (ptr2)
            {
                // Remove it from the user name string
                *ptr2 = 0;

                // And copy out the remainder to the password field
                ptr2++;
                fMemoryManager->deallocate(fPassword);//delete [] fPassword;
                fPassword = XMLString::replicate(ptr2, fMemoryManager);
            }
        }

        //
        //  Ok, so now we are at the actual host name, if any. If we are
        //  not at the end of the host data, then lets see if we have a
        //  port trailing the
        //
        ptr1 = XMLString::findAny(fHost, gListThree);
        if (ptr1)
        {
            // Remove it from the host name
            *ptr1 = 0;

            // Try to convert it to a numeric port value and store it
            ptr1++;
            if (!XMLString::textToBin(ptr1, fPortNum, fMemoryManager))
                ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_BadPortField, fMemoryManager);
        }

        // If the host ended up empty, then toss is
        if (!*fHost)
        {
            fMemoryManager->deallocate(fHost);//delete[] fHost;
            fHost = 0;
        }
    }

    // If we are at the end, then we are done now
    if (!*srcPtr) {
        if(fHost) {
            static const XMLCh slash[] = { chForwardSlash, chNull };
            fPath = XMLString::replicate(slash, fMemoryManager);
        }
        return;
    }

    //
    //  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.
    //
    ptr1 = XMLString::findAny(srcPtr, gListFive);
    if (!ptr1)
    {
        fMemoryManager->deallocate(fPath);//delete [] fPath;
        fPath = XMLString::replicate(srcPtr, fMemoryManager);
        return;
    }

    // Everything from where we are to what we found is the path
    if (ptr1 > srcPtr)
    {
        fMemoryManager->deallocate(fPath);//delete [] fPath;
        fPath = (XMLCh*) fMemoryManager->allocate
        (
            ((ptr1 - srcPtr) + 1) * sizeof(XMLCh)
        );//new XMLCh[(ptr1 - srcPtr) + 1];
        ptr2 = fPath;
        while (srcPtr < ptr1)
            *ptr2++ = *srcPtr++;
        *ptr2 = 0;
    }

    //
    //  If we found a fragment, then it is the rest of the string and we
    //  are done.
    //
    if (*srcPtr == chPound)
    {
        srcPtr++;
        fMemoryManager->deallocate(fFragment);//delete [] fFragment;
        fFragment = XMLString::replicate(srcPtr, fMemoryManager);
        return;
    }

    //
    //  The query is either the rest of the string, or up to the fragment
    //  separator.
    //
    srcPtr++;
    ptr1 = XMLString::findAny(srcPtr, gListSix);
    fMemoryManager->deallocate(fQuery);//delete [] fQuery;
    if (!ptr1)
    {
        fQuery = XMLString::replicate(srcPtr, fMemoryManager);
        return;
    }
     else
    {
        fQuery = (XMLCh*) fMemoryManager->allocate
        (
            ((ptr1 - srcPtr) + 1) * sizeof(XMLCh)
        );//new XMLCh[(ptr1 - srcPtr) + 1];
        ptr2 = fQuery;
        while (srcPtr < ptr1)
            *ptr2++ = *srcPtr++;
        *ptr2 = 0;
    }

    // If we are not at the end now, then everything else is the fragment
    if (*srcPtr == chPound)
    {
        srcPtr++;
        fMemoryManager->deallocate(fFragment);//delete [] fFragment;
        fFragment = XMLString::replicate(srcPtr, fMemoryManager);
    }
}

bool XMLURL::parse(const XMLCh* const urlText, XMLURL& xmlURL)
{
    // Simplify things by checking for the psycho scenarios first
    if (!*urlText)
        return false;

    // Before we start, check if this urlText contains valid uri characters
    if (!XMLUri::isURIString(urlText))
        xmlURL.fHasInvalidChar = true;
    else
        xmlURL.fHasInvalidChar = false;

    //
    //  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 (((*urlText >= chLatin_A) && (*urlText <= chLatin_Z))
    ||  ((*urlText >= chLatin_a) && (*urlText <= chLatin_z)))
    {
        if (*(urlText + 1) == chColon)
        {
            if ((*(urlText + 2) == chForwardSlash)
            ||  (*(urlText + 2) == chBackSlash))
            {
                return false;
            }
        }
    }

    // Get a copy of the URL that we can modify
    XMLCh* srcCpy = XMLString::replicate(urlText, xmlURL.fMemoryManager);
    ArrayJanitor<XMLCh> janSrcCopy(srcCpy, xmlURL.fMemoryManager);

    //
    //  Get a pointer now that we can run up thrown the source as we parse
    //  bits and pieces out of it.
    //
    XMLCh* srcPtr = srcCpy;

    // Run up past any spaces
    while (*srcPtr)
    {
        if (!XMLChar1_0::isWhitespace(*srcPtr))
            break;
        srcPtr++;
    }

    // Make sure it wasn't all space
    if (!*srcPtr)
        return false;

    //
    //  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.
    //
    XMLCh* ptr1 = XMLString::findAny(srcPtr, gListOne);
    XMLCh* ptr2;

    // If we found a protocol, then deal with it
    if (ptr1)
    {
        if (*ptr1 == chColon)
        {
            // Cap the string at the colon
            *ptr1 = 0;

            // And try to find it in our list of protocols
            xmlURL.fProtocol = lookupByName(srcPtr);

            if (xmlURL.fProtocol == Unknown)
                return false;

            // And move our source pointer up past what we've processed
            srcPtr = (ptr1 + 1);
        }
    }

    //
    //  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 part at this point. we will just look for the next / char
        //  or end of string and make all of that the host for now.
        //
        if (*srcPtr)
        {
            // Search from here for a / character
            ptr1 = XMLString::findAny(srcPtr, gListFour);

            //
            //  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)
                {
                    xmlURL.fHost = (XMLCh*) xmlURL.fMemoryManager->allocate
                    (
                        ((ptr1 - srcPtr) + 1) * sizeof(XMLCh)
                    );//new XMLCh[(ptr1 - srcPtr) + 1];
                    ptr2 = xmlURL.fHost;
                    while (srcPtr < ptr1)
                        *ptr2++ = *srcPtr++;
                    *ptr2 = 0;
                }
            }
             else
            {
                xmlURL.fHost = XMLString::replicate(srcPtr, xmlURL.fMemoryManager);

                // Update source pointer to the end
                srcPtr += XMLString::stringLen(xmlURL.fHost);
            }
        }
    }
    else
    {
        //
        // http protocol requires two forward slashes
        // we didn't get them, so throw an exception
        //
        if (xmlURL.fProtocol == HTTP)
            return false;
    }

    //
    //  If there was a host part, then we have to grovel through it for
    //  all the bits and pieces it can hold.
    //
    if (xmlURL.fHost)
    {
        //
        //  Look for a '@' character, which indicates a user name. If we
        //  find one, then everything between the start of the host data
        //  and the character is the user name.
        //
        ptr1 = XMLString::findAny(xmlURL.fHost, gListTwo);
        if (ptr1)
        {
            // Get this info out as the user name
            *ptr1 = 0;
            xmlURL.fUser = XMLString::replicate(xmlURL.fHost, xmlURL.fMemoryManager);
            ptr1++;

            // And now cut these chars from the host string
            XMLString::cut(xmlURL.fHost, ptr1 - xmlURL.fHost);

            // Is there a password inside the user string?
            ptr2 = XMLString::findAny(xmlURL.fUser, gListThree);
            if (ptr2)
            {
                // Remove it from the user name string
                *ptr2 = 0;

                // And copy out the remainder to the password field
                ptr2++;
                xmlURL.fPassword = XMLString::replicate(ptr2, xmlURL.fMemoryManager);
            }
        }

        //
        //  Ok, so now we are at the actual host name, if any. If we are
        //  not at the end of the host data, then lets see if we have a
        //  port trailing the
        //
        ptr1 = XMLString::findAny(xmlURL.fHost, gListThree);
        if (ptr1)
        {
            // Remove it from the host name
            *ptr1 = 0;

            // Try to convert it to a numeric port value and store it
            ptr1++;
            if (!XMLString::textToBin(ptr1, xmlURL.fPortNum, xmlURL.fMemoryManager))
                return false;
        }

        // If the host ended up empty, then toss is
        if (!*(xmlURL.fHost))
        {
            xmlURL.fMemoryManager->deallocate(xmlURL.fHost);//delete[] fHost;
            xmlURL.fHost = 0;
        }
    }

    // If we are at the end, then we are done now
    if (!*srcPtr) {
        if(xmlURL.fHost) {
            static const XMLCh slash[] = { chForwardSlash, chNull };
            xmlURL.fPath = XMLString::replicate(slash, xmlURL.fMemoryManager);
        }
        return true;
    }

    //
    //  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.
    //
    ptr1 = XMLString::findAny(srcPtr, gListFive);
    if (!ptr1)
    {
        xmlURL.fPath = XMLString::replicate(srcPtr, xmlURL.fMemoryManager);
        return true;
    }

    // Everything from where we are to what we found is the path
    if (ptr1 > srcPtr)
    {
        xmlURL.fPath = (XMLCh*) xmlURL.fMemoryManager->allocate
        (
            ((ptr1 - srcPtr) + 1) * sizeof(XMLCh)
        );//new XMLCh[(ptr1 - srcPtr) + 1];
        ptr2 = xmlURL.fPath;
        while (srcPtr < ptr1)
            *ptr2++ = *srcPtr++;
        *ptr2 = 0;
    }

    //
    //  If we found a fragment, then it is the rest of the string and we
    //  are done.
    //
    if (*srcPtr == chPound)
    {
        srcPtr++;
        xmlURL.fFragment = XMLString::replicate(srcPtr, xmlURL.fMemoryManager);
        return true;
    }

    //
    //  The query is either the rest of the string, or up to the fragment
    //  separator.
    //
    srcPtr++;
    ptr1 = XMLString::findAny(srcPtr, gListSix);
    if (!ptr1)
    {
        xmlURL.fQuery = XMLString::replicate(srcPtr, xmlURL.fMemoryManager);
        return true;
    }
     else
    {
        xmlURL.fQuery = (XMLCh*) xmlURL.fMemoryManager->allocate
        (
            ((ptr1 - srcPtr) + 1) * sizeof(XMLCh)
        );//new XMLCh[(ptr1 - srcPtr) + 1];
        ptr2 = xmlURL.fQuery;
        while (srcPtr < ptr1)
            *ptr2++ = *srcPtr++;
        *ptr2 = 0;
    }

    // If we are not at the end now, then everything else is the fragment
    if (*srcPtr == chPound)
    {
        srcPtr++;
        xmlURL.fFragment = XMLString::replicate(srcPtr, xmlURL.fMemoryManager);
    }

    return true;
}

XERCES_CPP_NAMESPACE_END
