activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject [3/4] https://issues.apache.org/jira/browse/AMQCPP-511
Date Wed, 30 Oct 2013 23:35:30 GMT
http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/b1746b23/activemq-cpp/src/main/decaf/lang/String.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/String.h b/activemq-cpp/src/main/decaf/lang/String.h
index 9b99b20..30d2caf 100644
--- a/activemq-cpp/src/main/decaf/lang/String.h
+++ b/activemq-cpp/src/main/decaf/lang/String.h
@@ -24,6 +24,7 @@
 #include <decaf/lang/Comparable.h>
 
 #include <string>
+#include <ostream>
 
 namespace decaf {
 namespace lang {
@@ -64,6 +65,18 @@ namespace lang {
         String(const std::string& source);
 
         /**
+         * Create a new String object that represents the given array of characters, the C string
+         * must be null terminated in order for a proper size calculation to work.  If the string
+         * is not properly terminated than this method can overrun the array and cause a fault.
+         *
+         * @param array
+         *      The character buffer to copy into this new String object.
+         *
+         * @throws NullPointerException if the character array parameter is NULL.
+         */
+        String(const char* array);
+
+        /**
          * Create a new String object that represents the given array of characters.  The method
          * takes the size of the array as a parameter to allow for strings that are not NULL
          * terminated, the caller can pass strlen(array) in the case where the array is properly
@@ -80,6 +93,24 @@ namespace lang {
         String(const char* array, int size);
 
         /**
+         * Create a new String object that represents the given array of characters, the C string
+         * must be null terminated in order for a proper size calculation to work.  If the string
+         * is not properly terminated than this method can overrun the array and cause a fault.
+         *
+         * @param array
+         *      The character buffer to copy into this new String object.
+         * @param offset
+         *      The position to start copying from in the given buffer.
+         * @param length
+         *      The number of bytes to copy from the given buffer starting from the offset.
+         *
+         * @throws NullPointerException if the character array parameter is NULL.
+         * @throws IndexOutOfBoundsException if the size, offset or length parameter is negative
+         *         or if the length to copy is greater than the span of size - offset.
+         */
+        String(const char* array, int offset, int length);
+
+        /**
          * Create a new String object that represents the given array of characters.  The method
          * takes the size of the array as a parameter to allow for strings that are not NULL
          * terminated, the caller can pass strlen(array) in the case where the array is properly
@@ -104,18 +135,738 @@ namespace lang {
 
     public:
 
-        // TODO
-        String& operator=(const String&);
-        String& operator=(const std::string&);
+        /**
+         * Assignment from another String instance.  The internal contents of this string now
+         * reference the same contents as the provided String.  The original contents of this
+         * String are not altered in other String instances that reference it.
+         *
+         * @param other
+         *      The other String to assign to this instance.
+         *
+         * @returns a reference to this string with the new contents.
+         */
+        String& operator= (const String& other);
+
+        /**
+         * Assignment from another std::string instance.  The internal contents of this string now
+         * reference a copy of the contents as the provided std::string.  The original contents of
+         * this String are not altered in other String instances that reference it.
+         *
+         * @param other
+         *      The other std::string to assign to this instance.
+         *
+         * @returns a reference to this string with the new contents.
+         */
+        String& operator= (const std::string& other);
+
+        /**
+         * Assignment from another C string instance.  The internal contents of this string now
+         * reference a copy of the contents as the provided C string.  The original contents of
+         * this String are not altered in other String instances that reference it.
+         *
+         * @param other
+         *      The other C string to assign to this instance.
+         *
+         * @returns a reference to this string with the new contents.
+         */
+        String& operator= (const char* other);
+
+        /**
+         * Comparison operators for the various string types that uses the equals method
+         * to determine equality.
+         *
+         * @param other
+         *      The string value to compare to this one.
+         *
+         * @returns true if the other string is equal to this one, false otherwise.
+         */
+        bool operator==(const char* other) const;
+        bool operator==(const String& other) const;
+        bool operator==(const std::string& other) const;
+
+        /**
+         * Comparison operators for the various string types that uses the equals method
+         * to determine equality.
+         *
+         * @param other
+         *      The string value to compare to this one.
+         *
+         * @returns true if the other string is not equal to this one, false otherwise.
+         */
+        bool operator!=(const char* other) const;
+        bool operator!=(const String& other) const;
+        bool operator!=(const std::string& other) const;
+
+        /**
+         * Comparison operators for the various string types that uses the compareTo method
+         * to determine the string are lexicographically equal or not.
+         *
+         * @param other
+         *      The string value to compare to this one.
+         *
+         * @returns true if this string is lexicographically less than the other string.
+         */
+        bool operator< (const char* other) const;
+        bool operator< (const String& other) const;
+        bool operator< (const std::string& other) const;
+
+        /**
+         * Concatenation operators for the various string types.  The value of this string
+         * and the given string are concatenated and returned in a new String instance.
+         *
+         * @param other
+         *      The string whose value is to be concatenated with this one.
+         *
+         * @returns a new String instance that is the concatenation of the two strings.
+         */
+        String operator+ (const String& other) const;
+        String operator+ (const std::string& other) const;
+        String operator+ (const char* other) const;
+
+    private:
+
+        // TODO - String is not always NULL terminated at the moment.
+
+        /**
+         * Returns a const char* value to allow easier coexistence with standard c++
+         * string operations.  The value returned will be NULL if the String is empty.
+         *
+         * @returns a const char* value for this String or NULL if empty.
+         */
+        const char* c_str() const;
 
     public:
 
         /**
+         * Compares two strings lexicographically. The comparison is based on the value
+         * of each character in the strings. The character sequence represented by this
+         * String is compared lexicographically to the character sequence represented by
+         * the provided string. The result is a negative number if this String
+         * lexicographically precedes the argument string. The result is a positive value
+         * if this String lexicographically follows the argument string. The result is
+         * zero if the strings are equal; compareTo returns 0 exactly when the equals
+         * method would return true.
+         *
+         * @param string
+         *      the string to compare.
+         *
+         * @return 0 if the strings are equal, a negative integer if this string is
+         *         before the specified string, or a positive integer if this string
+         *         is after the specified string.
+         */
+        int compareTo(const String& string) const;
+
+        /**
+         * Compares two strings lexicographically. The comparison is based on the value
+         * of each character in the strings. The character sequence represented by this
+         * String is compared lexicographically to the character sequence represented by
+         * the provided string. The result is a negative number if this String
+         * lexicographically precedes the argument string. The result is a positive value
+         * if this String lexicographically follows the argument string. The result is
+         * zero if the strings are equal; compareTo returns 0 exactly when the equals
+         * method would return true.
+         *
+         * @param string
+         *      the STL string to compare.
+         *
+         * @return 0 if the strings are equal, a negative integer if this string is
+         *         before the specified string, or a positive integer if this string
+         *         is after the specified string.
+         */
+        int compareTo(const std::string& string) const;
+
+        /**
+         * Compares two strings lexicographically. The comparison is based on the value
+         * of each character in the strings. The character sequence represented by this
+         * String is compared lexicographically to the character sequence represented by
+         * the provided string. The result is a negative number if this String
+         * lexicographically precedes the argument string. The result is a positive value
+         * if this String lexicographically follows the argument string. The result is
+         * zero if the strings are equal; compareTo returns 0 exactly when the equals
+         * method would return true.
+         *
+         * @param string
+         *      the C string to compare.
+         *
+         * @return 0 if the strings are equal, a negative integer if this string is
+         *         before the specified string, or a positive integer if this string
+         *         is after the specified string.
+         *
+         * @throws NullPointerException if the passed in C String value is NULL.
+         */
+        int compareTo(const char* string) const;
+
+        /**
+         * Compares two strings lexicographically, ignoring case differences. This method
+         * returns an integer whose sign is that of calling compareTo with normalized
+         * versions of the strings where case differences have been eliminated by calling
+         * Character::toLowerCase() on each character.
+         *
+         * @param string
+         *      the string to compare.
+         *
+         * @return 0 if the strings are equal, a negative integer if this string is
+         *         before the specified string, or a positive integer if this string
+         *         is after the specified string.
+         */
+        int compareToIgnoreCase(const String& string) const;
+
+        /**
+         * Compares two strings lexicographically, ignoring case differences. This method
+         * returns an integer whose sign is that of calling compareTo with normalized
+         * versions of the strings where case differences have been eliminated by calling
+         * Character::toLowerCase() on each character.
+         *
+         * @param string
+         *      the STL string to compare.
+         *
+         * @return 0 if the strings are equal, a negative integer if this string is
+         *         before the specified string, or a positive integer if this string
+         *         is after the specified string.
+         */
+        int compareToIgnoreCase(const std::string& string) const;
+
+        /**
+         * Compares two strings lexicographically, ignoring case differences. This method
+         * returns an integer whose sign is that of calling compareTo with normalized
+         * versions of the strings where case differences have been eliminated by calling
+         * Character::toLowerCase() on each character.
+         *
+         * @param string
+         *      the C string to compare.
+         *
+         * @return 0 if the strings are equal, a negative integer if this string is
+         *         before the specified string, or a positive integer if this string
+         *         is after the specified string.
+         *
+         * @throws NullPointerException if the passed in C String value is NULL.
+         */
+        int compareToIgnoreCase(const char* string) const;
+
+        /**
+         * Concatenates this string and the specified string.
+         *
+         * @param string
+         *      the string to concatenate onto this String
+         *
+         * @return a new string which is the concatenation of this string and the
+         *         specified string.
+         */
+        String concat(const String& string) const;
+
+        /**
+         * Concatenates this string and the specified std::string.
+         *
+         * @param string
+         *      the STL string to concatenate onto this String
+         *
+         * @return a new string which is the concatenation of this string and the
+         *         specified string.
+         */
+        String concat(const std::string& string) const;
+
+        /**
+         * Concatenates this string and the specified C string.
+         *
+         * @param string
+         *      the C string to concatenate onto this String
+         *
+         * @return a new string which is the concatenation of this string and the
+         *         specified string.
+         */
+        String concat(const char* string) const;
+
+        /**
+         * Determines if this String contains the sequence of characters in the String
+         * passed in.
+         *
+         * @param string
+         *      the String value to search for.
+         *
+         * @return true if the sequence of characters are contained in this String,
+         *         otherwise returns false.
+         */
+        bool contains(const String& string) const;
+
+        /**
+         * Determines if this String contains the sequence of characters in the std::string
+         * passed in.
+         *
+         * @param string
+         *      the STL String value to search for.
+         *
+         * @return true if the sequence of characters are contained in this String,
+         *         otherwise returns false.
+         */
+        bool contains(const std::string& string) const;
+
+        /**
+         * Determines if this String contains the sequence of characters in the C String
+         * passed in.  If the value given is null the method always returns false.
+         *
+         * @param string
+         *      the C String value to search for.
+         *
+         * @return true if the sequence of characters are contained in this String,
+         *         otherwise returns false.
+         */
+        bool contains(const char* string) const;
+
+        /**
+         * Compares the specified string to this string to determine if the
+         * specified string is a suffix.
+         *
+         * @param suffix
+         *            the suffix to look for.
+         *
+         * @return true if the specified string is a suffix of this string, false otherwise.
+         */
+        bool endsWith(const String& suffix) const;
+
+        /**
+         * Returns true if this String is equal to the given String instance.
+         *
+         * @param other
+         *      A String instance to compare to this string.
+         *
+         * @returns true if this String is equal to the given String instance.
+         */
+        bool equals(const String& other) const;
+
+        /**
+         * Returns true if this String is equal to the given std::string instance.
+         *
+         * @param other
+         *      A standard string instance to compare to this String.
+         *
+         * @returns true if this String is equal to the given std::string instance.
+         */
+        bool equals(const std::string& other) const;
+
+        /**
+         * Returns true if this String is equal to the given C string instance.  This method
+         * treats the NULL pointer case as equivalent to the empty string case and returns
+         * true if this String instance is also empty.
+         *
+         * @param other
+         *      A C string instance to compare to this String.
+         *
+         * @returns true if this String is equal to the given C string instance.
+         */
+        bool equals(const char* other) const;
+
+        /**
+         * Compares the specified string to this string ignoring the case of the
+         * characters and returns true if they are equal.
+         *
+         * @param string
+         *      the string to compare.
+         *
+         * @return true if the specified string is equal to this string, false otherwise.
+         */
+        bool equalsIgnoreCase(const String& string) const;
+
+        /**
+         * Compares the specified std::string to this String ignoring the case of the
+         * characters and returns true if they are equal.
+         *
+         * @param string
+         *      the std::string to compare.
+         *
+         * @return true if the specified string is equal to this String, false otherwise.
+         */
+        bool equalsIgnoreCase(const std::string& string) const;
+
+        /**
+         * Compares the specified C string to this string ignoring the case of the
+         * characters and returns true if they are equal.
+         *
+         * @param string
+         *      the C string to compare.
+         *
+         * @return true if the specified C string is equal to this string, false otherwise.
+         */
+        bool equalsIgnoreCase(const char* string) const;
+
+        /**
+         * Returns a hash code for this String instance, the hash code for an empty
+         * String will always be zero.
+         *
+         * @returns a hash code for this String instance.
+         */
+        int hashCode() const;
+
+        /**
+         * Searches in this string for the first index of the specified character.
+         * The search for the character starts at the beginning and moves towards
+         * the end of this string.
+         *
+         * @param c
+         *      the character to find.
+         *
+         * @return the index in this string of the specified character, -1 if the
+         *         character isn't found.
+         */
+        int indexOf(char value) const;
+
+        /**
+         * Searches in this string for the index of the specified character. The
+         * search for the character starts at the specified offset and moves towards
+         * the end of this string.
+         *
+         * If the start value given is less than zero the search starts at the beginning
+         * of the string.  If the start value is greater than the length of the string
+         * minus one is returned.
+         *
+         * @param value
+         *      the character to find.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index in this string of the specified character, -1 if the
+         *         character isn't found.
+         */
+        int indexOf(char value, int start) const;
+
+        /**
+         * Searches in this string for the first index of the specified string. The
+         * search for the string starts at the beginning and moves towards the end
+         * of this string.
+         *
+         * @param string
+         *      the string to find within this String.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int indexOf(const String& string) const;
+
+        /**
+         * Searches in this string for the index of the specified string. The search
+         * for the string starts at the specified offset and moves towards the end
+         * of this string.
+         *
+         * @param subString
+         *      the string to find within this String.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int indexOf(const String& subString, int start) const;
+
+        /**
+         * Searches in this String for the first index of the specified std::string. The
+         * search for the string starts at the beginning and moves towards the end
+         * of this string.
+         *
+         * @param string
+         *      the STL string to find within this String.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int indexOf(const std::string& string) const;
+
+        /**
+         * Searches in this string for the index of the specified std::string. The search
+         * for the string starts at the specified offset and moves towards the end
+         * of this string.
+         *
+         * @param subString
+         *      the STL string to find within this String.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int indexOf(const std::string& subString, int start) const;
+
+        /**
+         * Searches in this String for the first index of the specified C string. The
+         * search for the string starts at the beginning and moves towards the end
+         * of this string.  If the given string pointer is NULL this method returns -1.
+         *
+         * @param string
+         *      the C string to find within this String.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int indexOf(const char* string) const;
+
+        /**
+         * Searches in this string for the index of the specified C string. The search
+         * for the string starts at the specified offset and moves towards the end
+         * of this string.  If the given string pointer is NULL this method returns -1.
+         *
+         * @param subString
+         *      the C string to find within this String.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int indexOf(const char* subString, int start) const;
+
+        /**
          * @returns true if the length of this String is zero.
          */
         bool isEmpty() const;
 
         /**
+         * Searches in this string for the last index of the specified character.
+         * The search for the character starts at the end and moves towards the
+         * beginning of this string.
+         *
+         * @param value
+         *      the character to find.
+         *
+         * @return the index in this string of the specified character, -1 if the
+         *         character isn't found.
+         */
+        int lastIndexOf(char value) const;
+
+        /**
+         * Searches in this string for the index of the specified character. The
+         * search for the character starts at the specified offset and moves towards
+         * the beginning of this string.
+         *
+         * @param value
+         *      the character to find.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index in this string of the specified character, -1 if the
+         *         character isn't found.
+         */
+        int lastIndexOf(char value, int start) const;
+
+        /**
+         * Searches in this string for the last index of the specified string. The
+         * search for the string starts at the end and moves towards the beginning
+         * of this string.
+         *
+         * @param string
+         *      the string to find.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int lastIndexOf(const String& string) const;
+
+        /**
+         * Searches in this string for the index of the specified string. The search
+         * for the string starts at the specified offset and moves towards the
+         * beginning of this string.
+         *
+         * @param subString
+         *      the string to find.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string , -1 if the specified string is not a substring.
+         */
+        int lastIndexOf(const String& subString, int start) const;
+
+        /**
+         * Searches in this string for the last index of the specified std::string. The
+         * search for the string starts at the end and moves towards the beginning
+         * of this string.
+         *
+         * @param string
+         *      the STL string to find.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int lastIndexOf(const std::string& string) const;
+
+        /**
+         * Searches in this string for the index of the specified std::string. The search
+         * for the string starts at the specified offset and moves towards the
+         * beginning of this string.
+         *
+         * @param subString
+         *      the STL string to find.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string , -1 if the specified string is not a substring.
+         */
+        int lastIndexOf(const std::string& subString, int start) const;
+
+        /**
+         * Searches in this string for the last index of the specified C string. The
+         * search for the string starts at the end and moves towards the beginning
+         * of this string.
+         *
+         * @param string
+         *      the C string to find.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string, -1 if the specified string is not a substring.
+         */
+        int lastIndexOf(const char* string) const;
+
+        /**
+         * Searches in this string for the index of the specified C string. The search
+         * for the string starts at the specified offset and moves towards the
+         * beginning of this string.
+         *
+         * @param subString
+         *      the C string to find.
+         * @param start
+         *      the starting offset.
+         *
+         * @return the index of the first character of the specified string in this
+         *         string , -1 if the specified string is not a substring.
+         */
+        int lastIndexOf(const char* subString, int start) const;
+
+        /**
+         * Compares the specified string to this string and compares the specified
+         * range of characters to determine if they are the same.  The method returns
+         * false is any of the index values are negative or result in a span that would
+         * exceed the length of either string.
+         *
+         * @param thisStart
+         *      the starting offset in this string.
+         * @param string
+         *      the string to compare.
+         * @param start
+         *      the starting offset in the specified string.
+         * @param length
+         *      the number of characters to compare.
+         *
+         * @return true if the ranges of characters are equal, false otherwise
+         */
+        bool regionMatches(int thisStart, const String& string, int start, int length) const;
+
+        /**
+         * Compares the specified string to this string and compares the specified
+         * range of characters to determine if they are the same. When ignoreCase is
+         * true, the case of the characters is ignored during the comparison.
+         *
+         * @param ignoreCase
+         *      specifies if case should be ignored.
+         * @param thisStart
+         *      the starting offset in this string.
+         * @param string
+         *      the string to compare.
+         * @param start
+         *      the starting offset in the specified string.
+         * @param length
+         *      the number of characters to compare.
+         *
+         * @return true if the ranges of characters are equal, false otherwise.
+         */
+        bool regionMatches(bool ignoreCase, int thisStart, const String& string, int start, int length) const;
+
+        /**
+         * Copies this string replacing occurrences of the specified character with
+         * another character.
+         *
+         * @param oldChar
+         *      the character to replace.
+         * @param newChar
+         *      the replacement character.
+         *
+         * @return a new string with occurrences of oldChar replaced by newChar.
+         */
+        String replace(char oldChar, char newChar) const;
+
+        /**
+         * Compares the specified string to this string to determine if the specified
+         * string is a prefix.  If the prefix string is empty or is equal to this String
+         * than true is returned.
+         *
+         * @param prefix
+         *      the string to look for.
+         *
+         * @return if the specified string is a prefix of this string, false otherwise
+         */
+        bool startsWith(const String& prefix) const;
+
+        /**
+         * Compares the specified string to this string, starting at the specified
+         * offset, to determine if the specified string is a prefix.
+         *
+         * @param prefix
+         *      the string to look for.
+         * @param start
+         *      the starting offset.
+         *
+         * @return true if the specified string occurs in this string at the specified
+         *         offset, false otherwise.
+         */
+        bool startsWith(const String& prefix, int start) const;
+
+        /**
+         * Copies a range of characters into a new string starting from the given offset and
+         * extending to the end of this String.
+         *
+         * @param start
+         *      the offset of the first character.
+         *
+         * @return a new string containing the characters from start to the end of the string.
+         *
+         * @throws IndexOutOfBoundsException if start < 0 or start > length().
+         */
+        String substring(int start) const;
+
+        /**
+         * Copies a range of characters into a new string.  The length of the returned String
+         * is end - start meaning that the characters in the new string include only start to
+         * end - 1.
+         *
+         * @param start
+         *      the offset of the first character. (inclusive)
+         * @param end
+         *      the offset one past the last character. (exclusive)
+         *
+         * @return a new string containing the characters from start to end - 1.
+         *
+         * @throws IndexOutOfBoundsException if start < 0, start > end or end > length().
+         */
+        String substring(int start, int end) const;
+
+        /**
+         * Copies the characters in this string to a newly allocated character array.  The
+         * returned array is the property of the caller and must be deleted by them.  If the
+         * String is empty then a NULL is returned.
+         *
+         * The array returned is not guaranteed to be null terminated as the array is
+         * sized according to the result of calling length().
+         *
+         * @return a character array containing the characters of this string.
+         */
+        char* toCharArray() const;
+
+        /**
+         * Converts the characters in this string to lower case.  The resulting value
+         * is returned in a new String instance and this one is left unchanged.
+         *
+         * @return a new string containing the lower case characters equivalent to
+         *         the characters in this string.
+         */
+        String toLowerCase() const;
+
+        /**
+         * Converts the characters in this string to upper case.  The resulting value
+         * is returned in a new String instance and this one is left unchanged.
+         *
+         * @return a new string containing the upper case characters equivalent to
+         *         the characters in this string.
+         */
+        String toUpperCase() const;
+
+        /**
          * Returns a copy of the string, with leading and trailing whitespace omitted.
          *
          * @returns a copy of the string, with leading and trailing whitespace omitted.
@@ -147,6 +898,48 @@ namespace lang {
     public:
 
         /**
+         * Creates a new string containing the characters in the specified character
+         * array. Modifying the character array after creating the string has no
+         * effect on the string.
+         *
+         * @param data
+         *      the array of characters.
+         *
+         * @return the new string.
+         *
+         * @throws NullPointerException if the C string pointer is NULL
+         */
+        static String copyValueOf(const char* data);
+
+        /**
+         * Creates a new string containing the specified characters in the character
+         * array. Modifying the character array after creating the string has no
+         * effect on the string.
+         *
+         * @param data
+         *      the array of characters.
+         * @param start
+         *      the starting offset in the character array.
+         * @param length
+         *      the number of characters to use.
+         *
+         * @return the new string.
+         *
+         * @throws NullPointerException if the C string is NULL
+         * @throws IndexOutOfBoundsException
+         *         if length < 0, start < 0 or start + length > the C string's length.
+         */
+        static String copyValueOf(char* data, int start, int length);
+
+        /**
+         * Given a C String pointer return true if the value is either NULL or the
+         * string contained is empty.
+         *
+         * @returns true if the C string is either a NULL or an Empty string.
+         */
+        static bool isNullOrEmpty(const char*);
+
+        /**
          * Returns a String that represents the value of the given boolean value.
          *
          * @param value
@@ -216,8 +1009,15 @@ namespace lang {
          */
         static String valueOf(long long value);
 
+    private:
+
+        String(Contents* content);
+        String(int offset, int length, Contents* content);
+
     };
 
+    std::ostream& operator<<(std::ostream &out, const String& target);
+
 }}
 
 #endif /* _DECAF_LANG_STRING_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/b1746b23/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.cpp b/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.cpp
new file mode 100644
index 0000000..5fbda1d
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#include "ArrayIndexOutOfBoundsException.h"
+
+#include <decaf/lang/Integer.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException() : IndexOutOfBoundsException() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(int index) : IndexOutOfBoundsException() {
+    this->setMessage("Array index out of range: %d", index);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::~ArrayIndexOutOfBoundsException() throw () {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(const Exception& ex) : IndexOutOfBoundsException() {
+    *(Exception*) this = ex;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(const ArrayIndexOutOfBoundsException& ex) : IndexOutOfBoundsException() {
+    *(Exception*) this = ex;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(const std::exception* cause) : IndexOutOfBoundsException(cause) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(const char* file, const int lineNumber, const char* msg, ...) : IndexOutOfBoundsException() {
+
+    va_list vargs;
+    va_start(vargs, msg);
+    buildMessage(msg, vargs);
+
+    // Set the first mark for this exception.
+    setMark(file, lineNumber);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(const char* file, const int lineNumber, int index) : IndexOutOfBoundsException() {
+    setMark(file, lineNumber);
+    this->setMessage("Array index out of range: %d", index);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(const char* file, const int lineNumber, const std::exception* cause, const char* msg, ...) : IndexOutOfBoundsException(cause) {
+
+    va_list vargs;
+    va_start(vargs, msg);
+    buildMessage(msg, vargs);
+
+    // Set the first mark for this exception.
+    setMark(file, lineNumber);
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/b1746b23/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.h b/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.h
new file mode 100644
index 0000000..c16e439
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/exceptions/ArrayIndexOutOfBoundsException.h
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+#ifndef _DECAF_LANG_EXCEPTIONS_ARRAYINDEXOUTOFBOUNDSEXCEPTION_H_
+#define _DECAF_LANG_EXCEPTIONS_ARRAYINDEXOUTOFBOUNDSEXCEPTION_H_
+
+#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
+
+namespace decaf {
+namespace lang {
+namespace exceptions {
+
+    /*
+     * Thrown when an operation is requested, but the array index would result in
+     * an access that is outside the bounds of the array.
+     *
+     * @since 1.0
+     */
+    class DECAF_API ArrayIndexOutOfBoundsException : public IndexOutOfBoundsException {
+    public:
+
+        /**
+         * Default Constructor
+         */
+        ArrayIndexOutOfBoundsException();
+
+        /**
+         * Create a new ArrayIndexOutOfBoundsException with the given index value
+         * to use to create the error message.
+         *
+         * @param index
+         *      The given string index that was out of bounds.
+         */
+        ArrayIndexOutOfBoundsException(int index);
+
+        /**
+         * Conversion Constructor from some other Exception
+         *
+         * @param ex
+         *      The Exception whose data is to be copied into this one.
+         */
+        ArrayIndexOutOfBoundsException(const Exception& ex);
+
+        /**
+         * Copy Constructor
+         *
+         * @param ex
+         *      The Exception whose data is to be copied into this one.
+         */
+        ArrayIndexOutOfBoundsException(const ArrayIndexOutOfBoundsException& ex);
+
+        /**
+         * Constructor - Initializes the file name and line number where
+         * this message occurred.  Sets the message to report, using an
+         * optional list of arguments to parse into the message
+         *
+         * @param file
+         *      The file name where exception occurs
+         * @param lineNumber
+         *      The line number where the exception occurred.
+         * @param cause
+         *      The exception that was the cause for this one to be thrown.
+         * @param msg
+         *      The message to report
+         * @param ...
+         *      list of primitives that are formatted into the message
+         */
+        ArrayIndexOutOfBoundsException(const char* file, const int lineNumber, const std::exception* cause, const char* msg, ...);
+
+        /**
+         * Constructor
+         *
+         * @param cause
+         *      Pointer to the exception that caused this one to be thrown, the
+         *      object is cloned caller retains ownership.
+         */
+        ArrayIndexOutOfBoundsException(const std::exception* cause);
+
+        /**
+         * Constructor - Initializes the file name and line number where
+         * this message occurred.  Sets the message to report, using an
+         * optional list of arguments to parse into the message
+         *
+         * @param file
+         *      The file name where exception occurs
+         * @param lineNumber
+         *      The line number where the exception occurred.
+         * @param msg
+         *      The message to report
+         * @param ...
+         *      list of primitives that are formatted into the message
+         */
+        ArrayIndexOutOfBoundsException(const char* file, const int lineNumber, const char* msg, ...);
+
+        /**
+         * Constructor - Initializes the file name and line number where
+         * this message occurred.  Sets the message to report, using the
+         * given index.
+         *
+         * @param file
+         *      The file name where exception occurs
+         * @param lineNumber
+         *      The line number where the exception occurred.
+         * @param index
+         *      The string index that was out of bounds.
+         */
+        ArrayIndexOutOfBoundsException(const char* file, const int lineNumber, int index);
+
+        /**
+         * Clones this exception.  This is useful for cases where you need
+         * to preserve the type of the original exception as well as the message.
+         * All subclasses should override.
+         *
+         * @return an new Exception instance that is a copy of this one.
+         */
+        virtual ArrayIndexOutOfBoundsException* clone() const {
+            return new ArrayIndexOutOfBoundsException(*this);
+        }
+
+        virtual ~ArrayIndexOutOfBoundsException() throw();
+
+    };
+
+}}}
+
+#endif /*_DECAF_LANG_EXCEPTIONS_ARRAYINDEXOUTOFBOUNDSEXCEPTION_H_*/

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/b1746b23/activemq-cpp/src/main/decaf/net/URL.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/net/URL.cpp b/activemq-cpp/src/main/decaf/net/URL.cpp
index 8b003e8..87c7f68 100644
--- a/activemq-cpp/src/main/decaf/net/URL.cpp
+++ b/activemq-cpp/src/main/decaf/net/URL.cpp
@@ -17,6 +17,8 @@
 
 #include "URL.h"
 
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/String.h>
 #include <decaf/lang/Pointer.h>
 #include <decaf/net/URI.h>
 #include <decaf/net/URLConnection.h>
@@ -28,10 +30,14 @@
 #include <decaf/util/HashMap.h>
 #include <decaf/util/concurrent/Mutex.h>
 
+#include <decaf/internal/net/URLStreamHandlerManager.h>
+
 using namespace std;
 using namespace decaf;
 using namespace decaf::io;
 using namespace decaf::net;
+using namespace decaf::internal;
+using namespace decaf::internal::net;
 using namespace decaf::util;
 using namespace decaf::util::concurrent;
 using namespace decaf::lang;
@@ -49,191 +55,37 @@ namespace net {
         URLType url;
         Pointer<URLStreamHandler> streamHandler;
 
-        static URLStreamHandlerFactory* streamHandlerFactory;
-        static HashMap<std::string, URLStreamHandler*> streamHandlers;
-
     public:
 
         URLImpl() : url(), streamHandler() {}
 
-        void initialize(const URL* context, const std::string& spec, URLStreamHandler* handler) {
-            if (handler != NULL) {
-                streamHandler.reset(handler);
+        void fixURL(bool fixHost) {
+            int index;
+            if (!url.getHost().isEmpty()) {
+                url.setAuthority(url.getHost());
+                if (url.getPort() != -1) {
+                    url.setAuthority(url.getAuthority() + ":" + Integer::toString(url.getPort()));
+                }
             }
 
-            if (spec.empty()) {
-                throw MalformedURLException(__FILE__, __LINE__, "spec was NULL");
+            if (fixHost) {
+                String host = url.getHost();
+                if (!host.isEmpty() && (index = host.lastIndexOf('@')) > -1) {
+                    url.setUserInfo(host.substring(0, index));
+                    url.setHost(host.substring(index + 1));
+                } else {
+                    url.setUserInfo("");
+                }
             }
-//            // spec = spec.trim();  // trim
-//
-//            // The spec includes a protocol if it includes a colon character
-//            // before the first occurrence of a slash character. Note that,
-//            // "protocol" is the field which holds this URLs protocol.
-//            int index;
-//            try {
-//                index = spec.indexOf(':');
-//            } catch (NullPointerException e) {
-//                throw new MalformedURLException(e.toString());
-//            }
-//            int startIPv6Addr = spec.indexOf('[');
-//            if (index >= 0) {
-//                if ((startIPv6Addr == -1) || (index < startIPv6Addr)) {
-//                    protocol = spec.substring(0, index);
-//                    // According to RFC 2396 scheme part should match
-//                    // the following expression:
-//                    // alpha *( alpha | digit | "+" | "-" | "." )
-//                    char c = protocol.charAt(0);
-//                    boolean valid = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
-//                    for (int i = 1; valid && (i < protocol.length()); i++) {
-//                        c = protocol.charAt(i);
-//                        valid = ('a' <= c && c <= 'z') ||
-//                                ('A' <= c && c <= 'Z') ||
-//                                ('0' <= c && c <= '9') ||
-//                                (c == '+') ||
-//                                (c == '-') ||
-//                                (c == '.');
-//                    }
-//                    if (!valid) {
-//                        protocol = NULL;
-//                        index = -1;
-//                    } else {
-//                        // Ignore case in protocol names.
-//                        // Scheme is defined by ASCII characters.
-//                        protocol = Util.toASCIILowerCase(protocol);
-//                    }
-//                }
-//            }
-//
-//            if (url.getProtocol().empty()) {
-//                // If the context was specified, and it had the same protocol
-//                // as the spec, then fill in the receiver's slots from the values
-//                // in the context but still allow them to be over-ridden later
-//                // by the values in the spec.
-//                if (context != NULL && protocol.equals(context.getProtocol())) {
-//                    String cPath = context.getPath();
-//                    if (cPath != NULL && cPath.startsWith("/")) {
-//                        set(protocol, context.getHost(), context.getPort(), context
-//                                .getAuthority(), context.getUserInfo(), cPath,
-//                                context.getQuery(), NULL);
-//                    }
-//                    if (streamHandler == NULL) {
-//                        streamHandler = context.streamHandler;
-//                    }
-//                }
-//            } else {
-//                // If the spec did not include a protocol, then the context
-//                // *must* be specified. Fill in the receiver's slots from the
-//                // values in the context, but still allow them to be over-ridden
-//                // by the values in the ("relative") spec.
-//                if (context == NULL) {
-//                    throw MalformedURLException(__FILE__, __LINE__, "Protocol not found: %s", spec);
-//                }
-//                set(context.getProtocol(), context.getHost(), context.getPort(),
-//                        context.getAuthority(), context.getUserInfo(), context
-//                                .getPath(), context.getQuery(), NULL);
-//                if (streamHandler == NULL) {
-//                    streamHandler = context.streamHandler;
-//                }
-//            }
-//
-//            // If the stream handler has not been determined, set it
-//            // to the default for the specified protocol.
-//            if (streamHandler == NULL) {
-//                setupStreamHandler();
-//                if (streamHandler == NULL) {
-//                    throw MalformedURLException(__FILE__, __LINE__, "unknown protocol: %s", url.getProtocol().c_str());
-//                }
-//            }
-//
-//            // Let the handler parse the URL. If the handler throws
-//            // any exception, throw MalformedURLException instead.
-//            //
-//            // Note: We want "index" to be the index of the start of the scheme
-//            // specific part of the URL. At this point, it will be either
-//            // -1 or the index of the colon after the protocol, so we
-//            // increment it to point at either character 0 or the character
-//            // after the colon.
-//            try {
-//                streamHandler->parseURL(*this, spec, ++index, (int) spec.length());
-//            } catch (Exception& e) {
-//                throw MalformedURLException(__FILE__, __LINE__, e.getMessage());
-//            }
-//
-//            if (url.getPort() < -1) {
-//                throw MalformedURLException(__FILE__, __LINE__, "port out of range: %d", url.getPort());
-//            }
-        }
 
-        void initialize(const std::string& protocol, const std::string& host, int port,
-                        const std::string& file, const URLStreamHandler* handler) {
-
-            if (port < -1) {
-                throw MalformedURLException(__FILE__, __LINE__, "Port out of range: %d", port);
+            String file = url.getFile();
+            if (!file.isEmpty() && (index = file.indexOf('?')) > -1) {
+                url.setQuery(file.substring(index + 1));
+                url.setPath(file.substring(0, index));
+            } else {
+                url.setQuery("");
+                url.setPath(url.getFile());
             }
-
-//            if (host != NULL && host.indexOf(":") != -1 && host.charAt(0) != '[') {
-//                host = "[" + host + "]";
-//            }
-//
-//            if (protocol == NULL) {
-//                throw NullPointerException(
-//                    __FILE__, __LINE__, "Unknown protocol: %s", "NULL");
-//            }
-//
-//            url.setProtocol(protocol);
-//            url.setHost(host);
-//            url.setPort(port);
-//
-//            // Set the fields from the arguments. Handle the case where the
-//            // passed in "file" includes both a file and a reference part.
-//            std::size_t index = -1;
-//            index = file.find_first_of("#", file.find_last_of("/"));
-//            if (index != string::npos) {
-//                url.setFile(file.substr(0, index));
-//                url.setRef(file.substr(index + 1));
-//            } else {
-//                url.setFile(file);
-//            }
-//            fixURL(false);
-//
-//            // Set the stream handler for the URL either to the handler argument if it was
-//            // specified, or to the default for the receiver's protocol if the handler was NULL.
-//            if (handler == NULL) {
-//                setupStreamHandler();
-//                if (streamHandler == NULL) {
-//                    throw MalformedURLException(
-//                        __FILE__, __LINE__, "Unknown protocol: %s", protocol.c_str());
-//                }
-//            } else {
-//                streamHandler = handler;
-//            }
-        }
-
-        void fixURL(bool fixHost) {
-//            int index;
-//            if (!url.getHost().empty()) {
-//                url.setAuthority(url.getHost());
-//                if (url.getPort() != -1) {
-//                    url.setAuthority(url.getAuthority() + ":" + Integer::toString(url.getPort()));
-//                }
-//            }
-//
-//            if (fixHost) {
-//                if (host != NULL && (index = host.lastIndexOf('@')) > -1) {
-//                    userInfo = host.substring(0, index);
-//                    host = host.substring(index + 1);
-//                } else {
-//                    url.setUserInfo("");
-//                }
-//            }
-//
-//            if (file != NULL && (index = file.indexOf('?')) > -1) {
-//                query = file.substring(index + 1);
-//                path = file.substring(0, index);
-//            } else {
-//                url.setQuery("");
-//                url.setPath(url.getFile());
-//            }
         }
 
         /**
@@ -246,97 +98,202 @@ namespace net {
          * method if they do not want this behavior (a speed optimization).
          */
         void setupStreamHandler() {
-//            // Check for a cached (previously looked up) handler for the requested protocol.
-//            streamHandler = streamHandlers.get(protocol);
-//            if (streamHandler != NULL) {
-//                return;
-//            }
-//
-//            // If there is a stream handler factory, then attempt to
-//            // use it to create the handler.
-//            if (streamHandlerFactory != NULL) {
-//                streamHandler = streamHandlerFactory.createURLStreamHandler(protocol);
-//                if (streamHandler != NULL) {
-//                    streamHandlers.put(protocol, streamHandler);
-//                    return;
-//                }
-//            }
-//
-//            // Check if there is a list of packages which can provide handlers.
-//            // If so, then walk this list looking for an applicable one.
-//            String packageList = AccessController
-//                    .doPrivileged(new PriviAction<String>(
-//                            "java.protocol.handler.pkgs")); //$NON-NLS-1$
-//            if (packageList != NULL) {
-//                StringTokenizer st = new StringTokenizer(packageList, "|"); //$NON-NLS-1$
-//                while (st.hasMoreTokens()) {
-//                    String className = st.nextToken() + "." + protocol + ".Handler"; //$NON-NLS-1$ //$NON-NLS-2$
-//
-//                    try {
-//                        streamHandler = (URLStreamHandler) Class.forName(className,
-//                                true, ClassLoader.getSystemClassLoader())
-//                                .newInstance();
-//                        if (streamHandler != NULL) {
-//                            streamHandlers.put(protocol, streamHandler);
-//                        }
-//                        return;
-//                    } catch (IllegalAccessException e) {
-//                    } catch (InstantiationException e) {
-//                    } catch (ClassNotFoundException e) {
-//                    }
-//                }
-//            }
-//
-//            // No one else has provided a handler, so try our internal one.
-//
-//            String className = "org.apache.harmony.luni.internal.net.www.protocol." + protocol //$NON-NLS-1$
-//                    + ".Handler"; //$NON-NLS-1$
-//            try {
-//                streamHandler = (URLStreamHandler) Class.forName(className)
-//                        .newInstance();
-//            } catch (IllegalAccessException e) {
-//            } catch (InstantiationException e) {
-//            } catch (ClassNotFoundException e) {
-//            }
-//            if (streamHandler != NULL) {
-//                streamHandlers.put(protocol, streamHandler);
-//            }
+            URLStreamHandlerManager* manager = URLStreamHandlerManager::getInstance();
+            streamHandler.reset(manager->getURLStreamHandler(url.getProtocol()));
         }
     };
 
-    URLStreamHandlerFactory* URLImpl::streamHandlerFactory;
-    HashMap<std::string, URLStreamHandler*> URLImpl::streamHandlers;
 }}
 
 ////////////////////////////////////////////////////////////////////////////////
 URL::URL(const std::string& url) : impl(new URLImpl) {
-    impl->initialize(NULL, url, NULL);
+    initialize(NULL, url, NULL);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 URL::URL(const URL& context, const std::string& spec) : impl(new URLImpl) {
-    impl->initialize(&context, spec, NULL);
+    initialize(&context, spec, NULL);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 URL::URL(const URL& context, const std::string& spec, URLStreamHandler* streamHandler) : impl(new URLImpl) {
-    impl->initialize(&context, spec, streamHandler);
+    initialize(&context, spec, streamHandler);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 URL::URL(const std::string& protocol, const std::string& host, int port,
          const std::string& file, URLStreamHandler* handler) : impl(new URLImpl) {
-    impl->initialize(protocol, host, port, file, handler);
+    initialize(protocol, host, port, file, handler);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 URL::URL(const std::string& protocol, const std::string& host, const std::string& file) : impl(new URLImpl) {
-    impl->initialize(protocol, host, -1, file, NULL);
+    initialize(protocol, host, -1, file, NULL);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 URL::URL(const std::string& protocol, const std::string& host, int port, const std::string& file) : impl() {
-    impl->initialize(protocol, host, port, file, NULL);
+    initialize(protocol, host, port, file, NULL);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void URL::initialize(const URL* context, const String& theSpec, URLStreamHandler* handler) {
+    if (handler != NULL) {
+        impl->streamHandler.reset(handler);
+    }
+
+    if (theSpec.isEmpty()) {
+        throw MalformedURLException(__FILE__, __LINE__, "spec was NULL");
+    }
+    String spec = theSpec.trim();  // trim
+
+    // The spec includes a protocol if it includes a colon character
+    // before the first occurrence of a slash character. Note that,
+    // "protocol" is the field which holds this URLs protocol.
+    int index = spec.indexOf(':');
+    String protocol;
+    int startIPv6Addr = spec.indexOf('[');
+    if (index >= 0) {
+        if ((startIPv6Addr == -1) || (index < startIPv6Addr)) {
+            protocol = spec.substring(0, index);
+            impl->url.setProtocol(protocol);
+            // According to RFC 2396 scheme part should match the following expression:
+            // alpha *( alpha | digit | "+" | "-" | "." )
+            char c = protocol.charAt(0);
+            bool valid = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
+            for (int i = 1; valid && (i < protocol.length()); i++) {
+                c = protocol.charAt(i);
+                valid = ('a' <= c && c <= 'z') ||
+                        ('A' <= c && c <= 'Z') ||
+                        ('0' <= c && c <= '9') ||
+                        (c == '+') ||
+                        (c == '-') ||
+                        (c == '.');
+            }
+            if (!valid) {
+                impl->url.setProtocol(String());
+                index = -1;
+            } else {
+                // Ignore case in protocol names.
+                // Scheme is defined by ASCII characters.
+                impl->url.setProtocol(protocol.toLowerCase());
+            }
+        }
+    }
+
+    if (!impl->url.getProtocol().isEmpty()) {
+        // If the context was specified, and it had the same protocol
+        // as the spec, then fill in the receiver's slots from the values
+        // in the context but still allow them to be over-ridden later
+        // by the values in the spec.
+        if (context != NULL && protocol.equals(context->getProtocol())) {
+            String cPath = context->getPath();
+            if (cPath.startsWith("/")) {
+                set(protocol, context->getHost(), context->getPort(),
+                    context->getAuthority(), context->getUserInfo(), cPath,
+                    context->getQuery(), String());
+            }
+            if (impl->streamHandler == NULL) {
+                impl->streamHandler = context->impl->streamHandler;
+            }
+        }
+    } else {
+        // If the spec did not include a protocol, then the context
+        // *must* be specified. Fill in the receiver's slots from the
+        // values in the context, but still allow them to be over-ridden
+        // by the values in the ("relative") spec.
+        if (context == NULL) {
+            throw MalformedURLException(
+                __FILE__, __LINE__,
+                (std::string("Protocol not found: ") + spec.toString()).c_str());
+        }
+        set(context->getProtocol(), context->getHost(), context->getPort(),
+            context->getAuthority(), context->getUserInfo(),
+            context->getPath(), context->getQuery(), String());
+        if (impl->streamHandler == NULL) {
+            impl->streamHandler = context->impl->streamHandler;
+        }
+    }
+
+    // If the stream handler has not been determined, set it
+    // to the default for the specified protocol.
+    if (impl->streamHandler == NULL) {
+        impl->setupStreamHandler();
+        if (impl->streamHandler == NULL) {
+            throw MalformedURLException(
+                __FILE__, __LINE__,
+                (std::string("unknown protocol: ") + impl->url.getProtocol().toString()).c_str());
+        }
+    }
+
+    // Let the handler parse the URL. If the handler throws
+    // any exception, throw MalformedURLException instead.
+    //
+    // Note: We want "index" to be the index of the start of the scheme
+    // specific part of the URL. At this point, it will be either
+    // -1 or the index of the colon after the protocol, so we
+    // increment it to point at either character 0 or the character
+    // after the colon.
+    try {
+        impl->streamHandler->parseURL(*this, spec, ++index, (int) spec.length());
+    } catch (Exception& e) {
+        throw MalformedURLException(__FILE__, __LINE__, e.getMessage().c_str());
+    }
+
+    if (impl->url.getPort() < -1) {
+        throw MalformedURLException(
+            __FILE__, __LINE__, "port out of range: %d", impl->url.getPort());
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void URL::initialize(const String& protocol, const String& host, int port,
+                     const String& file, URLStreamHandler* handler) {
+
+    if (port < -1) {
+        throw MalformedURLException(__FILE__, __LINE__, "Port out of range: %d", port);
+    }
+
+    String theHost;
+
+    if (host.indexOf(":") != -1 && host.charAt(0) != '[') {
+        theHost = String("[").concat(host).concat("]");
+    } else {
+        theHost = host;
+    }
+
+    if (protocol.isEmpty()) {
+        throw NullPointerException(
+        __FILE__, __LINE__, "Unknown protocol: %s", "NULL");
+    }
+
+    impl->url.setProtocol(protocol);
+    impl->url.setHost(theHost);
+    impl->url.setPort(port);
+
+    // Set the fields from the arguments. Handle the case where the
+    // passed in "file" includes both a file and a reference part.
+    int index = -1;
+    index = file.indexOf("#", file.lastIndexOf("/"));
+    if (index >= 0) {
+        impl->url.setFile(file.substring(0, index));
+        impl->url.setRef(file.substring(index + 1));
+    } else {
+        impl->url.setFile(file);
+    }
+    impl->fixURL(false);
+
+    // Set the stream handler for the URL either to the handler argument if it was
+    // specified, or to the default for the receiver's protocol if the handler was NULL.
+    if (handler == NULL) {
+        impl->setupStreamHandler();
+        if (impl->streamHandler == NULL) {
+            throw MalformedURLException(
+            __FILE__, __LINE__, (std::string("Unknown protocol: ") + protocol.toString()).c_str());
+        }
+    } else {
+        impl->streamHandler.reset(handler);
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -353,7 +310,7 @@ bool URL::equals(const URL& other) const {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getAuthority() const {
+String URL::getAuthority() const {
     return impl->url.getAuthority();
 }
 
@@ -363,22 +320,22 @@ int URL::getDefaultPort() const {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getFile() const {
+String URL::getFile() const {
     return impl->url.getFile();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getHost() const {
+String URL::getHost() const {
     return impl->url.getHost();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getPath() const {
+String URL::getPath() const {
     return impl->url.getPath();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getUserInfo() const {
+String URL::getUserInfo() const {
     return impl->url.getUserInfo();
 }
 
@@ -388,17 +345,17 @@ int URL::getPort() const {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getProtocol() const {
+String URL::getProtocol() const {
     return impl->url.getProtocol();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getQuery() const {
+String URL::getQuery() const {
     return impl->url.getQuery();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::getRef() const {
+String URL::getRef() const {
     return impl->url.getRef();
 }
 
@@ -433,16 +390,16 @@ InputStream* URL::openStream() {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-std::string URL::toExternalForm() const {
+String URL::toExternalForm() const {
     if (impl->streamHandler == NULL) {
-        return std::string("unknown protocol(") + getProtocol() + ")://" + getHost() + getFile();
+        return String("unknown protocol(").concat(getProtocol()).concat(")://").concat(getHost()).concat(getFile());
     }
     return impl->streamHandler->toExternalForm(*this);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 std::string URL::toString() const {
-    return toExternalForm();
+    return toExternalForm().toString();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -451,10 +408,9 @@ URI URL::toURI() const {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void URL::set(const std::string& protocol, const std::string& host, int port,
-              const std::string& file, const std::string& ref) {
+void URL::set(const String& protocol, const String& host, int port, const String& file, const String& ref) {
 
-    if (impl->url.getProtocol().empty()) {
+    if (impl->url.getProtocol().isEmpty()) {
         impl->url.setProtocol(protocol);
     }
 
@@ -468,16 +424,16 @@ void URL::set(const std::string& protocol, const std::string& host, int port,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void URL::set(const std::string& protocol, const std::string& host, int port,
-              const std::string& authority, const std::string& userInfo,
-              const std::string& path, const std::string& query, const std::string& ref) {
-
-    std::string filePart = path;
-    if (!query.empty()) {
-        if (!filePart.empty()) {
-            filePart = filePart + "?" + query;
+void URL::set(const String& protocol, const String& host, int port,
+              const String& authority, const String& userInfo,
+              const String& path, const String& query, const String& ref) {
+
+    String filePart = path;
+    if (!query.isEmpty()) {
+        if (!filePart.isEmpty()) {
+            filePart = filePart.concat("?").concat(query);
         } else {
-            filePart = "?" + query;
+            filePart = String("?").concat(query);
         }
     }
     set(protocol, host, port, filePart, ref);
@@ -495,12 +451,6 @@ URLStreamHandler* URL::getURLStreamHandler() const {
 
 ////////////////////////////////////////////////////////////////////////////////
 void URL::setURLStreamHandlerFactory(URLStreamHandlerFactory* factory) {
-
-    if (URLImpl::streamHandlerFactory != NULL) {
-        throw Exception(__FILE__, __LINE__, "Attempt to set factory more than once");
-    }
-
-    // TODO thread safe
-    URLImpl::streamHandlers.clear();
-    URLImpl::streamHandlerFactory = factory;
+    URLStreamHandlerManager* manager = URLStreamHandlerManager::getInstance();
+    manager->setURLStreamHandlerFactory(factory);
 }

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/b1746b23/activemq-cpp/src/main/decaf/net/URL.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/net/URL.h b/activemq-cpp/src/main/decaf/net/URL.h
index 73c321b..1013307 100644
--- a/activemq-cpp/src/main/decaf/net/URL.h
+++ b/activemq-cpp/src/main/decaf/net/URL.h
@@ -19,6 +19,7 @@
 #define _DECAF_NET_URL_H_
 
 #include <decaf/util/Config.h>
+#include <decaf/lang/String.h>
 
 #include <decaf/io/InputStream.h>
 #include <string>
@@ -286,7 +287,7 @@ namespace net {
          *
          * @returns the authority part of this URL.
          */
-        std::string getAuthority() const;
+        decaf::lang::String getAuthority() const;
 
         /**
          * Gets the default port number of the protocol associated with this URL. If the URL
@@ -304,7 +305,7 @@ namespace net {
          *
          * @returns the file name associated with this URL.
          */
-        std::string getFile() const;
+        decaf::lang::String getFile() const;
 
         /**
          * Gets the host name of this URL, if applicable. The format of the host conforms to
@@ -313,21 +314,21 @@ namespace net {
          *
          * @returns the host name for this URL.
          */
-        std::string getHost() const;
+        decaf::lang::String getHost() const;
 
         /**
          * Gets the path part of this URL.
          *
          * @returns the path part of this URL.
          */
-        std::string getPath() const;
+        decaf::lang::String getPath() const;
 
         /**
          * Gets the user Info part of this URL.
          *
          * @returns the user info part of this URL.
          */
-        std::string getUserInfo() const;
+        decaf::lang::String getUserInfo() const;
 
         /**
          * Gets the port of this URL.
@@ -341,21 +342,21 @@ namespace net {
          *
          * @returns the path part of this URL.
          */
-        std::string getProtocol() const;
+        decaf::lang::String getProtocol() const;
 
         /**
          * Gets the query part of this URL.
          *
          * @returns the query part of this URL or empty string if not set.
          */
-        std::string getQuery() const;
+        decaf::lang::String getQuery() const;
 
         /**
          * Gets the anchor or "reference" portion of this URL.
          *
          * @returns the anchor or "reference" portion of this URL.
          */
-        std::string getRef() const;
+        decaf::lang::String getRef() const;
 
         /**
          * Creates an integer hash code for this URL which is used in hash based collections.
@@ -426,7 +427,7 @@ namespace net {
          *
          * @returns the string representation of this URL.
          */
-        std::string toExternalForm() const;
+        decaf::lang::String toExternalForm() const;
 
         /**
          * Calls toExternalForm to create a string representation of this URL.
@@ -476,8 +477,8 @@ namespace net {
          * @param ref
          *      the internal reference in the URL
          */
-        void set(const std::string& protocol, const std::string& host, int port,
-                 const std::string& file, const std::string& ref);
+        void set(const decaf::lang::String& protocol, const decaf::lang::String& host, int port,
+                 const decaf::lang::String& file, const decaf::lang::String& ref);
 
         /**
          * Sets the fields of the URL. This is not a public method so that only URLStreamHandlers
@@ -501,9 +502,10 @@ namespace net {
          * @param ref
          *      the internal reference in the URL
          */
-        void set(const std::string& protocol, const std::string& host, int port,
-                 const std::string& authority, const std::string& userInfo,
-                 const std::string& path, const std::string& query, const std::string& ref);
+        void set(const decaf::lang::String& protocol, const decaf::lang::String& host, int port,
+                 const decaf::lang::String& authority, const decaf::lang::String& userInfo,
+                 const decaf::lang::String& path, const decaf::lang::String& query,
+                 const decaf::lang::String& ref);
 
         /**
          * Returns the URLStreamHandler configured for this URL, used to validate that
@@ -513,6 +515,11 @@ namespace net {
 
     private:
 
+        void initialize(const URL* context, const decaf::lang::String& theSpec, URLStreamHandler* handler);
+        void initialize(const decaf::lang::String& protocol, const decaf::lang::String& host, int port,
+                        const decaf::lang::String& file, URLStreamHandler* handler);
+
+
         friend class URLStreamHandler;
 
     };

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/b1746b23/activemq-cpp/src/main/decaf/net/URLConnection.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/net/URLConnection.h b/activemq-cpp/src/main/decaf/net/URLConnection.h
index 20cc03c..a0eface 100644
--- a/activemq-cpp/src/main/decaf/net/URLConnection.h
+++ b/activemq-cpp/src/main/decaf/net/URLConnection.h
@@ -323,7 +323,7 @@ namespace net {
          * @return the string representation of this URLConnection instance.
          */
         virtual std::string toString() const {
-            return "URLConnection:" + url.toString();
+            return std::string("URLConnection:") + url.toString();
         }
 
         /**


Mime
View raw message