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 2008/04/29 22:52:37 UTC

svn commit: r652104 [5/29] - in /activemq/activemq-cpp/trunk: ./ m4/ src/examples/ src/examples/consumers/ src/main/ src/main/decaf/ src/main/decaf/internal/ src/main/decaf/internal/net/ src/main/decaf/internal/nio/ src/main/decaf/internal/util/ src/ma...

Added: activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,746 @@
+/*
+ * 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 "ByteArrayAdapter.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <decaf/lang/Math.h>
+#include <decaf/lang/Float.h>
+#include <decaf/lang/Double.h>
+
+using namespace decaf;
+using namespace decaf::nio;
+using namespace decaf::internal;
+using namespace decaf::internal::util;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( std::size_t capacity ) {
+
+    try{
+
+        this->array.bytes = new unsigned char[capacity];
+        memset( this->array.bytes, 0, capacity );
+        this->initialize( array.bytes, capacity, true );
+    }
+    DECAF_CATCH_RETHROW( Exception )
+    DECAF_CATCHALL_THROW( Exception )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( unsigned char* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( array, capacity, own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( char* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( reinterpret_cast<unsigned char*>( array ), capacity, own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( double* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( reinterpret_cast<unsigned char*>( array ),
+                          capacity * sizeof( double ), own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( float* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( reinterpret_cast<unsigned char*>( array ),
+                          capacity * sizeof( float ), own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( long long* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( reinterpret_cast<unsigned char*>( array ),
+                          capacity * sizeof( long long ), own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( int* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( reinterpret_cast<unsigned char*>( array ),
+                          capacity * sizeof( int ), own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::ByteArrayAdapter( short* array, std::size_t capacity, bool own )
+    throw( lang::exceptions::NullPointerException ) {
+
+    try{
+        this->initialize( reinterpret_cast<unsigned char*>( array ),
+                          capacity * sizeof( short ), own );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCHALL_THROW( NullPointerException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ByteArrayAdapter::initialize( unsigned char* array, std::size_t capacity, bool own ) {
+
+    try{
+
+        if( array == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::initialize - Passed Buffer is null" );
+        }
+
+        this->array.bytes = array;
+        this->capacity = capacity;
+        this->own = own;
+    }
+    DECAF_CATCH_RETHROW( Exception )
+    DECAF_CATCHALL_THROW( Exception )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter::~ByteArrayAdapter() {
+
+    try{
+
+        if( own ) {
+            delete [] array.bytes;
+        }
+    }
+    DECAF_CATCH_NOTHROW( Exception )
+    DECAF_CATCHALL_NOTHROW()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ByteArrayAdapter::read( unsigned char* buffer, std::size_t offset, std::size_t length ) const
+    throw( NullPointerException, BufferUnderflowException ) {
+
+    try{
+
+        if( length == 0 ) {
+            return;
+        }
+
+        if( buffer == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::write - Passed buffer is null" );
+        }
+
+        if( ( offset + length ) > this->capacity ) {
+            throw BufferUnderflowException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::read - Not enough data to fill request." );
+        }
+
+        // Read, starting at offset, length number of bytes to Buffer
+        memcpy( buffer, this->array.bytes + offset, length );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCH_RETHROW( BufferUnderflowException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, BufferUnderflowException )
+    DECAF_CATCHALL_THROW( BufferUnderflowException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ByteArrayAdapter::write( unsigned char* buffer, std::size_t offset, std::size_t length )
+    throw( NullPointerException, BufferOverflowException ) {
+
+    try{
+
+        if( length == 0 ) {
+            return;
+        }
+
+        if( buffer == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::write - Passed buffer is null" );
+        }
+
+        if( ( offset + length ) > this->capacity ) {
+            throw BufferOverflowException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::read - Not room in array to hold request." );
+        }
+
+        // Write, starting at offset, length number of bytes from buffer.
+        memcpy( this->array.bytes + offset, buffer, length );
+    }
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCH_RETHROW( BufferOverflowException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, BufferOverflowException )
+    DECAF_CATCHALL_THROW( BufferOverflowException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ByteArrayAdapter::resize( std::size_t capacity )
+    throw ( lang::exceptions::InvalidStateException ) {
+
+    try{
+
+        if( !own ) {
+            throw InvalidStateException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::resize - Not the array owner, can't resize" );
+        }
+
+        // Save old state
+        std::size_t oldCapacity = this->capacity;
+        unsigned char* oldArray = this->array.bytes;
+
+        // Resize and copy as much of the old as we can back and delete old array
+        this->array.bytes = new unsigned char[capacity];
+        this->capacity = capacity;
+        memcpy( this->array.bytes, oldArray, Math::min( (int)oldCapacity, (int)capacity ) );
+        delete [] oldArray;
+    }
+    DECAF_CATCH_RETHROW( InvalidStateException )
+    DECAF_CATCHALL_THROW( InvalidStateException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ByteArrayAdapter::clear() {
+    memset( this->array.bytes, 0, this->capacity );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+unsigned char& ByteArrayAdapter::operator[]( std::size_t index )
+    throw ( IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index > this->capacity ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::operator[] - Index %d is out of bounds", index );
+        }
+
+        return this->array.bytes[index];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+const unsigned char& ByteArrayAdapter::operator[]( std::size_t index ) const
+    throw ( decaf::lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index > this->capacity ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::operator[] - Index %d is out of bounds", index );
+        }
+
+        return this->array.bytes[index];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+unsigned char ByteArrayAdapter::get( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::get - Not enough data to fill request." );
+        }
+
+        return (*this)[index];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double ByteArrayAdapter::getDouble( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getDoubleCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getDouble(i) - Not enough data to fill a long long." );
+        }
+
+        return this->array.doubles[ index ];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double ByteArrayAdapter::getDoubleAt( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        unsigned long long lvalue = this->getLongAt( index );
+        return Double::longBitsToDouble( lvalue );
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float ByteArrayAdapter::getFloat( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getFloatCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getFloat(i) - Not enough data to fill a long long." );
+        }
+
+        return this->array.floats[ index ];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float ByteArrayAdapter::getFloatAt( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        unsigned int ivalue = this->getIntAt( index );
+        return Float::intBitsToFloat( ivalue );
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long ByteArrayAdapter::getLong( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getLongCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getLong(i) - Not enough data to fill a long long." );
+        }
+
+        return this->array.longs[ index ];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long ByteArrayAdapter::getLongAt( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( ( index + sizeof( long long ) ) > this->getCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getLong(i) - Not enough data to fill a long long." );
+        }
+
+        unsigned long long value = 0;
+        unsigned char buffer[sizeof(value)] = {0};
+        this->read( buffer, index, sizeof(value) );
+
+        // Have to do it this way because on Solaris and Cygwin we get all
+        // kinds of warnings when shifting a byte up into a long long.
+        unsigned long long byte1 = buffer[0] & 0x00000000000000FFULL;
+        unsigned long long byte2 = buffer[1] & 0x00000000000000FFULL;
+        unsigned long long byte3 = buffer[2] & 0x00000000000000FFULL;
+        unsigned long long byte4 = buffer[3] & 0x00000000000000FFULL;
+        unsigned long long byte5 = buffer[4] & 0x00000000000000FFULL;
+        unsigned long long byte6 = buffer[5] & 0x00000000000000FFULL;
+        unsigned long long byte7 = buffer[6] & 0x00000000000000FFULL;
+        unsigned long long byte8 = buffer[7] & 0x00000000000000FFULL;
+
+        value = ( byte1 << 56 | byte2 << 48 | byte3 << 40 | byte4 << 32 |
+                  byte5 << 24 | byte6 << 16 | byte7 << 8  | byte8 << 0 );
+
+        return value;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int ByteArrayAdapter::getInt( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getIntCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getInt(i) - Not enough data to fill an int." );
+        }
+
+        return this->array.ints[ index ];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int ByteArrayAdapter::getIntAt( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( ( index + sizeof( int ) ) > this->getCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getInt(i) - Not enough data to fill an int." );
+        }
+
+        unsigned int value = 0;
+        unsigned char buffer[sizeof(value)] = {0};
+        this->read( buffer, index, sizeof(value) );
+        value |= (buffer[0] << 24 | buffer[1] << 16 |
+                  buffer[2] << 8 | buffer[3] << 0);
+
+        return value;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+short ByteArrayAdapter::getShort( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException )  {
+
+    try{
+
+        if( index >= this->getShortCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getShort(i) - Not enough data to fill a short." );
+        }
+
+        return this->array.shorts[ index ];
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+short ByteArrayAdapter::getShortAt( std::size_t index ) const
+    throw ( lang::exceptions::IndexOutOfBoundsException )  {
+
+    try{
+
+        if( ( index + sizeof( short ) ) > this->getCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::getShort(i) - Not enough data to fill a short." );
+        }
+
+        short value = 0;
+        unsigned char buffer[sizeof(value)] = {0};
+        this->read( buffer, index, sizeof(value) );
+        value |= (buffer[0] << 8 | buffer[1] << 0);
+
+        return value;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::put( std::size_t index, unsigned char value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::put(i,i) - Not enough data to fill request." );
+        }
+
+        (*this)[index] = value;
+
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putChar( std::size_t index, char value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        this->put( index, value );
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putDouble( std::size_t index, double value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getDoubleCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::putDouble(i,i) - Not enough data to fill request." );
+        }
+
+        this->array.doubles[ index ] = value;
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putDoubleAt( std::size_t index, double value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        this->putLongAt( index, Double::doubleToLongBits( value ) );
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putFloat( std::size_t index, float value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getFloatCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::putFloat(i,i) - Not enough data to fill request." );
+        }
+
+        this->array.floats[index] = value;
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putFloatAt( std::size_t index, float value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        this->putIntAt( index, Float::floatToIntBits( value ) );
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putLong( std::size_t index, long long value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getLongCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::putLong(i,i) - Not enough data to fill request." );
+        }
+
+        this->array.longs[index] = value;
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putLongAt( std::size_t index, long long value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        unsigned char buffer[sizeof(value)];
+
+        buffer[0] = (unsigned char)((value & 0xFF00000000000000ULL) >> 56);
+        buffer[1] = (unsigned char)((value & 0x00FF000000000000ULL) >> 48);
+        buffer[2] = (unsigned char)((value & 0x0000FF0000000000ULL) >> 40);
+        buffer[3] = (unsigned char)((value & 0x000000FF00000000ULL) >> 32);
+        buffer[4] = (unsigned char)((value & 0x00000000FF000000ULL) >> 24);
+        buffer[5] = (unsigned char)((value & 0x0000000000FF0000ULL) >> 16);
+        buffer[6] = (unsigned char)((value & 0x000000000000FF00ULL) >> 8);
+        buffer[7] = (unsigned char)((value & 0x00000000000000FFULL) >> 0);
+
+        this->write( buffer, index, sizeof(value) );
+
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putInt( std::size_t index, int value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getIntCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::putInt(i,i) - Not enough data to fill request." );
+        }
+
+        this->array.ints[index] = value;
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putIntAt( std::size_t index, int value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        unsigned char buffer[sizeof(value)];
+
+        buffer[0] = (value & 0xFF000000) >> 24;
+        buffer[1] = (value & 0x00FF0000) >> 16;
+        buffer[2] = (value & 0x0000FF00) >> 8;
+        buffer[3] = (value & 0x000000FF) >> 0;
+
+        this->write( buffer, index, sizeof(value) );
+
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putShort( std::size_t index, short value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        if( index >= this->getShortCapacity() ) {
+            throw IndexOutOfBoundsException(
+                __FILE__, __LINE__,
+                "ByteArrayAdapter::putShort(i,i) - Not enough data to fill request." );
+        }
+
+        this->array.shorts[index] = value;
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+ByteArrayAdapter& ByteArrayAdapter::putShortAt( std::size_t index, short value )
+    throw( lang::exceptions::IndexOutOfBoundsException ) {
+
+    try{
+
+        unsigned char buffer[sizeof(value)];
+
+        buffer[0] = (value & 0xFF00) >> 8;
+        buffer[1] = (value & 0x00FF) >> 0;
+
+        this->write( buffer, index, sizeof(value) );
+
+        return *this;
+    }
+    DECAF_CATCH_RETHROW( IndexOutOfBoundsException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IndexOutOfBoundsException )
+    DECAF_CATCHALL_THROW( IndexOutOfBoundsException )
+}

Added: activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/internal/util/ByteArrayAdapter.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,637 @@
+/*
+ * 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_INTERNAL_UTIL_BYTEARRAYADAPTER_H_
+#define _DECAF_INTERNAL_UTIL_BYTEARRAYADAPTER_H_
+
+#include <decaf/lang/exceptions/InvalidStateException.h>
+#include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/nio/BufferUnderflowException.h>
+#include <decaf/nio/BufferOverflowException.h>
+
+namespace decaf{
+namespace internal{
+namespace util{
+
+    /**
+     * This class adapts primitve type arrays to a base byte array so that the
+     * classes can interoperate on the same base byte array without copying data.
+     * All the array types are mapped down to a byte array and methods are
+     * supplied for accesing the data in any of the primitve type forms.
+     * <p>
+     * Methods in this class that do not return a specifc value return a
+     * reference to this object so that calls can be chained.
+     */
+    class DECAF_API ByteArrayAdapter {
+    private:
+
+        // Used to allow this adapter to view its array as the different
+        // types it supports
+        union Array {
+            unsigned char* bytes;
+            char* chars;
+            short* shorts;
+            int* ints;
+            long long* longs;
+            float* floats;
+            double* doubles;
+        };
+
+        // Buffer to read and write to, may be shared with other instances.
+        Array array;
+
+        // Size of the Buffer
+        std::size_t capacity;
+
+        // Wether this object owns the buffer
+        bool own;
+
+    public:
+
+        /**
+         * Creates a byte array object that is allocated internally and is then owned
+         * and deleted when this object is deleted.  The array is initially created
+         * with all elements initialized to zero.
+         * @param capacity - size of the array, this is the limit we read and write to.
+         */
+        ByteArrayAdapter( std::size_t capacity );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( unsigned char* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( char* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( double* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( float* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( long long* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( int* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        /**
+         * Creates a byte array object that wraps the given array.  If the own flag
+         * is set then it will delete this array when this object is deleted.
+         * @param array - array to wrap
+         * @param capacity - size of the array, this is the limit we read and write to.
+         * @param own - is this class now the owner of the pointer.
+         * @throws NullPointerException if buffer is NULL
+         */
+        ByteArrayAdapter( short* array, std::size_t capacity, bool own = false )
+            throw( lang::exceptions::NullPointerException );
+
+        virtual ~ByteArrayAdapter();
+
+        /**
+         * Gets the capacity of the underlying array.
+         * @return the size the array.
+         */
+        virtual std::size_t getCapacity() const {
+            return this->capacity;
+        }
+
+        /**
+         * Gets the capacity of the underlying array as if it contains chars
+         * @return the size the array.
+         */
+        virtual std::size_t getCharCapacity() const {
+            return this->capacity;
+        }
+
+        /**
+         * Gets the capacity of the underlying array as if it contains doubles
+         * @return the size the array.
+         */
+        virtual std::size_t getDoubleCapacity() const {
+            return this->capacity / sizeof( double );
+        }
+
+        /**
+         * Gets the capacity of the underlying array as if it contains doubles
+         * @return the size the array.
+         */
+        virtual std::size_t getFloatCapacity() const {
+            return this->capacity / sizeof( float );
+        }
+
+        /**
+         * Gets the capacity of the underlying array as if it contains doubles
+         * @return the size the array.
+         */
+        virtual std::size_t getLongCapacity() const {
+            return this->capacity / sizeof( long long );
+        }
+
+        /**
+         * Gets the capacity of the underlying array as if it contains ints
+         * @return the size the array.
+         */
+        virtual std::size_t getIntCapacity() const {
+            return this->capacity / sizeof( int );
+        }
+
+        /**
+         * Gets the capacity of the underlying array as if it contains shorts
+         * @return the size the array.
+         */
+        virtual std::size_t getShortCapacity() const {
+            return this->capacity / sizeof( short );
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an unsigned char* pointer to the array this object wraps.
+         */
+        virtual unsigned char* getByteArray() {
+            return this->array.bytes;
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an char* pointer to the array this object wraps.
+         */
+        virtual char* getCharArray() {
+            return this->array.chars;
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an short* pointer to the array this object wraps.
+         */
+        virtual short* getShortArray() {
+            return this->array.shorts;
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an int* pointer to the array this object wraps.
+         */
+        virtual int* getIntArray() {
+            return this->array.ints;
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an long long* pointer to the array this object wraps.
+         */
+        virtual long long* getLongArray() {
+            return this->array.longs;
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an double* pointer to the array this object wraps.
+         */
+        virtual double* getDoubleArray() {
+            return this->array.doubles;
+        }
+
+        /**
+         * Gets the pointer to the array we are wrapping.  Changes to the data in this
+         * array are reflected by all ByteArrayAdapter objects that point to this array.
+         * @returns an float* pointer to the array this object wraps.
+         */
+        virtual float* getFloatArray() {
+            return this->array.floats;
+        }
+
+        /**
+         * Reads from the Byte array starting at the specified offset and reading
+         * the specified length.  If the length is greater than the capacity of this
+         * underlying byte array then an BufferUnderflowException is thrown.
+         * @param buffer - the buffer to read data from this array into.
+         * @param offset - postition in this array to start reading from.
+         * @param length - the amount of data to read from this array.
+         * @throws NullPointerException if buffer is null
+         * @throws BufferUnderflowException if there is not enought data to read
+         * because the offset or the length is greater than the size of this array.
+         */
+        virtual void read( unsigned char* buffer, std::size_t offset, std::size_t length ) const
+            throw( decaf::lang::exceptions::NullPointerException,
+                   decaf::nio::BufferUnderflowException );
+
+        /**
+         * Writes from the Byte array given, starting at the specified offset and writing
+         * the specified amoutn of data into this objects internal array..  If the length
+         * is greater than the capacity of this underlying byte array then an
+         * BufferOverflowException is thrown.
+         * @param buffer - the buffer to write get data written into this array.
+         * @param offset - postition in this array to start writing from.
+         * @param length - the amount of data to write to this array.
+         * @throws NullPointerException if buffer is null
+         * @throws BufferOverflowException if the amount of data to be written to this
+         * array or the offset given are larger than this array's capacity.
+         */
+        virtual void write( unsigned char* buffer, std::size_t offset, std::size_t length )
+            throw( decaf::lang::exceptions::NullPointerException,
+                   decaf::nio::BufferOverflowException );
+
+        /**
+         * Resizes the underlying array to the new given capacity, preserving all the
+         * Data that was previouly in the array, unless the resize is smaller than the
+         * current size in which case only the data that will fit into the new array is
+         * preserved.
+         * <p>
+         * A ByteArrayAdapter can only be resized when it owns the underlying array, if it does
+         * not then it will throw an IllegalStateException.
+         * @param capacity - the new capacity of the array.
+         * @throws InvalidStateException if this object does not own the buffer.
+         */
+        virtual void resize( std::size_t capacity )
+            throw ( lang::exceptions::InvalidStateException );
+
+        /**
+         * Clear all data from that Array, setting the underlying bytes to zero.
+         */
+        virtual void clear();
+
+        /**
+         * Allows the ByteArrayAdapter to be indexed as a standard array.  calling the
+         * non const version allows the user to change the value at index
+         * @param index - the position in the array to access
+         * @throws IndexOutOfBoundsException
+         */
+        unsigned char& operator[]( std::size_t index )
+            throw ( decaf::lang::exceptions::IndexOutOfBoundsException );
+        const unsigned char& operator[]( std::size_t index ) const
+            throw ( decaf::lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Absolute get method. Reads the byte at the given index.
+         * @param index - the index in the Buffer where the byte is to be read
+         * @returns the byte that is located at the given index
+         * @throws IndexOutOfBoundsException - If index is not smaller than the
+         * buffer's limit
+         */
+        virtual unsigned char get( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads one byte at the given index and returns it
+         * @param index - the index in the Buffer where the byte is to be read
+         * @returns the char at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If index is not smaller than the
+         * buffer's limit
+         */
+        virtual char getChar( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException ) {
+
+            return (char)this->get( index );
+        }
+
+        /**
+         * Reads eight bytes at the given index and returns it.  The index is a
+         * relative to the size of the type to be read, in otherwords when accessing
+         * the element in the array index * sizeof( type ) if the actual start index
+         * of the type to be read.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the double at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual double getDouble( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads eight bytes at the given byte index and returns it
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the double at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual double getDoubleAt( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads four bytes at the given index and returns it. The index is a
+         * relative to the size of the type to be read, in otherwords when accessing
+         * the element in the array index * sizeof( type ) if the actual start index
+         * of the type to be read.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the float at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual float getFloat( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads four bytes at the given byte index and returns it
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the float at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual float getFloatAt( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads eight bytes at the given index and returns it.  The index is a
+         * relative to the size of the type to be read, in otherwords when accessing
+         * the element in the array index * sizeof( type ) if the actual start index
+         * of the type to be read.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the long long at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual long long getLong( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads eight bytes at the given byte index and returns it.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the long long at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual long long getLongAt( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads four bytes at the given index and returns it.  The index is a
+         * relative to the size of the type to be read, in otherwords when accessing
+         * the element in the array index * sizeof( type ) if the actual start index
+         * of the type to be read.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the int at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual int getInt( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads four bytes at the given byte index and returns it.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the int at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual int getIntAt( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads two bytes at the given index and returns it. The index is a
+         * relative to the size of the type to be read, in otherwords when accessing
+         * the element in the array index * sizeof( type ) if the actual start index
+         * of the type to be read.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the short at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual short getShort( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Reads two bytes at the given byte index and returns it.
+         * @param index - the index in the Buffer where the bytes are to be read
+         * @returns the short at the given index in the buffer
+         * @throws IndexOutOfBoundsException - If there are not enough bytes
+         * remaining to fill the requested Data Type
+         */
+        virtual short getShortAt( std::size_t index ) const
+            throw ( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes the given byte into this buffer at the given index. The index is a
+         * relative to the size of the type to be read, in otherwords when accessing
+         * the element in the array index * sizeof( type ) if the actual start index
+         * of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the byte to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& put( std::size_t index, unsigned char value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes one byte containing the given value, into this buffer at the
+         * given index. The index is a relative to the size of the type to be read,
+         * in otherwords when accessing the element in the array index * sizeof( type )
+         * if the actual start index of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putChar( std::size_t index, char value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes eight bytes containing the given value, into this buffer at the
+         * given index. The index is a relative to the size of the type to be read,
+         * in otherwords when accessing the element in the array index * sizeof( type )
+         * if the actual start index of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putDouble( std::size_t index, double value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes eight bytes containing the given value, into this buffer at the
+         * given byte index.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putDoubleAt( std::size_t index, double value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes four bytes containing the given value, into this buffer at the
+         * given index. The index is a relative to the size of the type to be read,
+         * in otherwords when accessing the element in the array index * sizeof( type )
+         * if the actual start index of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putFloat( std::size_t index, float value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes four bytes containing the given value, into this buffer at the
+         * given byte index.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putFloatAt( std::size_t index, float value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes eight bytes containing the given value, into this buffer at the
+         * given index. The index is a relative to the size of the type to be read,
+         * in otherwords when accessing the element in the array index * sizeof( type )
+         * if the actual start index of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putLong( std::size_t index, long long value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes eight bytes containing the given value, into this buffer at the
+         * given byte index.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putLongAt( std::size_t index, long long value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes four bytes containing the given value, into this buffer at the
+         * given index. The index is a relative to the size of the type to be read,
+         * in otherwords when accessing the element in the array index * sizeof( type )
+         * if the actual start index of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putInt( std::size_t index, int value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes four bytes containing the given value, into this buffer at the
+         * given byte index.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putIntAt( std::size_t index, int value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes two bytes containing the given value, into this buffer at the
+         * given index. The index is a relative to the size of the type to be read,
+         * in otherwords when accessing the element in the array index * sizeof( type )
+         * if the actual start index of the type to be read.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putShort( std::size_t index, short value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+        /**
+         * Writes two bytes containing the given value, into this buffer at the
+         * given byte index.
+         * @param index - position in the Buffer to write the data
+         * @param value - the value to write.
+         * @returns a reference to this buffer
+         * @throw IndexOutOfBoundsException - If index greater than the buffer's limit
+         * minus the size of the type being written.
+         */
+        virtual ByteArrayAdapter& putShortAt( std::size_t index, short value )
+            throw( lang::exceptions::IndexOutOfBoundsException );
+
+    private:
+
+        void initialize( unsigned char* buffer, std::size_t capacity, bool own );
+
+    };
+
+}}}
+
+#endif /*_DECAF_INTERNAL_UTIL_BYTEARRAYADAPTER_H_*/

Added: activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,312 @@
+/*
+ *  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 "HexStringParser.h"
+
+#include <decaf/lang/Character.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Double.h>
+#include <decaf/lang/Float.h>
+#include <decaf/util/StringTokenizer.h>
+#include <decaf/lang/exceptions/NumberFormatException.h>
+#include <apr_pools.h>
+#include <apr_strmatch.h>
+
+using namespace decaf;
+using namespace decaf::util;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::internal;
+using namespace decaf::internal::util;
+
+////////////////////////////////////////////////////////////////////////////////
+const std::string HexStringParser::HEX_SIGNIFICANT =
+    "0[xX](\\p{XDigit}+\\.?|\\p{XDigit}*\\.\\p{XDigit}+)";
+const std::string HexStringParser::BINARY_EXPONENT =
+    "[pP]([+-]?\\d+)";
+const std::string HexStringParser::FLOAT_TYPE_SUFFIX =
+    "[fFdD]?";
+const std::string HexStringParser::HEX_PATTERN =
+    "[\\x00-\\x20]*([+-]?)" + HEX_SIGNIFICANT + BINARY_EXPONENT + FLOAT_TYPE_SUFFIX + "[\\x00-\\x20]*";
+
+////////////////////////////////////////////////////////////////////////////////
+HexStringParser::HexStringParser( int exponentWidth, int mantissaWidth ) {
+
+    this->EXPONENT_WIDTH = exponentWidth;
+    this->MANTISSA_WIDTH = mantissaWidth;
+
+    this->EXPONENT_BASE = ~( -1 << (exponentWidth - 1) );
+    this->MAX_EXPONENT = ~( -1 << exponentWidth );
+    this->MIN_EXPONENT = -( MANTISSA_WIDTH + 1 );
+    this->MANTISSA_MASK = ~( -1 << mantissaWidth );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+double HexStringParser::parseDouble( const std::string& hexString ) {
+
+    HexStringParser parser( DOUBLE_EXPONENT_WIDTH, DOUBLE_MANTISSA_WIDTH );
+    long long result = parser.parse( hexString );
+    return Double::longBitsToDouble( result );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float HexStringParser::parseFloat( const std::string& hexString ) {
+
+    HexStringParser parser( FLOAT_EXPONENT_WIDTH, FLOAT_MANTISSA_WIDTH );
+    int result = (int)parser.parse( hexString );
+    return Float::intBitsToFloat( result );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+long long HexStringParser::parse( const std::string& hexString ) {
+
+    std::string* hexSegments = getSegmentsFromHexString( hexString );
+    std::string signStr = hexSegments[0];
+    std::string significantStr = hexSegments[1];
+    std::string exponentStr = hexSegments[2];
+    delete hexSegments;
+
+    parseHexSign( signStr );
+    parseExponent( exponentStr );
+    parseMantissa( significantStr );
+
+    sign <<= ( MANTISSA_WIDTH + EXPONENT_WIDTH );
+    exponent <<= MANTISSA_WIDTH;
+    return sign | exponent | mantissa;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string* HexStringParser::getSegmentsFromHexString( DECAF_UNUSED const std::string& hexString ) {
+
+//    apr_pool_t* thePool = NULL;
+//    apr_pool_create( &thePool, NULL );
+//    apr_strmatch_pattern* pattern =
+//        apr_strmatch_precompile( thePool, HEX_PATTERN.c_str(), 0 );
+//
+//    std::vector<std::string> hexSegments;
+//
+
+
+    // TODO
+//    Matcher matcher = PATTERN.matcher(hexString);
+//    if( !matcher.matches() ) {
+//        throw NumberFormatException(
+//            __FILE__, __LINE__,
+//            "HexStringParser::getSegmentsFromHexString"
+//            "Invalid hex string:", hexString.c_str() );
+//    }
+//
+//    std::string* hexSegments = new std::string[3];
+//    hexSegments[0] = matcher.group(1);
+//    hexSegments[1] = matcher.group(2);
+//    hexSegments[2] = matcher.group(3);
+//
+//    return hexSegments;
+
+    return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::parseExponent(const std::string& exponentStr) {
+
+    std::string newExponentStr = exponentStr;
+
+    char leadingChar = newExponentStr.at(0);
+    int expSign = ( leadingChar == '-' ? -1 : 1 );
+    if( !Character::isDigit( leadingChar ) ) {
+        newExponentStr = newExponentStr.substr( 1, newExponentStr.size() );
+    }
+
+    try {
+        exponent = expSign * Long::parseLong( exponentStr );
+        checkedAddExponent( EXPONENT_BASE );
+    } catch( exceptions::NumberFormatException& e ) {
+        exponent = expSign * Long::MAX_VALUE;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::parseMantissa(const std::string& significantStr) {
+
+    StringTokenizer tokenizer( significantStr, "\\." );
+    std::vector<std::string> strings;
+
+    tokenizer.toArray( strings );
+
+    std::string strIntegerPart = strings[0];
+    std::string strDecimalPart = strings.size() > 1 ? strings[1] : "";
+
+    std::string significand =
+        getNormalizedSignificand( strIntegerPart, strDecimalPart) ;
+
+    if( significand == "0" ) {
+        setZero();
+        return;
+    }
+
+    int offset = getOffset( strIntegerPart, strDecimalPart );
+    checkedAddExponent( offset );
+
+    if( exponent >= MAX_EXPONENT ) {
+        setInfinite();
+        return;
+    }
+
+    if( exponent <= MIN_EXPONENT ) {
+        setZero();
+        return;
+    }
+
+    if( significand.length() > MAX_SIGNIFICANT_LENGTH ) {
+        abandonedNumber = significand.substr( MAX_SIGNIFICANT_LENGTH );
+        significand = significand.substr( 0, MAX_SIGNIFICANT_LENGTH );
+    }
+
+    mantissa = Long::parseLong( significand, HEX_RADIX );
+
+    if( exponent >= 1 ) {
+        processNormalNumber();
+    } else{
+        processSubNormalNumber();
+    }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::checkedAddExponent( long long offset ) {
+
+    long long result = exponent + offset;
+    int expSign = Long::signum( exponent );
+
+    if( expSign * Long::signum( offset ) > 0 &&
+        expSign * Long::signum( result ) < 0 ) {
+
+        exponent = expSign * Long::MAX_VALUE;
+    } else {
+        exponent = result;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::processNormalNumber() {
+    int desiredWidth = MANTISSA_WIDTH + 2;
+    fitMantissaInDesiredWidth( desiredWidth );
+    round();
+    mantissa = mantissa & MANTISSA_MASK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::processSubNormalNumber() {
+    int desiredWidth = MANTISSA_WIDTH + 1;
+    desiredWidth += (int)exponent;//lends bit from mantissa to exponent
+    exponent = 0;
+    fitMantissaInDesiredWidth( desiredWidth );
+    round();
+    mantissa = mantissa & MANTISSA_MASK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::fitMantissaInDesiredWidth(int desiredWidth){
+    int bitLength = countBitsLength( mantissa );
+    if( bitLength > desiredWidth ) {
+        discardTrailingBits( bitLength - desiredWidth );
+    } else {
+        mantissa <<= ( desiredWidth - bitLength );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::discardTrailingBits( long long num ) {
+    long long mask = ~( -1L << num );
+    abandonedNumber += ( mantissa & mask );
+    mantissa >>= num;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HexStringParser::round() {
+
+    std::string result = abandonedNumber;
+    replaceAll( result, "0+", "" );
+
+    bool moreThanZero = ( result.length() > 0 ? true : false );
+
+    int lastDiscardedBit = (int)( mantissa & 1L );
+    mantissa >>= 1;
+    int tailBitInMantissa = (int)( mantissa & 1L );
+
+    if( lastDiscardedBit == 1 && ( moreThanZero || tailBitInMantissa == 1 ) ) {
+
+        int oldLength = countBitsLength( mantissa );
+        mantissa += 1L;
+        int newLength = countBitsLength( mantissa );
+
+        //Rounds up to exponent when whole bits of mantissa are one-bits.
+        if( oldLength >= MANTISSA_WIDTH && newLength > oldLength ) {
+            checkedAddExponent( 1 );
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string HexStringParser::getNormalizedSignificand(
+    const std::string& strIntegerPart, const std::string& strDecimalPart ) {
+
+    std::string significand = strIntegerPart + strDecimalPart;
+
+    replaceFirst( significand, "^0x", "" );
+
+    if( significand.length() == 0 ) {
+        significand = "0";
+    }
+    return significand;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int HexStringParser::getOffset(
+    const std::string& strIntegerPart, const std::string& strDecimalPart ) {
+
+    std::string strIntegerPart2 = strIntegerPart;
+
+    replaceFirst( strIntegerPart2, "^0+", "" );
+
+    //If the Interger part is a nonzero number.
+    if( strIntegerPart.length() != 0 ) {
+        std::string leadingNumber = strIntegerPart.substr( 0, 1 );
+        return ( strIntegerPart.length() - 1) * 4 +
+               countBitsLength(Long::parseLong( leadingNumber,HEX_RADIX ) ) - 1;
+    }
+
+    //If the Interger part is a zero number.
+    int i;
+    for( i = 0; (std::size_t)i < strDecimalPart.length() && strDecimalPart.at(i) == '0'; i++ );
+
+    if( (std::size_t)i == strDecimalPart.length() ) {
+        return 0;
+    }
+
+    std::string leadingNumber = strDecimalPart.substr( i,i + 1 );
+
+    return (-i - 1) * 4 +
+        countBitsLength( Long::parseLong( leadingNumber, HEX_RADIX) ) - 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int HexStringParser::countBitsLength(long long value) {
+    int leadingZeros = Long::numberOfLeadingZeros( value );
+    return Long::SIZE - leadingZeros;
+}

Added: activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.h?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.h (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/internal/util/HexStringParser.h Tue Apr 29 13:52:30 2008
@@ -0,0 +1,209 @@
+/*
+ *  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_INTERNAL_UTIL_HEXSTRINGPARSER_H_
+#define _DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_
+
+#include <decaf/util/Config.h>
+#include <string>
+
+namespace decaf{
+namespace internal{
+namespace util{
+
+    class HexStringParser {
+    private:
+
+        static const unsigned int DOUBLE_EXPONENT_WIDTH = 11;
+        static const unsigned int DOUBLE_MANTISSA_WIDTH = 52;
+        static const unsigned int FLOAT_EXPONENT_WIDTH = 8;
+        static const unsigned int FLOAT_MANTISSA_WIDTH = 23;
+        static const unsigned int HEX_RADIX = 16;
+        static const unsigned int MAX_SIGNIFICANT_LENGTH = 15;
+
+        static const std::string HEX_SIGNIFICANT;
+        static const std::string BINARY_EXPONENT;
+        static const std::string FLOAT_TYPE_SUFFIX;
+        static const std::string HEX_PATTERN;
+
+        // TODO
+        //static final Pattern PATTERN = Pattern.compile(HEX_PATTERN);
+
+    private:
+
+        int EXPONENT_WIDTH;
+        int MANTISSA_WIDTH;
+        long EXPONENT_BASE;
+        long MAX_EXPONENT;
+        long MIN_EXPONENT;
+        long MANTISSA_MASK;
+        long sign;
+        long exponent;
+        long mantissa;
+        std::string abandonedNumber;
+
+    public:
+
+        /**
+         * Create a new HexParser
+         * @param exponentWidth - Width of the exponent for the type to parse
+         * @param mantissaWidth - Width of the mantissa for the type to parse
+         */
+        HexStringParser( int exponentWidth, int mantissaWidth );
+
+        virtual ~HexStringParser() {}
+
+        /**
+         * Parses a hex string using the specs given in the constructor
+         * and returns a long long with the bits of the parsed string, the
+         * caller can then convert those to a float or doulbe as needed.
+         * @param hexString - string to parse
+         * @returns the bits parsed from the string
+         */
+        long long parse( const std::string& hexString );
+
+    private:
+
+        /*
+         * Parses the sign field.
+         * @param sign string to parse
+         */
+        void parseHexSign( const std::string& signStr ) {
+            this->sign = signStr.compare("-") == 0 ? 1 : 0;
+        }
+
+        /*
+         * Parses the exponent field.
+         * @param exponent string to parse
+         */
+        void parseExponent( const std::string& exponentStr );
+
+        /*
+         * Parses the mantissa field.
+         * @param mantissa string to parse
+         */
+        void parseMantissa( const std::string& significantStr );
+
+        void setInfinite() {
+            exponent = MAX_EXPONENT;
+            mantissa = 0;
+        }
+
+        void setZero() {
+            exponent = 0;
+            mantissa = 0;
+        }
+
+        /*
+         * Sets the exponent variable to Long::MAX_VALUE or -Long::MAX_VALUE if
+         * overflow or underflow happens.
+         * @param the offset to set
+         */
+        void checkedAddExponent( long long offset );
+
+        void processNormalNumber();
+        void processSubNormalNumber();
+        int countBitsLength( long long value );
+
+        /*
+         * Adjusts the mantissa to desired width for further analysis.
+         */
+        void fitMantissaInDesiredWidth( int desiredWidth );
+
+        /*
+         * Stores the discarded bits to abandonedNumber.
+         */
+        void discardTrailingBits( long long num );
+
+        /*
+         * The value is rounded up or down to the nearest infinitely precise result.
+         * If the value is exactly halfway between two infinitely precise results,
+         * then it should be rounded up to the nearest infinitely precise even.
+         */
+        void round();
+
+        /*
+         * Returns the normalized significand after removing the leading zeros.
+         */
+        std::string getNormalizedSignificand( const std::string& strIntegerPart,
+                                              const std::string& strDecimalPart );
+
+        /*
+         * Calculates the offset between the normalized number and unnormalized
+         * number. In a normalized representation, significand is represented by the
+         * characters "0x1." followed by a lowercase hexadecimal representation of
+         * the rest of the significand as a fraction.
+         */
+        int getOffset( const std::string& strIntegerPart,
+                       const std::string& strDecimalPart );
+
+    public:  // Statics
+
+        /*
+         * Parses the hex string to a double number.
+         * @param hexString - string to parse
+         * @returns the parsed double value
+         */
+        static double parseDouble( const std::string& hexString );
+
+        /*
+         * Parses the hex string to a float number.
+         * @param hexString - string to parse
+         * @returns the parsed float value
+         */
+        static float parseFloat( const std::string& hexString );
+
+
+    private:  // Static
+
+        /*
+         * Analyzes the hex string and extracts the sign and digit segments.
+         * @param hexString - string to parse
+         * @returns array of three strings holding the segments caller owns
+         */
+        static std::string* getSegmentsFromHexString( const std::string& hexString );
+
+        std::string& replaceFirst( std::string& target,
+                                   const std::string& find,
+                                   const std::string& replace ) {
+
+            std::string::size_type pos = std::string::npos;
+
+            if( ( pos = target.find_first_of( find, 0 ) ) != std::string::npos ) {
+                return target.replace( pos, find.length(), replace );
+            }
+
+            return target;
+        }
+
+        std::string& replaceAll( std::string& target,
+                                 const std::string& find,
+                                 const std::string& replace ) {
+
+            std::string::size_type pos = std::string::npos;
+            while( ( pos = target.find( find ) ) != std::string::npos ) {
+                target.replace( pos, find.length(), replace );
+            }
+
+            return target;
+        }
+
+    };
+
+}}}
+
+#endif /*_DECAF_INTERNAL_UTIL_HEXSTRINGPARSER_H_*/

Added: activemq/activemq-cpp/trunk/src/main/decaf/io/BlockingByteArrayInputStream.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/decaf/io/BlockingByteArrayInputStream.cpp?rev=652104&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/decaf/io/BlockingByteArrayInputStream.cpp (added)
+++ activemq/activemq-cpp/trunk/src/main/decaf/io/BlockingByteArrayInputStream.cpp Tue Apr 29 13:52:30 2008
@@ -0,0 +1,169 @@
+/*
+ * 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 "BlockingByteArrayInputStream.h"
+#include <algorithm>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::io;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+BlockingByteArrayInputStream::BlockingByteArrayInputStream(){
+    pos = buffer.end();
+    closing = false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+BlockingByteArrayInputStream::BlockingByteArrayInputStream(
+    const unsigned char* buffer,
+    std::size_t bufferSize ){
+
+    closing = false;
+    setByteArray( buffer, bufferSize );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+BlockingByteArrayInputStream::~BlockingByteArrayInputStream(){
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void BlockingByteArrayInputStream::setByteArray( const unsigned char* lbuffer,
+                                                 std::size_t lbufferSize ){
+    synchronized( this ){
+
+        // Remove old data
+        buffer.clear();
+        buffer.reserve( lbufferSize );
+
+        // Copy data to internal buffer.
+        std::back_insert_iterator< std::vector<unsigned char> > iter( buffer );
+        std::copy( lbuffer, lbuffer + lbufferSize, iter );
+
+        // Begin at the Beginning.
+        pos = this->buffer.begin();
+
+        // Notify any listening threds that there is now data available.
+        notifyAll();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void BlockingByteArrayInputStream::close() throw ( lang::Exception ){
+
+    synchronized( this ){
+
+        // Indicate that we're shutting down.
+        closing = true;
+
+        // Clear out the buffer.
+        buffer.clear();
+
+        // Notify that this stream is shutting down.
+        notifyAll();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+unsigned char BlockingByteArrayInputStream::read() throw ( IOException ){
+
+    try{
+        synchronized( this ){
+
+            while( !closing ){
+
+                if( pos != buffer.end() ){
+                    return *(pos++);
+                }
+
+                // Wait for more data
+                wait();
+            }
+
+            throw IOException( __FILE__, __LINE__, "close occurred during read" );
+        }
+
+        return 0;
+    }
+    DECAF_CATCH_RETHROW( IOException )
+    DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int BlockingByteArrayInputStream::read( unsigned char* buffer,
+                                        std::size_t offset,
+                                        std::size_t bufferSize )
+    throw ( IOException, lang::exceptions::NullPointerException ){
+
+    if( bufferSize == 0 ) {
+        return 0;
+    }
+
+    if( buffer == NULL ) {
+        throw NullPointerException(
+            __FILE__, __LINE__,
+            "BlockingByteArrayInputStream::read - Passed buffer is Null" );
+    }
+
+    synchronized( this ){
+
+        std::size_t ix = 0;
+
+        for( ; ix < bufferSize && !closing; ++ix, ++pos)
+        {
+            if(pos == this->buffer.end())
+            {
+                // Wait for more data to come in.
+                wait();
+            }
+
+            if( !closing ){
+                buffer[ix + offset] = *(pos);
+            }
+        }
+
+        if( closing ){
+            throw IOException(
+                __FILE__, __LINE__,
+                "BlockingByteArrayInputStream::read - close occurred during read" );
+        }
+
+        return (int)ix;
+    }
+
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::size_t BlockingByteArrayInputStream::skip( std::size_t num )
+    throw ( io::IOException, lang::exceptions::UnsupportedOperationException ){
+
+    std::size_t ix = 0;
+
+    synchronized( this ){
+
+        // Increment the pos until we'v skipped the desired num
+        // or we've hit the end of the buffer.
+        for( ; ix < num && !closing && pos != buffer.end(); ++ix, ++pos) {}
+    }
+
+    return ix;
+}
+
+