Skip to content
Snippets Groups Projects
XMLString.hpp 53 KiB
Newer Older
PeiYong Zhang's avatar
PeiYong Zhang committed
    /** Tells if the sub-string appears within a string at the beginning
      * without regard to case
      *
      * @param toTest The string to test
      * @param prefix The sub-string that needs to be checked
      *
      * @return Returns true if the sub-string was found at the beginning
      * of <code>toTest</code>, else false
      */
    static bool startsWithI
    (
        const   XMLCh* const    toTest
        , const XMLCh* const    prefix
    );

    /** Tells if the sub-string appears within a string at the end.
      * @param toTest The string to test
      * @param suffix The sub-string that needs to be checked
      * @return Returns true if the sub-string was found at the end of
      * <code>toTest</code>, else false
      */
    static bool endsWith
    (
        const   XMLCh* const    toTest
        , const XMLCh* const    suffix
PeiYong Zhang's avatar
PeiYong Zhang committed
    );


    /** Tells if a string has any occurance of another string within itself
      * @param toSearch The string to be searched
      * @param searchList The sub-string to be searched within the string
      * @return Returns the pointer to the location where the sub-string was
      * found, else returns 0
      */
    static const XMLCh* findAny
    (
        const   XMLCh* const    toSearch
        , const XMLCh* const    searchList
    );

    /** Tells if a string has any occurance of another string within itself
      * @param toSearch The string to be searched
      * @param searchList The sub-string to be searched within the string
      * @return Returns the pointer to the location where the sub-string was
      * found, else returns 0
      */
    static XMLCh* findAny
    (
                XMLCh* const    toSearch
        , const XMLCh* const    searchList
    );

    /** Tells if a string has pattern within itself
      * @param toSearch The string to be searched
      * @param pattern The pattern to be searched within the string
      * @return Returns index to the location where the pattern was
      * found, else returns -1
      */
    static int patternMatch
    (
          const XMLCh* const    toSearch
PeiYong Zhang's avatar
PeiYong Zhang committed
        , const XMLCh* const    pattern
    );

    /** Get the length of the string
      * @param src The string whose length is to be determined
      * @return Returns the length of the string
      */
    static unsigned int stringLen(const char* const src);

    /** Get the length of the string
      * @param src The string whose length is to be determined
      * @return Returns the length of the string
      */
    static unsigned int stringLen(const XMLCh* const src);

    /**
      * Checks whether an name is a valid NCName.
      * @param name The string to check its NCName validity
      * @return Returns true if name is NCName valid, otherwise false
      */
    static bool isValidNCName(const XMLCh* const name);

    /**
      * Checks whether an name is a valid Name.
      * @param name The string to check its Name validity
      * @return Returns true if name is Name valid, otherwise false
      */
    static bool isValidName(const XMLCh* const name);

    /**
      * Checks whether an name is a valid EncName.
      * @param name The string to check its EncName validity
      * @return Returns true if name is EncName valid, otherwise false
      */
    static bool isValidEncName(const XMLCh* const name);
PeiYong Zhang's avatar
PeiYong Zhang committed

    /**
      * Checks whether an name is a valid QName.
      * @param name The string to check its QName validity
      * @return Returns true if name is QName valid, otherwise false
      */
    static bool isValidQName(const XMLCh* const name);
PeiYong Zhang's avatar
PeiYong Zhang committed

    /**
      * Checks whether a character is within [a-zA-Z].
      * @param theChar the character to check
PeiYong Zhang's avatar
PeiYong Zhang committed
      * @return Returns true if within the range, otherwise false
      */

    static bool isAlpha(XMLCh const theChar);

    /**
      * Checks whether a character is within [0-9].
      * @param theChar the character to check
PeiYong Zhang's avatar
PeiYong Zhang committed
      * @return Returns true if within the range, otherwise false
      */
    static bool isDigit(XMLCh const theChar);

    /**
      * Checks whether a character is within [0-9a-zA-Z].
      * @param theChar the character to check
PeiYong Zhang's avatar
PeiYong Zhang committed
      * @return Returns true if within the range, otherwise false
      */
    static bool isAlphaNum(XMLCh const theChar);

    /**
      * Checks whether a character is within [0-9a-fA-F].
      * @param theChar the character to check
PeiYong Zhang's avatar
PeiYong Zhang committed
      * @return Returns true if within the range, otherwise false
      */
    static bool isHex(XMLCh const theChar);

    /**
      * Checks whether a string contains only whitespace.
      * @param toCheck the string to check
PeiYong Zhang's avatar
PeiYong Zhang committed
      * @return Returns true if it is, otherwise false
      */
    static bool isAllWhiteSpace(const XMLCh* const toCheck);

    //@}

    /** @name Conversion functions */
    //@{

    /** Cut leading chars from a string
      *
      * @param toCutFrom The string to cut chars from
      * @param count     The count of leading chars to cut
PeiYong Zhang's avatar
PeiYong Zhang committed
      */
    static void cut
    (
                XMLCh* const    toCutFrom
        , const unsigned int    count
    );

    /** Transcodes a string to native code-page
      *
      * NOTE: The returned buffer is dynamically allocated and is the
      * responsibility of the caller to delete it when not longer needed.
      *
      * @param toTranscode The string to be transcoded
      * @return Returns the transcoded string
      */
    static char* transcode
    (
        const   XMLCh* const    toTranscode
    );

    /** Transcodes a string to native code-page
      *
      * Be aware that when transcoding to an external encoding, that each
      * Unicode char can create multiple output bytes. So you cannot assume
      * a one to one correspondence of input chars to output bytes.
      *
      * @param toTranscode The string tobe transcoded
      * @param toFill The buffer that is filled with the transcoded value.
      *        The size of this buffer should atleast be 'maxChars + 1'.
      * @param maxChars The maximum number of bytes that the output
      *         buffer can hold (not including the null, which is why
      *         toFill should be at least maxChars+1.) If the resulting
      *         output cannot fit into this many bytes, it is an error and
      *         false is returned.
      * @return Returns true if successful, false if there was an error
      */
    static bool transcode
    (
        const   XMLCh* const    toTranscode
        ,       char* const     toFill
        , const unsigned int    maxChars
    );

    /** Transcodes a string to native code-page
      *
      * NOTE: The returned buffer is dynamically allocated and is the
      * responsibility of the caller to delete it when not longer needed.
      *
      * @param toTranscode The string to be transcoded
      * @return Returns the transcoded string
      */
    static XMLCh* transcode
    (
        const   char* const     toTranscode
    );

    /** Transcodes a string to native code-page
      * @param toTranscode The string tobe transcoded
      * @param toFill The buffer that is filled with the transcoded value.
      *        The size of this buffer should atleast be 'maxChars + 1'.
      * @param maxChars The maximum number of characters that the output
      *         buffer can hold (not including the null, which is why
      *         toFill should be at least maxChars+1.) If the resulting
      *         output cannot fit into this many characters, it is an error
      *         and false is returned.
      * @return Returns true if successful, false if there was an error
      */
    static bool transcode
    (
        const   char* const     toTranscode
        ,       XMLCh* const    toFill
        , const unsigned int    maxChars
    );

    /** Trims off extra space characters from the start and end of the string,
      * moving the non-space string content back to the start.
      * @param toTrim The string to be trimmed. On return this contains the
      * trimmed string
      */
    static void trim(char* const toTrim);

    /** Trims off extra space characters from the start and end of the string,
      * moving the non-space string content back to the start.
      * @param toTrim The string to be trimmed. On return this contains
      * the trimmed string
      */
    static void trim(XMLCh* const toTrim);

    /** Break a string into tokens with space as delimiter, and
      * stored in a string vector.  The caller owns the string vector
      * that is returned, and is responsible for deleting it.
      * @param tokenizeSrc String to be tokenized
PeiYong Zhang's avatar
PeiYong Zhang committed
      * @return a vector of all the tokenized string
      */
    static RefVectorOf<XMLCh>* tokenizeString(const XMLCh* const tokenizeSrc);

    /** Find is the string appears in the enum list
      * @param toFind the string to be found
      * @param enumList the list
      * return true if found
      */
    static bool isInList(const XMLCh* const toFind, const XMLCh* const enumList);

    //@}

    /** @name Formatting functions */
    //@{
    /** Creates a UName from a URI and base name. It is in the form
      * {url}name, and is commonly used internally to represent fully
      * qualified names when namespaces are enabled.
      *
      * @param pszURI The URI part of the name
      * @param pszName The base part of the name
      * @return Returns the complete formatted UName
      */
    static XMLCh* makeUName
    (
        const   XMLCh* const    pszURI
        , const XMLCh* const    pszName
    );

    /**
      * Internal function to perform token replacement for strings.
      *
      * @param errText The text (NULL terminated) where the replacement
      *        is to be done. The size of this buffer should be
      *        'maxChars + 1' to account for the final NULL.
      * @param maxChars The size of the output buffer, i.e. the maximum
      *         number of characters that it will hold. If the result is
      *         larger, it will be truncated.
      * @param text1 Replacement text-one
      * @param text2 Replacement text-two
      * @param text3 Replacement text-three
      * @param text4 Replacement text-four
      * @return Returns the count of characters that are outputted
      */
    static unsigned int replaceTokens
    (
                XMLCh* const    errText
        , const unsigned int    maxChars
        , const XMLCh* const    text1
        , const XMLCh* const    text2
        , const XMLCh* const    text3
        , const XMLCh* const    text4
    );

    /** Converts a string to uppercase
      * @param toUpperCase The string which needs to be converted to uppercase.
      *        On return, this buffer also holds the converted uppercase string
      */
    static void upperCase(XMLCh* const toUpperCase);

	/** Converts a string to lowercase
      * @param toLowerCase The string which needs to be converted to lowercase.
      *        On return, this buffer also holds the converted lowercase string
      */
    static void lowerCase(XMLCh* const toLowerCase);

	/** Check if string is WhiteSpace:replace
      * @param toCheck The string which needs to be checked.
      */
    static bool isWSReplaced(const XMLCh* const toCheck);

	/** Check if string is WhiteSpace:collapse
      * @param toCheck The string which needs to be checked.
      */
    static bool isWSCollapsed(const XMLCh* const toCheck);

	/** Replace whitespace
      * @param toConvert The string which needs to be whitespace replaced.
PeiYong Zhang's avatar
PeiYong Zhang committed
      *        On return , this buffer also holds the converted string
      */
    static void replaceWS(XMLCh* const toConvert);

	/** Collapse whitespace
      * @param toConvert The string which needs to be whitespace collapsed.
      *        On return , this buffer also holds the converted string
PeiYong Zhang's avatar
PeiYong Zhang committed
    static void collapseWS(XMLCh* const toConvert);

    /**
     * Fixes a platform dependent absolute path filename to standard URI form.
     * 1. Windows: fix 'x:' to 'file:///x:' and convert any backslash to forward slash
     * 2. UNIX: fix '/blah/blahblah' to 'file:///blah/blahblah'
     * @param str    The string that has the absolute path filename
     * @param target The target string pre-allocated to store the fixed uri
    static void fixURI(const XMLCh* const str, XMLCh* const target);
PeiYong Zhang's avatar
PeiYong Zhang committed
    //@}


private :

    /** @name Constructors and Destructor */
    //@{
    /** Unimplemented default constructor */
    XMLString();
    /** Unimplemented destructor */
    ~XMLString();
    //@}


    /** @name Initialization */
    //@{
    /** Init/Term methods called from XMLPlatformUtils class */
    static void initString(XMLLCPTranscoder* const defToUse);
    static void termString();
    //@}

	/**
	  * Called by regionMatches/regionIMatches to validate that we
	  * have a valid input
	  */
	static bool validateRegion(const XMLCh* const str1, const int offset1,
						const XMLCh* const str2, const int offset2,
						const unsigned int charCount);
PeiYong Zhang's avatar
PeiYong Zhang committed

    friend class XMLPlatformUtils;
};


// ---------------------------------------------------------------------------
//  Inline some methods that are either just passthroughs to other string
//  methods, or which are key for performance.
// ---------------------------------------------------------------------------
inline void XMLString::moveChars(       XMLCh* const    targetStr
                                , const XMLCh* const    srcStr
                                , const unsigned int    count)
{
    XMLCh* outPtr = targetStr;
    const XMLCh* inPtr = srcStr;
    for (unsigned int index = 0; index < count; index++)
        *outPtr++ = *inPtr++;
}

inline unsigned int XMLString::stringLen(const XMLCh* const src)
{
    if (src == 0 || *src == 0)
    {
        return 0;
   }
    else
   {
        const XMLCh* pszTmp = src + 1;

        while (*pszTmp)
            ++pszTmp;

        return (unsigned int)(pszTmp - src);
    }
}

inline bool XMLString::startsWith(  const   XMLCh* const    toTest
                                    , const XMLCh* const    prefix)
{
    return (compareNString(toTest, prefix, stringLen(prefix)) == 0);
}

inline bool XMLString::startsWithI( const   XMLCh* const    toTest
                                    , const XMLCh* const    prefix)
{
    return (compareNIString(toTest, prefix, stringLen(prefix)) == 0);
}

inline bool XMLString::endsWith(const XMLCh* const toTest,
                                const XMLCh* const suffix)
{

    unsigned int suffixLen = XMLString::stringLen(suffix);

    return regionMatches(toTest, XMLString::stringLen(toTest) - suffixLen,
                         suffix, 0, suffixLen);
}

inline XMLCh* XMLString::replicate(const XMLCh* const toRep)
{
    // If a null string, return a null string!
    XMLCh* ret = 0;
    if (toRep)
    {
        const unsigned int len = stringLen(toRep);
        ret = new XMLCh[len + 1];
        XMLCh* outPtr = ret;
        const XMLCh* inPtr = toRep;
        for (unsigned int index = 0; index <= len; index++)
            *outPtr++ = *inPtr++;
    }
    return ret;
}

inline bool XMLString::validateRegion(const XMLCh* const str1,
									  const int offset1,
									  const XMLCh* const str2,
									  const int offset2,
									  const unsigned int charCount)
PeiYong Zhang's avatar
PeiYong Zhang committed
{

	if (offset1 < 0 || offset2 < 0 ||
		(offset1 + charCount) > XMLString::stringLen(str1) ||
		(offset2 + charCount) > XMLString::stringLen(str2) )
PeiYong Zhang's avatar
PeiYong Zhang committed
		return false;

	return true;
}

inline bool XMLString::equals(   const   XMLCh* const    str1
                               , const XMLCh* const    str2)
{
    const XMLCh* psz1 = str1;
    const XMLCh* psz2 = str2;

    if (psz1 == 0 || psz2 == 0) {
        if ((psz1 != 0 && *psz1) || (psz2 != 0 && *psz2))
            return false;
        else
            return true;
    }

    while (*psz1 == *psz2)
    {
        // If either has ended, then they both ended, so equal
        if (!*psz1 || !*psz2)
            return true;

        // Move upwards for the next round
        psz1++;
        psz2++;
    }
    return false;
}


PeiYong Zhang's avatar
PeiYong Zhang committed
#endif