You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2013/11/13 23:46:34 UTC

git commit: Work on more String utils StringBuilder and StringBuffer.

Updated Branches:
  refs/heads/trunk 12bb514c6 -> 5b958427e


Work on more String utils StringBuilder and StringBuffer.

Project: http://git-wip-us.apache.org/repos/asf/activemq-cpp/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-cpp/commit/5b958427
Tree: http://git-wip-us.apache.org/repos/asf/activemq-cpp/tree/5b958427
Diff: http://git-wip-us.apache.org/repos/asf/activemq-cpp/diff/5b958427

Branch: refs/heads/trunk
Commit: 5b958427ef1181a086285bddba87f7a85fdc82e2
Parents: 12bb514
Author: Timothy Bish <ta...@gmai.com>
Authored: Wed Nov 13 17:46:25 2013 -0500
Committer: Timothy Bish <ta...@gmai.com>
Committed: Wed Nov 13 17:46:25 2013 -0500

----------------------------------------------------------------------
 activemq-cpp/src/main/Makefile.am               |   6 +
 .../util/concurrent/SynchronizableImpl.h        |   4 +-
 .../main/decaf/lang/AbstractStringBuilder.cpp   | 436 ++++++++++++++++
 .../src/main/decaf/lang/AbstractStringBuilder.h | 262 ++++++++++
 .../src/main/decaf/lang/StringBuffer.cpp        |  56 ++
 activemq-cpp/src/main/decaf/lang/StringBuffer.h | 104 ++++
 .../src/main/decaf/lang/StringBuilder.cpp       | 151 ++++++
 .../src/main/decaf/lang/StringBuilder.h         | 261 ++++++++++
 activemq-cpp/src/test/Makefile.am               |   4 +
 .../src/test/decaf/lang/StringBufferTest.cpp    |  58 +++
 .../src/test/decaf/lang/StringBufferTest.h      |  47 ++
 .../src/test/decaf/lang/StringBuilderTest.cpp   | 505 +++++++++++++++++++
 .../src/test/decaf/lang/StringBuilderTest.h     |  89 ++++
 activemq-cpp/src/test/testRegistry.cpp          |   4 +
 14 files changed, 1985 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/Makefile.am
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/Makefile.am b/activemq-cpp/src/main/Makefile.am
index ebbb5ee..5939df9 100644
--- a/activemq-cpp/src/main/Makefile.am
+++ b/activemq-cpp/src/main/Makefile.am
@@ -444,6 +444,7 @@ cc_sources = \
     decaf/io/UTFDataFormatException.cpp \
     decaf/io/UnsupportedEncodingException.cpp \
     decaf/io/Writer.cpp \
+    decaf/lang/AbstractStringBuilder.cpp \
     decaf/lang/Appendable.cpp \
     decaf/lang/Boolean.cpp \
     decaf/lang/Byte.cpp \
@@ -462,6 +463,8 @@ cc_sources = \
     decaf/lang/Runtime.cpp \
     decaf/lang/Short.cpp \
     decaf/lang/String.cpp \
+    decaf/lang/StringBuffer.cpp \
+    decaf/lang/StringBuilder.cpp \
     decaf/lang/System.cpp \
     decaf/lang/Thread.cpp \
     decaf/lang/ThreadGroup.cpp \
@@ -1127,6 +1130,7 @@ h_sources = \
     decaf/io/UTFDataFormatException.h \
     decaf/io/UnsupportedEncodingException.h \
     decaf/io/Writer.h \
+    decaf/lang/AbstractStringBuilder.h \
     decaf/lang/Appendable.h \
     decaf/lang/ArrayPointer.h \
     decaf/lang/Boolean.h \
@@ -1148,6 +1152,8 @@ h_sources = \
     decaf/lang/Runtime.h \
     decaf/lang/Short.h \
     decaf/lang/String.h \
+    decaf/lang/StringBuffer.h \
+    decaf/lang/StringBuilder.h \
     decaf/lang/System.h \
     decaf/lang/Thread.h \
     decaf/lang/ThreadGroup.h \

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/internal/util/concurrent/SynchronizableImpl.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/internal/util/concurrent/SynchronizableImpl.h b/activemq-cpp/src/main/decaf/internal/util/concurrent/SynchronizableImpl.h
index 96fb438..ca8b29e 100644
--- a/activemq-cpp/src/main/decaf/internal/util/concurrent/SynchronizableImpl.h
+++ b/activemq-cpp/src/main/decaf/internal/util/concurrent/SynchronizableImpl.h
@@ -34,9 +34,9 @@ namespace concurrent {
      * @since 1.0
      */
     class DECAF_API SynchronizableImpl : public decaf::util::concurrent::Synchronizable {
-    private:
+    protected:
 
-        decaf::util::concurrent::Mutex mutex;
+        mutable decaf::util::concurrent::Mutex mutex;
 
     public:
 

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
new file mode 100644
index 0000000..e9e8c87
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
@@ -0,0 +1,436 @@
+/*
+ * 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 <decaf/lang/AbstractStringBuilder.h>
+
+#include <decaf/lang/System.h>
+#include <decaf/lang/Math.h>
+#include <decaf/lang/ArrayPointer.h>
+#include <decaf/util/Arrays.h>
+
+#include <decaf/lang/exceptions/NegativeArraySizeException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/lang/exceptions/ArrayIndexOutOfBoundsException.h>
+#include <decaf/lang/exceptions/StringIndexOutOfBoundsException.h>
+
+#include <decaf/internal/util/StringUtils.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::util;
+using namespace decaf::internal::util;
+
+////////////////////////////////////////////////////////////////////////////////
+const int AbstractStringBuilder::INITIAL_CAPACITY = 16;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace decaf {
+namespace lang {
+
+    class AbstractStringBuilderImpl {
+    public:
+
+        ArrayPointer<char> value;
+        int length;
+        bool shared;
+        int hashCode;
+
+    public:
+
+        /**
+         * Contents created with the given length, the array is length + 1 to add the
+         * null terminating character.
+         */
+        AbstractStringBuilderImpl(int capacity) :
+            value(capacity + 1), length(0), shared(false), hashCode(0) {}
+
+        /**
+         * Contents is a view of some other String which can either be all or a
+         * window allowing for substring methods to not need to copy the contents.
+         */
+        AbstractStringBuilderImpl(int length, ArrayPointer<char> value) :
+            value(value), length(length), shared(false), hashCode(0) {}
+
+        void enlargeBuffer(int min) {
+            // API calls for length() * 2 + 2 but we need to add one for Null termination.
+            int newCount = ((value.length() >> 1) + value.length()) + 3;
+            int newCapacity = (min > newCount ? min : newCount) + 1;
+            ArrayPointer<char> newData(newCapacity);
+            System::arraycopy(value.get(), 0, newData.get(), 0, length);
+            value = newData;
+            shared = false;
+        }
+
+        int capacity() const {
+            return this->value.length() - 1;
+        }
+
+        // ensure enough room for current length + additional
+        void ensureCapacity(int newLength) {
+            if (newLength > (value.length() - 1)) {
+                enlargeBuffer(newLength);
+            }
+        }
+    };
+
+}}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractStringBuilder::AbstractStringBuilder() :
+    impl(new AbstractStringBuilderImpl(INITIAL_CAPACITY)) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractStringBuilder::AbstractStringBuilder(int capacity) : impl() {
+
+    if (capacity < 0) {
+        throw NegativeArraySizeException(__FILE__, __LINE__, "Capacity cannot be negative");
+    }
+
+    impl = new AbstractStringBuilderImpl(capacity);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractStringBuilder::AbstractStringBuilder(const String& source) :
+    impl(new AbstractStringBuilderImpl(source.length() + INITIAL_CAPACITY)) {
+
+    for (int i = 0; i < source.length(); ++i) {
+        impl->value[i] = source.charAt(i);
+    }
+
+    impl->length = source.length();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractStringBuilder::AbstractStringBuilder(const std::string& source) :
+    impl(new AbstractStringBuilderImpl((int)source.length() + INITIAL_CAPACITY)) {
+
+    for (int i = 0; i < (int) source.length(); ++i) {
+        impl->value[i] = source.at(i);
+    }
+
+    impl->length = (int) source.length();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractStringBuilder::AbstractStringBuilder(const CharSequence* source) : impl() {
+
+    if (source == NULL) {
+        throw NullPointerException(__FILE__, __LINE__, "CharSequence was NULL");
+    }
+
+    std::string src = source->toString();
+    int capacity = (int) src.length();
+
+    impl = new AbstractStringBuilderImpl(capacity + INITIAL_CAPACITY);
+
+    for (int i = 0; i < (int) src.length(); ++i) {
+        impl->value[i] = src.at(i);
+    }
+
+    impl->length = (int) src.length();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractStringBuilder::~AbstractStringBuilder() {
+    try {
+        delete this->impl;
+    }
+    DECAF_CATCHALL_NOTHROW()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppendNull() {
+    int newCount = impl->length + 4;
+    if (newCount > impl->capacity()) {
+        impl->enlargeBuffer(newCount);
+    }
+
+    impl->value[impl->length++] = 'n';
+    impl->value[impl->length++] = 'u';
+    impl->value[impl->length++] = 'l';
+    impl->value[impl->length++] = 'l';
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const char value) {
+    int newCount = impl->length + 1;
+    if (newCount > impl->capacity()) {
+        impl->enlargeBuffer(newCount);
+    }
+
+    impl->value[impl->length++] = value;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const char* value) {
+
+    if (value == NULL) {
+        throw NullPointerException(__FILE__, __LINE__, "C String cannot be null, call 'doAppendNull' instead");
+    }
+
+    int length = StringUtils::stringLength(value);
+
+    if (length <= 0) {
+        return;
+    }
+
+    int newLength = impl->length + length;
+    impl->ensureCapacity(newLength);
+    System::arraycopy(value, 0, impl->value.get(), impl->length, length);
+    impl->length = newLength;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const char* value, int offset, int length) {
+
+    if (value == NULL) {
+        throw NullPointerException(__FILE__, __LINE__, "C String cannot be null, call 'doAppendNull' instead");
+    }
+
+    int arrayLength = StringUtils::stringLength(value);
+
+    if ((offset | length) < 0 || offset > arrayLength || arrayLength - offset < length) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid offset or length value given.");
+    }
+
+    if (length <= 0) {
+        return;
+    }
+
+    int newLength = impl->length + length;
+    impl->ensureCapacity(newLength);
+    System::arraycopy(value, offset, impl->value.get(), impl->length, length);
+    impl->length = newLength;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const CharSequence* value) {
+
+    if (value == NULL) {
+        throw NullPointerException(__FILE__, __LINE__, "C String cannot be null, call 'doAppendNull' instead");
+    }
+
+    int length = value->length();
+
+    if (length <= 0) {
+        return;
+    }
+
+    int newLength = impl->length + length;
+    impl->ensureCapacity(newLength);
+    for (int i = 0; i < length; ++i) {
+        impl->value[impl->length++] = value->charAt(i);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const CharSequence* value, int start, int end) {
+
+    if (value == NULL) {
+        const char* nullString = "null";
+        doAppend(nullString, start, end - start);
+        return;
+    }
+
+    int arrayLength = value->length();
+
+    if ((start | end) < 0 || start > end || end > arrayLength) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid offset or length value given.");
+    }
+
+    int length = end - start;
+
+    if (length == 0) {
+        return;
+    }
+
+    int newLength = impl->length + length;
+    impl->ensureCapacity(newLength);
+
+    for (int i = start; i < end; ++i) {
+        impl->value[impl->length++] = value->charAt(i);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const std::string& value) {
+
+    int length = (int) value.length();
+    int newLength = impl->length + length;
+    impl->ensureCapacity(newLength);
+
+    for (int i = 0; i < length; ++i) {
+        impl->value[impl->length++] = value.at(i);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const String& value) {
+
+    int length = value.length();
+    int newLength = impl->length + length;
+    impl->ensureCapacity(newLength);
+
+    for (int i = 0; i < length; ++i) {
+        impl->value[impl->length++] = value.charAt(i);
+    }
+
+    // TODO direct access: string._getChars(0, length, value, count);
+    // impl->length = newLength;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doAppend(const AbstractStringBuilder& value) {
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doDeleteRange(int start, int end) {
+
+    // This method is specified not to throw if the end index is >= length(), as
+    // long as it's >= start. This means we have to clamp it to count here.
+    if (end > impl->length) {
+        end = impl->length;
+    }
+
+    if (start < 0 || start > impl->length || start > end) {
+        throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid start index: %d", start);
+    }
+
+    // This method is defined to throw only if start > count and start == count is a NO-OP
+    // Since 'end' is already a clamped value, that case is handled here.
+    if (end == start) {
+        return;
+    }
+
+    // At this point we know for sure that end > start.
+    int length = impl->length - end;
+    if (length >= 0) {
+        if (!impl->shared) {
+            System::arraycopy(impl->value.get(), end, impl->value.get(), start, length);
+        } else {
+            ArrayPointer<char> newValue(impl->value.length());
+            System::arraycopy(impl->value.get(), 0, newValue.get(), 0, start);
+            System::arraycopy(impl->value.get(), end, newValue.get(), start, length);
+            impl->value = newValue;
+            impl->shared = false;
+        }
+    }
+    impl->length -= end - start;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doDeleteCharAt(int index) {
+    if (index < 0 || index >= impl->length) {
+        throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid index: %d", index);
+    }
+
+    doDeleteRange(index, index + 1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int AbstractStringBuilder::capacity() const {
+    return impl->capacity();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+char AbstractStringBuilder::charAt(int index) const {
+    if (index < 0 || index >= impl->length) {
+        throw StringIndexOutOfBoundsException(__FILE__, __LINE__, index);
+    }
+
+    return impl->value[index];
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::ensureCapacity(int minCapacity) {
+    if (minCapacity > impl->value.length() - 1) {
+        impl->enlargeBuffer(minCapacity);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int AbstractStringBuilder::length() const {
+    return impl->length;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::setCharAt(int index, char value) {
+
+    if (index < 0) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Index < 0: %d", index);
+    }
+
+    if (index > impl->length) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Index > length(): %d", index);
+    }
+
+    if (impl->shared) {
+        ArrayPointer<char> newValue(impl->value.length());
+        System::arraycopy(impl->value.get(), 0, newValue.get(), 0, impl->length);
+        impl->value = newValue;
+        impl->shared = false;
+    }
+
+    impl->value[index] = value;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::setLength(int length) {
+
+    if (length < 0) {
+        throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "length < 0: %d", length);
+    }
+
+    if (length > impl->value.length() - 1) {
+        impl->enlargeBuffer(length);
+    } else {
+        if (impl->shared) {
+            ArrayPointer<char> newValue(impl->value.length());
+            System::arraycopy(impl->value.get(), 0, newValue.get(), 0, impl->length);
+            impl->value = newValue;
+            impl->shared = false;
+        } else {
+            if (impl->length < length) {
+                Arrays::fill(impl->value.get(), impl->value.length(), impl->length, length, (char) 0);
+            }
+        }
+    }
+    impl->length = length;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+String AbstractStringBuilder::toString() const {
+
+    // TODO optimize so that internal data can be shared with the returned String
+    //      and discarded only after a new mutating method call is made.
+    //      ensure the shared flag is set once we do this.
+
+    return String(impl->value.get(), 0, impl->length);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::trimToSize() {
+    if (impl->length < (impl->value.length() - 1)) {
+        ArrayPointer<char> newValue(impl->length + 1);
+        System::arraycopy(impl->value.get(), 0, newValue.get(), 0, impl->length);
+        impl->value = newValue;
+        impl->shared = false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
new file mode 100644
index 0000000..e9470ee
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
@@ -0,0 +1,262 @@
+/*
+ * 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_ABSTRACTSTRINGBUILDER_H_
+#define _DECAF_LANG_ABSTRACTSTRINGBUILDER_H_
+
+#include <decaf/util/Config.h>
+#include <decaf/lang/String.h>
+
+#include <decaf/internal/util/concurrent/SynchronizableImpl.h>
+
+namespace decaf {
+namespace lang {
+
+    class AbstractStringBuilderImpl;
+
+    /**
+     * A modifiable sequence of characters for use in creating and modifying Strings.
+     * This class is intended as a base class for StringBuffer and StringBuilder.
+     *
+     * @see StringBuffer
+     * @see StringBuilder
+     *
+     * @since 1.0
+     */
+    class DECAF_API AbstractStringBuilder : public decaf::internal::util::concurrent::SynchronizableImpl {
+    protected:
+
+        static const int INITIAL_CAPACITY;
+
+    private:
+
+        AbstractStringBuilderImpl* impl;
+
+    public:
+
+        AbstractStringBuilder();
+
+        AbstractStringBuilder(int capacity);
+
+        AbstractStringBuilder(const String& source);
+
+        AbstractStringBuilder(const std::string& source);
+
+        AbstractStringBuilder(const CharSequence* source);
+
+        virtual ~AbstractStringBuilder();
+
+    public:
+
+        /**
+         * Returns the current capacity. The capacity indicates the amount of space available in
+         * the internal character buffer, when the number of characters inserted exceeds the current
+         * capacity the internal buffer is reallocated and old contents copied to the new buffer.
+         *
+         * @returns the current capacity value.
+         */
+        virtual int capacity() const;
+
+        /**
+         * Returns the character at the given index.
+         *
+         * @param index
+         *      The index in this buffer where the character to return is located.
+         *
+         * @throws IndexOutOfBoundsException if index < 0 or index >= length().
+         */
+        char charAt(int index) const;
+
+        /**
+         * Ensures that the capacity is at least equal to the specified min value. If
+         * the current capacity is less than the given value, then this buffer backing this
+         * instance will be reallocated and the old contents copied into the new buffer. The
+         * new capacity is set to either the given value or twice the old capacity + 2
+         * depending on which is larger.
+         *
+         * If the minimumCapacity argument is negative this method does nothing.
+         *
+         * @param minCapacity
+         *      The minimum capacity to ensure exists in this buffer.
+         */
+        virtual void ensureCapacity(int minCapacity);
+
+        /**
+         * Returns the current length of the String that has been built.
+         *
+         * @returns the current number of characters that have been inserted.
+         */
+        virtual int length() const;
+
+        /**
+         * Sets the length of this character buffer. The backing buffer is changed to a new
+         * character buffer whose length is specified by the argument.  Each character in the
+         * old buffer is copied into the new buffer up to the given length value.  If the new
+         * length is greater than the old buffer length then the additional character are all
+         * set to '\0'.
+         *
+         * @param length
+         *      The new length to give this character buffer
+         *
+         * @throws IndexOutOfBoundsException if length is less than zero.
+         */
+        virtual void setLength(int length);
+
+        /**
+         * Sets the character at the specified index to the new char value given.
+         *
+         * @param index
+         *      The index of the character to modify.
+         * @param value
+         *      The new char value to assign at the given index.
+         *
+         * @throws IndexOutOfBoundsException if index is negative or greater than length().
+         */
+        virtual void setCharAt(int index, char value);
+
+        /**
+         * Returns a String that represents the contents of this buffer.  Any changes
+         * made to this buffer after calling this method will not be reflected in the
+         * String value that is returned.
+         */
+        virtual String toString() const;
+
+        /**
+         * Attempts to reduce storage used for the character sequence. If the buffer
+         * is larger than necessary to hold its current sequence of characters, then
+         * it may be resized to become more space efficient. Calling this method may,
+         * but is not required to, affect the value returned by a subsequent call to
+         * the capacity() method.
+         */
+        virtual void trimToSize();
+
+    protected:
+
+        /**
+         * Appends the string "null" to the current character buffer.
+         */
+        void doAppendNull();
+
+        /**
+         * Appends the given char to this buffer.
+         *
+         * @param value
+         *      The char value to be appended into this buffer.
+         */
+        void doAppend(const char value);
+
+        /**
+         * Appends the given C string to this buffer.
+         *
+         * @param value
+         *      The C string value to be appended into this buffer.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         */
+        void doAppend(const char* value);
+
+        /**
+         * Appends the given C string to this buffer starting at the given offset and
+         * ending after the length number of characters has been appened.
+         *
+         * @param value
+         *      The C string value to be appended into this buffer.
+         * @param offset
+         *      The starting position into the C string array.
+         * @param length
+         *      The number of characters to copy from the given array.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         * @throws IndexOutOfBoundsException if offset or length is negative or the value of
+         *         offset + length is greater than the strings length.
+         */
+        void doAppend(const char* value, int offset, int length);
+
+        /**
+         * Appends the given CharSequence to this buffer.
+         *
+         * @param value
+         *      The CharSequence value to be appended into this buffer.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         */
+        void doAppend(const CharSequence* value);
+
+        /**
+         * Appends the given CharSequence to this buffer starting at the given offset and
+         * ending after the length number of characters has been appened.
+         *
+         * @param value
+         *      The CharSequence value to be appended into this buffer.
+         * @param offset
+         *      The starting position into the CharSequence.
+         * @param length
+         *      The number of characters to copy from the given CharSequence.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         * @throws IndexOutOfBoundsException if offset or length is negative or the value of
+         *         offset + length is greater than the strings length.
+         */
+        void doAppend(const CharSequence* value, int offset, int length);
+
+        /**
+         * Append the given std::string to this buffer.
+         *
+         * @param value
+         *      The String instance to append into this buffer.
+         */
+        void doAppend(const std::string& value);
+
+        /**
+         * Append the given String to this buffer.
+         *
+         * @param value
+         *      The String instance to append into this buffer.
+         */
+        void doAppend(const String& value);
+
+        /**
+         * Append the given AbstractStringBuilder to this buffer.
+         *
+         * @param value
+         *      The String instance to append into this buffer.
+         */
+        void doAppend(const AbstractStringBuilder& value);
+
+        /**
+         * Delete the characters in the range start - end.
+         *
+         * @param start
+         *      The starting index of the delete operation
+         * @param end
+         *      The ending index of the delete operation (exclusive).
+         */
+        void doDeleteRange(int start, int end);
+
+        /**
+         * Deletes the character at the given index from this buffer.
+         *
+         * @param index
+         *      The index of the character to delete.
+         */
+        void doDeleteCharAt(int index);
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_ABSTRACTSTRINGBUILDER_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp b/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
new file mode 100644
index 0000000..9419a10
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 <decaf/lang/StringBuffer.h>
+
+#include <decaf/lang/exceptions/NegativeArraySizeException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer::StringBuffer() : AbstractStringBuilder() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer::StringBuffer(int capacity) : AbstractStringBuilder(capacity) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer::StringBuffer(const String& source) : AbstractStringBuilder(source) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer::StringBuffer(const CharSequence* source) : AbstractStringBuilder(source) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer::~StringBuffer() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringBuffer::capacity() const {
+    int capacity = 0;
+
+    synchronized(&this->mutex) {
+        capacity = AbstractStringBuilder::capacity();
+    }
+
+    return capacity;
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/lang/StringBuffer.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuffer.h b/activemq-cpp/src/main/decaf/lang/StringBuffer.h
new file mode 100644
index 0000000..f779d5d
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/StringBuffer.h
@@ -0,0 +1,104 @@
+/*
+ * 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_STRINGBUFFER_H_
+#define _DECAF_LANG_STRINGBUFFER_H_
+
+#include <decaf/util/Config.h>
+#include <decaf/lang/AbstractStringBuilder.h>
+#include <decaf/lang/String.h>
+#include <decaf/lang/CharSequence.h>
+#include <decaf/lang/Appendable.h>
+#include <decaf/util/concurrent/Mutex.h>
+
+namespace decaf {
+namespace lang {
+
+    /**
+     * StringBuffer is a variable size contiguous indexable array of characters. The
+     * length of the StringBuffer is the number of characters it contains. The capacity
+     * of the StringBuffer is the number of characters it can hold.
+     *
+     * Characters may be inserted at any position up to the length of the StringBuffer,
+     * increasing the length of the StringBuffer. Characters at any position in the
+     * StringBuffer may be replaced, which does not affect the StringBuffer length.
+     *
+     * The capacity of a StringBuffer may be specified when the StringBuffer is
+     * created. If the capacity of the StringBuffer is exceeded, the capacity is
+     * increased.
+     *
+     * StringBuffer objects are safe for use by multiple threads. The methods are
+     * synchronized where necessary so that all the operations on any particular instance
+     * behave as if they occur in some serial order that is consistent with the order of
+     * the method calls made by each of the individual threads involved.
+     *
+     * @see String
+     * @see StringBuilder
+     *
+     * @since 1.0
+     */
+    class DECAF_API StringBuffer : public AbstractStringBuilder {
+    public:
+
+        /**
+         * Creates an empty StringBuffer instance with a capacity of 16.
+         */
+        StringBuffer();
+
+        /**
+         * Creates an empty StringBuffer instance with the given capacity
+         *
+         * @param capacity
+         *      The initial capacity to give this new instance.
+         *
+         * @throws NegativeArraySizeException if the given capacity is less than zero.
+         */
+        StringBuffer(int capacity);
+
+        /**
+         * Constructs a string buffer initialized to the contents of the specified string.
+         * The initial capacity of the string builder is 16 plus the length of the string
+         * argument.
+         *
+         * @param source
+         *      The String whose contents are to be copied into this StringBuffer.
+         */
+        StringBuffer(const String& source);
+
+        /**
+         * Constructs a string buffer initialized to the contents of the specified string.
+         * The initial capacity of the string builder is 16 plus the length of the string
+         * argument.
+         *
+         * @param source
+         *      The CharSequence whose contents are to be copied into this StringBuffer.
+         *
+         * @throws NullPointerException if the CharSequence pointer is NULL.
+         */
+        StringBuffer(const CharSequence* source);
+
+        virtual ~StringBuffer();
+
+    public:
+
+        virtual int capacity() const;
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_STRINGBUFFER_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp b/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
new file mode 100644
index 0000000..3ea67b8
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
@@ -0,0 +1,151 @@
+/*
+ * 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 <decaf/lang/StringBuilder.h>
+
+#include <decaf/lang/exceptions/NegativeArraySizeException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+
+#include <decaf/lang/StringBuffer.h>
+#include <decaf/lang/Short.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Float.h>
+#include <decaf/lang/Double.h>
+
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder::StringBuilder() : AbstractStringBuilder() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder::StringBuilder(int capacity) : AbstractStringBuilder(capacity) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder::StringBuilder(const String& source) : AbstractStringBuilder(source) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder::StringBuilder(const CharSequence* source) : AbstractStringBuilder(source) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder::~StringBuilder() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(bool value) {
+    doAppend(value ? "true" : "false");
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(char value) {
+    doAppend(value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(short value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    doAppend(Short::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(int value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    doAppend(Integer::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(long long value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    doAppend(Long::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(float value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    doAppend(Float::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(double value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    doAppend(Double::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(const char* value) {
+    doAppend(value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(const char* value, int offset, int length) {
+    doAppend(value, offset, length);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(const CharSequence* value) {
+    if (value == NULL) {
+        doAppendNull();
+    } else {
+        doAppend(value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(const CharSequence* value, int offset, int length) {
+    doAppend(value, offset, length);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(const String& value) {
+    doAppend(value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::append(const StringBuffer& value) {
+    // TODO doAppend(value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::deleteRange(int start, int end) {
+    doDeleteRange(start, end);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::deleteCharAt(int index) {
+    doDeleteCharAt(index);
+    return *this;
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/main/decaf/lang/StringBuilder.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuilder.h b/activemq-cpp/src/main/decaf/lang/StringBuilder.h
new file mode 100644
index 0000000..1a9428e
--- /dev/null
+++ b/activemq-cpp/src/main/decaf/lang/StringBuilder.h
@@ -0,0 +1,261 @@
+/*
+ * 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_STRINGBUILDER_H_
+#define _DECAF_LANG_STRINGBUILDER_H_
+
+#include <decaf/util/Config.h>
+#include <decaf/lang/AbstractStringBuilder.h>
+#include <decaf/lang/String.h>
+#include <decaf/lang/CharSequence.h>
+#include <decaf/lang/Appendable.h>
+#include <decaf/lang/Pointer.h>
+
+namespace decaf {
+namespace lang {
+
+    class StringBuffer;
+
+    /**
+     * A modifiable sequence of characters for use in creating and modifying Strings.
+     * This class is intended as a direct replacement of StringBuffer for non-concurrent
+     * use; unlike StringBuffer this class is not synchronized for thread safety.
+     *
+     * The majority of the modification methods on this class return a reference to this
+     * StringBuilder, so that, like StringBuffers, they can be used in chaining method
+     * calls together. For example:
+     *
+     *  StringBuilder("One should ").append("always strive ").append("to achieve Harmony")}.
+     *
+     * @see CharSequence
+     * @see Appendable
+     * @see StringBuffer
+     * @see String
+     *
+     * @since 1.0
+     */
+    class DECAF_API StringBuilder : public AbstractStringBuilder {
+    public:
+
+        /**
+         * Creates an empty StringBuilder instance with a capacity of 16.
+         */
+        StringBuilder();
+
+        /**
+         * Creates an empty StringBuilder instance with the given capacity.
+         *
+         * @param capacity
+         *      The initial capacity to give this new instance.
+         *
+         * @throws NegativeArraySizeException if the given capacity is less than zero.
+         */
+        StringBuilder(int capacity);
+
+        /**
+         * Constructs a string builder initialized to the contents of the specified string.
+         * The initial capacity of the string builder is 16 plus the length of the string
+         * argument.
+         *
+         * @param source
+         *      The String whose contents are to be copied into this StringBuilder.
+         */
+        StringBuilder(const String& source);
+
+        /**
+         * Constructs a string builder initialized to the contents of the specified string.
+         * The initial capacity of the string builder is 16 plus the length of the string
+         * argument.
+         *
+         * @param source
+         *      The CharSequence whose contents are to be copied into this StringBuilder.
+         *
+         * @throws NullPointerException if the CharSequence pointer is NULL.
+         */
+        StringBuilder(const CharSequence* source);
+
+        virtual ~StringBuilder();
+
+    public:
+
+        /**
+         * Appends the string representation of the given object pointer.  If the pointer
+         * is NULL then the value "null" is appended to this StringBuilder.
+         *
+         * @param pointer
+         *      A pointer to some object that must define a toString method.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        template<typename POINTER>
+        StringBuilder& append(const POINTER* pointer) {
+
+            if (pointer == NULL) {
+                doAppendNull();
+            } else {
+                doAppend(pointer->toString());
+            }
+
+            return *this;
+        }
+
+        /**
+         * Appends the string representation of the given object pointer.  If the pointer
+         * is NULL then the value "null" is appended to this StringBuilder.
+         *
+         * @param pointer
+         *      A pointer to some object that must define a toString method.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        template<typename TYPE>
+        StringBuilder& append(const Pointer<TYPE> pointer) {
+
+            if (pointer == NULL) {
+                doAppendNull();
+            } else {
+                doAppend(pointer->toString());
+            }
+
+            return *this;
+        }
+
+        /**
+         * Appends the string representation of the given boolean value.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(bool value);
+
+        /**
+         * Appends the given char value into the internal char buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(char value);
+
+        /**
+         * Appends the given short value into the internal char buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(short value);
+
+        /**
+         * Appends the given int value into the internal char buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(int value);
+
+        /**
+         * Appends the given long long value into the internal char buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(long long value);
+
+        /**
+         * Appends the given float value into the internal char buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(float value);
+
+        /**
+         * Appends the given double value into the internal char buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(double value);
+
+        /**
+         * Appends the contents of the given C string into this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(const char* value);
+
+        /**
+         * Appends the given subsequence of the given C string into this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(const char* value, int offset, int length);
+
+        /**
+         * Appends the contents of the CharSequence into this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(const CharSequence* value);
+
+        /**
+         * Appends the given subsequence of the given CharSequence into this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(const CharSequence* value, int offset, int length);
+
+        /**
+         * Appends the contents of the String into this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(const String& value);
+
+        /**
+         * Appends the contents of the StringBuffer into this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& append(const StringBuffer& value);
+
+        /**
+         * Removes the characters in a substring of this buffer. The substring begins at
+         * the specified start and extends to the character at index end - 1 or to the
+         * end of the sequence if end is greater than the current length() value. If
+         * start is equal to end, no changes are made.
+         *
+         * @param start
+         *      The starting index to delete from this buffer.
+         * @param end
+         *      The ending index (exclusive) to delete from this buffer.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if start is negative, greater than length(), or greater than end.
+         */
+        StringBuilder& deleteRange(int start, int end);
+
+        /**
+         * Deletes the char at the specified position in this buffer, length decreases by one.
+         *
+         * @param index
+         *      The index in this buffer where the character to delete is located.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& deleteCharAt(int index);
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_STRINGBUILDER_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/test/Makefile.am
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/Makefile.am b/activemq-cpp/src/test/Makefile.am
index dd0f87d..ab6e7b9 100644
--- a/activemq-cpp/src/test/Makefile.am
+++ b/activemq-cpp/src/test/Makefile.am
@@ -182,6 +182,8 @@ cc_sources = \
     decaf/lang/MathTest.cpp \
     decaf/lang/PointerTest.cpp \
     decaf/lang/ShortTest.cpp \
+    decaf/lang/StringBufferTest.cpp \
+    decaf/lang/StringBuilderTest.cpp \
     decaf/lang/StringTest.cpp \
     decaf/lang/SystemTest.cpp \
     decaf/lang/ThreadLocalTest.cpp \
@@ -437,6 +439,8 @@ h_sources = \
     decaf/lang/MathTest.h \
     decaf/lang/PointerTest.h \
     decaf/lang/ShortTest.h \
+    decaf/lang/StringBufferTest.h \
+    decaf/lang/StringBuilderTest.h \
     decaf/lang/StringTest.h \
     decaf/lang/SystemTest.h \
     decaf/lang/ThreadLocalTest.h \

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp b/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
new file mode 100644
index 0000000..e3411f5
--- /dev/null
+++ b/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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 "StringBufferTest.h"
+
+#include <decaf/lang/String.h>
+#include <decaf/lang/StringBuffer.h>
+#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
+#include <decaf/lang/exceptions/NegativeArraySizeException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/lang/exceptions/StringIndexOutOfBoundsException.h>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+StringBufferTest::StringBufferTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBufferTest::~StringBufferTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testDefaultConstructor() {
+    StringBuffer buffer;
+    CPPUNIT_ASSERT_EQUAL(16, buffer.capacity());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testConstructorInt() {
+
+    StringBuffer sb(24);
+    CPPUNIT_ASSERT_EQUAL(24, sb.capacity());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NegativeArraySizeException",
+        StringBuffer(-1),
+        NegativeArraySizeException);
+
+    CPPUNIT_ASSERT_NO_THROW(StringBuffer(0));
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBufferTest.h b/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
new file mode 100644
index 0000000..0823c89
--- /dev/null
+++ b/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
@@ -0,0 +1,47 @@
+/*
+ * 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_STRINGBUFFERTEST_H_
+#define _DECAF_LANG_STRINGBUFFERTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace decaf {
+namespace lang {
+
+    class StringBufferTest : public CppUnit::TestFixture {
+    private:
+
+        CPPUNIT_TEST_SUITE( StringBufferTest );
+        CPPUNIT_TEST( testDefaultConstructor );
+        CPPUNIT_TEST( testConstructorInt );
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        StringBufferTest();
+        virtual ~StringBufferTest();
+
+        void testDefaultConstructor();
+        void testConstructorInt();
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_STRINGBUFFERTEST_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
new file mode 100644
index 0000000..8ab87fa
--- /dev/null
+++ b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
@@ -0,0 +1,505 @@
+/*
+ * 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 "StringBuilderTest.h"
+
+#include <decaf/lang/String.h>
+#include <decaf/lang/StringBuilder.h>
+#include <decaf/lang/StringBuffer.h>
+#include <decaf/lang/Short.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Float.h>
+#include <decaf/lang/Double.h>
+#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
+#include <decaf/lang/exceptions/NegativeArraySizeException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/lang/exceptions/StringIndexOutOfBoundsException.h>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilderTest::StringBuilderTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilderTest::~StringBuilderTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testDefaultConstructor() {
+    StringBuilder builder;
+    CPPUNIT_ASSERT_EQUAL(16, builder.capacity());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testConstructorInt() {
+
+    StringBuilder sb(24);
+    CPPUNIT_ASSERT_EQUAL(24, sb.capacity());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NegativeArraySizeException",
+        StringBuilder(-1),
+        NegativeArraySizeException);
+
+    CPPUNIT_ASSERT_NO_THROW(StringBuilder(0));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testConstructorString() {
+
+    StringBuilder sb("fixture");
+    CPPUNIT_ASSERT_EQUAL(String("fixture"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(String("fixture").length() + 16, sb.capacity());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendBoolean() {
+
+    StringBuilder sb;
+    sb.append(true);
+    CPPUNIT_ASSERT_EQUAL(String("true"), sb.toString());
+    sb.setLength(0);
+    sb.append(false);
+    CPPUNIT_ASSERT_EQUAL(String("false"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendChar() {
+    StringBuilder sb;
+    sb.append('a');
+    CPPUNIT_ASSERT_EQUAL(String("a"), sb.toString());
+    sb.setLength(0);
+    sb.append('b');
+    CPPUNIT_ASSERT_EQUAL(String("b"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendCharArray() {
+
+    StringBuilder sb;
+    sb.append("ab");
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append("cd");
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.append((const char*) NULL),
+        NullPointerException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendCharArrayIntInt() {
+
+    StringBuilder sb;
+    sb.append("ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append("cd");
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+
+    sb.setLength(0);
+    sb.append("abcd", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+
+    sb.setLength(0);
+    sb.append("abcd", 2, 2);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+
+    sb.setLength(0);
+    sb.append("abcd", 2, 0);
+    CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.append((const char*) NULL, 0, 2),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.append("abcd", -1, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.append("abcd", 0, -1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.append("abcd", 2, 3),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendCharSequence() {
+
+    String ab("ab");
+    String cd("cd");
+
+    StringBuilder sb;
+    sb.append(&ab);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(&cd);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    sb.setLength(0);
+    sb.append((CharSequence*) NULL);
+    CPPUNIT_ASSERT_EQUAL(String("null"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendCharSequenceIntInt() {
+
+    String ab("ab");
+    String cd("cd");
+    String abcd("abcd");
+
+    StringBuilder sb;
+    sb.append(&ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(&cd, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    sb.setLength(0);
+    sb.append(&abcd, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(&abcd, 2, 4);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    sb.setLength(0);
+    sb.append((CharSequence*) NULL, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("nu"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendShort() {
+
+    short a = 1;
+    short b = 0;
+    short c = -1;
+
+    StringBuilder sb;
+    sb.append(a);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(a), sb.toString());
+    sb.setLength(0);
+    sb.append(0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(b), sb.toString());
+    sb.setLength(0);
+    sb.append(c);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(c), sb.toString());
+    sb.setLength(0);
+    sb.append(Short::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Short::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Short::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Short::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendInt() {
+
+    int a = 1;
+    int b = 0;
+    int c = -1;
+
+    StringBuilder sb;
+    sb.append(a);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(a), sb.toString());
+    sb.setLength(0);
+    sb.append(0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(b), sb.toString());
+    sb.setLength(0);
+    sb.append(c);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(c), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendLong() {
+    StringBuilder sb;
+    sb.append(1LL);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(1LL), sb.toString());
+    sb.setLength(0);
+    sb.append(0LL);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(0LL), sb.toString());
+    sb.setLength(0);
+    sb.append(-1LL);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(-1LL), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendDouble() {
+    StringBuilder sb;
+    sb.append(1.0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(1.0), sb.toString());
+    sb.setLength(0);
+    sb.append(0.0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(0.0), sb.toString());
+    sb.setLength(0);
+    sb.append(-1.0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(-1.0), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::NaN);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::NaN), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::NEGATIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::NEGATIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::POSITIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::POSITIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendFloat() {
+    StringBuilder sb;
+    sb.append(1.0f);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(1.0f), sb.toString());
+    sb.setLength(0);
+    sb.append(0.0f);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(0.0f), sb.toString());
+    sb.setLength(0);
+    sb.append(-1.0f);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(-1.0f), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::NaN);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::NaN), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::NEGATIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::NEGATIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::POSITIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::POSITIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendString() {
+    StringBuilder sb;
+    sb.append(String("ab"));
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(String("cd"));
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendStringBuffer() {
+
+    // TODO
+//    StringBuilder sb;
+//    sb.append(StringBuffer("ab"));
+//    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+//    sb.setLength(0);
+//    sb.append(StringBuffer("cd"));
+//    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class MyObject {
+    public:
+
+        String toString() const {
+            return "MyObject";
+        }
+
+    };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendRawPointer() {
+
+    MyObject obj;
+    StringBuilder sb;
+    sb.append(&obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testAppendPointer() {
+
+    Pointer<MyObject> obj(new MyObject);
+    StringBuilder sb;
+    sb.append(obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testCapacity() {
+    StringBuilder sb;
+    CPPUNIT_ASSERT_EQUAL(16, sb.capacity());
+    sb.append("0123456789ABCDEF0123456789ABCDEF");
+    CPPUNIT_ASSERT(sb.capacity() > 16);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testCharAt() {
+
+    String fixture = "0123456789";
+    StringBuilder sb(fixture);
+
+    for (int i = 0; i < fixture.length(); i++) {
+        CPPUNIT_ASSERT_EQUAL((char) ('0' + i), sb.charAt(i));
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.charAt(-1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.charAt(fixture.length()),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.charAt(fixture.length() + 1),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testDeleteRange() {
+
+    String fixture = "0123456789";
+    StringBuilder sb(fixture);
+
+    sb.deleteRange(0, 0);
+    CPPUNIT_ASSERT_EQUAL(fixture, sb.toString());
+    sb.deleteRange(5, 5);
+    CPPUNIT_ASSERT_EQUAL(fixture, sb.toString());
+    sb.deleteRange(0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("123456789"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.deleteRange(0, sb.length());
+    CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(0, sb.length());
+
+    {
+        StringBuilder sb(fixture);
+        sb.deleteRange(0, 11);
+        CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+        CPPUNIT_ASSERT_EQUAL(0, sb.length());
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuilder(fixture).deleteRange(-1, 2),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuilder(fixture).deleteRange(13, 12),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuilder(fixture).deleteRange(11, 12),
+        StringIndexOutOfBoundsException);
+
+    {
+        StringBuilder sb;
+        sb.append("abcde");
+        String str = sb.toString();
+        sb.deleteRange(0, sb.length());
+        sb.append("YY");
+        CPPUNIT_ASSERT_EQUAL(String("abcde"), str);
+        CPPUNIT_ASSERT_EQUAL(String("YY"), sb.toString());
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testDeleteCharAt() {
+
+    String fixture = "0123456789";
+    StringBuilder sb(fixture);
+
+    sb.deleteCharAt(0);
+    CPPUNIT_ASSERT_EQUAL(String("123456789"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    {
+        StringBuilder sb(fixture);
+        sb.deleteCharAt(5);
+        CPPUNIT_ASSERT_EQUAL(String("012346789"), sb.toString());
+        CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    }
+    {
+        StringBuilder sb(fixture);
+        sb.deleteCharAt(9);
+        CPPUNIT_ASSERT_EQUAL(String("012345678"), sb.toString());
+        CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuilder(fixture).deleteCharAt(-1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuilder(fixture).deleteCharAt(fixture.length()),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuilder(fixture).deleteCharAt(fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testEnsureCapacity() {
+
+    StringBuilder sb(5);
+    CPPUNIT_ASSERT_EQUAL(5, sb.capacity());
+    sb.ensureCapacity(10);
+    CPPUNIT_ASSERT_EQUAL(12, sb.capacity());
+    sb.ensureCapacity(26);
+    CPPUNIT_ASSERT_EQUAL(26, sb.capacity());
+    sb.ensureCapacity(55);
+    CPPUNIT_ASSERT_EQUAL(55, sb.capacity());
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
new file mode 100644
index 0000000..abf4f2b
--- /dev/null
+++ b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
@@ -0,0 +1,89 @@
+/*
+ * 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_STRINGBUILDERTEST_H_
+#define _DECAF_LANG_STRINGBUILDERTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace decaf {
+namespace lang {
+
+    class StringBuilderTest : public CppUnit::TestFixture {
+    private:
+
+        CPPUNIT_TEST_SUITE( StringBuilderTest );
+        CPPUNIT_TEST( testDefaultConstructor );
+        CPPUNIT_TEST( testConstructorInt );
+        CPPUNIT_TEST( testConstructorString );
+        CPPUNIT_TEST( testAppendBoolean );
+        CPPUNIT_TEST( testAppendChar );
+        CPPUNIT_TEST( testAppendCharArray );
+        CPPUNIT_TEST( testAppendCharArrayIntInt );
+        CPPUNIT_TEST( testAppendCharSequence );
+        CPPUNIT_TEST( testAppendCharSequenceIntInt );
+        CPPUNIT_TEST( testAppendShort );
+        CPPUNIT_TEST( testAppendInt );
+        CPPUNIT_TEST( testAppendLong );
+        CPPUNIT_TEST( testAppendDouble );
+        CPPUNIT_TEST( testAppendFloat );
+        CPPUNIT_TEST( testAppendString );
+        CPPUNIT_TEST( testAppendStringBuffer );
+        CPPUNIT_TEST( testAppendRawPointer );
+        CPPUNIT_TEST( testAppendPointer );
+        CPPUNIT_TEST( testCapacity );
+        CPPUNIT_TEST( testCharAt );
+        CPPUNIT_TEST( testDeleteRange );
+        CPPUNIT_TEST( testDeleteCharAt );
+        CPPUNIT_TEST( testEnsureCapacity );
+        CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+        StringBuilderTest();
+        virtual ~StringBuilderTest();
+
+        void testDefaultConstructor();
+        void testConstructorInt();
+        void testConstructorString();
+        void testAppendBoolean();
+        void testAppendChar();
+        void testAppendCharArray();
+        void testAppendCharArrayIntInt();
+        void testAppendCharSequence();
+        void testAppendCharSequenceIntInt();
+        void testAppendShort();
+        void testAppendInt();
+        void testAppendLong();
+        void testAppendDouble();
+        void testAppendFloat();
+        void testAppendString();
+        void testAppendStringBuffer();
+        void testAppendRawPointer();
+        void testAppendPointer();
+        void testCapacity();
+        void testCharAt();
+        void testDeleteRange();
+        void testDeleteCharAt();
+        void testEnsureCapacity();
+
+    };
+
+}}
+
+#endif /* _DECAF_LANG_STRINGBUILDERTEST_H_ */

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/5b958427/activemq-cpp/src/test/testRegistry.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/testRegistry.cpp b/activemq-cpp/src/test/testRegistry.cpp
index e49561e..e786fe0 100644
--- a/activemq-cpp/src/test/testRegistry.cpp
+++ b/activemq-cpp/src/test/testRegistry.cpp
@@ -267,6 +267,10 @@
 //CPPUNIT_TEST_SUITE_REGISTRATION( decaf::lang::ArrayPointerTest );
 #include <decaf/lang/StringTest.h>
 CPPUNIT_TEST_SUITE_REGISTRATION( decaf::lang::StringTest );
+#include <decaf/lang/StringBuilderTest.h>
+CPPUNIT_TEST_SUITE_REGISTRATION( decaf::lang::StringBuilderTest );
+#include <decaf/lang/StringBufferTest.h>
+CPPUNIT_TEST_SUITE_REGISTRATION( decaf::lang::StringBufferTest );
 //
 //#include <decaf/net/InetAddressTest.h>
 //CPPUNIT_TEST_SUITE_REGISTRATION( decaf::net::InetAddressTest );