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;
+}
+
+