Skip to content
Browse files

Work on more String utils StringBuilder and StringBuffer.

  • Loading branch information...
1 parent 12bb514 commit 5b958427ef1181a086285bddba87f7a85fdc82e2 @tabish121 tabish121 committed Nov 13, 2013
View
6 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 \
View
4 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:
View
436 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;
+ }
+}
View
262 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_ */
View
56 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;
+}
View
104 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_ */
View
151 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;
+}
View
261 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_ */
View
4 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 \
View
58 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));
+}
View
47 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_ */
View
505 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());
+}
View
89 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_ */
View
4 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 );

0 comments on commit 5b95842

Please sign in to comment.
Something went wrong with that request. Please try again.