blob: 7678179287671325405a18ef76668442b542fbac [file] [log] [blame]
/**
* 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 <activemq/wireformat/openwire/utils/BooleanStream.h>
#include <activemq/exceptions/ActiveMQException.h>
using namespace std;
using namespace activemq;
using namespace activemq::exceptions;
using namespace activemq::wireformat;
using namespace activemq::wireformat::openwire;
using namespace activemq::wireformat::openwire::utils;
using namespace decaf::io;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
///////////////////////////////////////////////////////////////////////////////
BooleanStream::BooleanStream() : data(), arrayLimit(0), arrayPos(0), bytePos(0) {
// Reserve 1K
this->data.resize( 1000, 0 );
}
///////////////////////////////////////////////////////////////////////////////
BooleanStream::~BooleanStream() {
}
///////////////////////////////////////////////////////////////////////////////
bool BooleanStream::readBoolean() {
try {
unsigned char b = data[arrayPos];
bool rc = ( ( b >> bytePos ) & 0x01 ) != 0;
bytePos++;
if( bytePos >= 8 ) {
bytePos = 0;
arrayPos++;
}
return rc;
}
AMQ_CATCH_RETHROW( IOException )
AMQ_CATCH_EXCEPTION_CONVERT( Exception, IOException )
AMQ_CATCHALL_THROW( IOException )
}
///////////////////////////////////////////////////////////////////////////////
void BooleanStream::writeBoolean( bool value ) {
try{
if( bytePos == 0 ) {
arrayLimit++;
if( (size_t)arrayLimit >= data.size() ) {
// re-grow the array if necessary
data.resize( data.size() * 2 );
}
}
if( value ) {
data[arrayPos] |= (unsigned char)( 0x01 << bytePos );
}
bytePos++;
// Wrap around when we hit the next byte
if( bytePos >= 8 ) {
bytePos=0;
arrayPos++;
}
}
AMQ_CATCH_RETHROW( IOException )
AMQ_CATCH_EXCEPTION_CONVERT( Exception, IOException )
AMQ_CATCHALL_THROW( IOException )
}
///////////////////////////////////////////////////////////////////////////////
void BooleanStream::marshal( DataOutputStream* dataOut ) {
try {
if( arrayLimit < 64 ) {
dataOut->writeByte( (unsigned char)arrayLimit );
} else if( arrayLimit < 256 ) { // max value of unsigned char
dataOut->writeByte( 0xC0 );
dataOut->writeByte( (unsigned char)arrayLimit );
} else {
dataOut->writeByte( 0x80 );
dataOut->writeShort( arrayLimit );
}
// Dump the payload
dataOut->write( &data[0], (int)data.size(), 0, arrayLimit );
clear();
}
AMQ_CATCH_RETHROW( IOException )
AMQ_CATCH_EXCEPTION_CONVERT( Exception, IOException )
AMQ_CATCHALL_THROW( IOException )
}
///////////////////////////////////////////////////////////////////////////////
void BooleanStream::marshal( std::vector< unsigned char >& dataOut ) {
try{
if( arrayLimit < 64 ) {
dataOut.push_back( ( unsigned char ) arrayLimit );
} else if( arrayLimit < 256 ) { // max value of unsigned byte
dataOut.push_back( ( unsigned char ) 0xC0 );
dataOut.push_back( ( unsigned char ) arrayLimit );
} else {
dataOut.push_back( ( unsigned char ) 0x80 );
dataOut.push_back( ( unsigned char )( arrayLimit >> 8 ) ); // High Byte
dataOut.push_back( ( unsigned char )( arrayLimit & 0xFF ) ); // Low Byte
}
// Insert all data from data into the passed buffer
dataOut.insert( dataOut.end(), &data[0], &data[arrayLimit-1] );
}
AMQ_CATCH_RETHROW( IOException )
AMQ_CATCH_EXCEPTION_CONVERT( Exception, IOException )
AMQ_CATCHALL_THROW( IOException )
}
///////////////////////////////////////////////////////////////////////////////
void BooleanStream::unmarshal( DataInputStream* dataIn ) {
try{
arrayLimit = (short)( dataIn->readByte() & 0xFF );
if ( arrayLimit == 0xC0 ) {
arrayLimit = (short)( dataIn->readByte() & 0xFF );
} else if( arrayLimit == 0x80 ) {
arrayLimit = dataIn->readShort();
}
// Make sure we can accomodate all the data.
data.resize( arrayLimit );
// Make sure we get all the data we are expecting
dataIn->readFully( &data[0], (int)data.size(), 0, arrayLimit );
clear();
}
AMQ_CATCH_RETHROW( IOException )
AMQ_CATCH_EXCEPTION_CONVERT( Exception, IOException )
AMQ_CATCHALL_THROW( IOException )
}
///////////////////////////////////////////////////////////////////////////////
void BooleanStream::clear() {
// Reset the positions
arrayPos = 0;
bytePos = 0;
}
///////////////////////////////////////////////////////////////////////////////
int BooleanStream::marshalledSize() {
if( arrayLimit < 64 ) {
return 1 + arrayLimit;
} else if( arrayLimit < 256 ) {
return 2 + arrayLimit;
} else {
return 3 + arrayLimit;
}
}