blob: f9684cf48a40a9b6e8ad851be3069ea383f5522d [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 "PrimitiveMapMarshaller.h"
#include <activemq/io/ByteArrayInputStream.h>
#include <activemq/io/ByteArrayOutputStream.h>
#include <activemq/io/DataInputStream.h>
#include <activemq/io/DataOutputStream.h>
#include <activemq/connector/openwire/utils/OpenwireStringSupport.h>
using namespace activemq;
using namespace activemq::io;
using namespace activemq::util;
using namespace activemq::exceptions;
using namespace activemq::connector;
using namespace activemq::connector::openwire;
using namespace activemq::connector::openwire::utils;
using namespace activemq::connector::openwire::marshal;
///////////////////////////////////////////////////////////////////////////////
void PrimitiveMapMarshaller::marshal( const util::PrimitiveMap* map,
std::vector<unsigned char>& dest )
throw ( cms::CMSException )
{
try {
ByteArrayOutputStream bytesOut( dest );
DataOutputStream dataOut( &bytesOut );
if( map == NULL ) {
dataOut.writeInt( -1 );
} else {
dataOut.writeInt( (int)map->size() );
std::vector<std::string> keys = map->getKeys();
std::vector<std::string>::const_iterator iter = keys.begin();
for(; iter != keys.end(); ++iter ) {
OpenwireStringSupport::writeString( dataOut, &(*iter) );
PrimitiveMap::ValueNode value = map->getValue( *iter );
marshalPrimitive( dataOut, value );
}
}
}
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
}
///////////////////////////////////////////////////////////////////////////////
PrimitiveMap* PrimitiveMapMarshaller::unmarshal(
const std::vector<unsigned char>& src )
throw ( cms::CMSException )
{
try{
ByteArrayInputStream bytesIn( src );
DataInputStream dataIn( &bytesIn );
int size = dataIn.readInt();
if( size > 0 ) {
PrimitiveMap* map = new PrimitiveMap;
for( int i=0; i < size; i++ ) {
std::string key = OpenwireStringSupport::readString( dataIn );
unmarshalPrimitive( dataIn, key, *map );
}
return map;
}
return NULL;
}
AMQ_CATCH_EXCEPTION_CONVERT( io::IOException, ActiveMQException )
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
}
///////////////////////////////////////////////////////////////////////////////
void PrimitiveMapMarshaller::unmarshal(
util::PrimitiveMap* map,
const std::vector<unsigned char>& src ) throw ( cms::CMSException ) {
try {
if( map == NULL || src.empty() ) {
return;
}
// Clear old data
map->clear();
ByteArrayInputStream bytesIn( src );
DataInputStream dataIn( &bytesIn );
int size = dataIn.readInt();
if( size > 0 ) {
for( int i=0; i < size; i++ ) {
std::string key = OpenwireStringSupport::readString( dataIn );
unmarshalPrimitive( dataIn, key, *map );
}
}
}
AMQ_CATCH_EXCEPTION_CONVERT( io::IOException, ActiveMQException )
AMQ_CATCH_RETHROW( ActiveMQException )
AMQ_CATCHALL_THROW( ActiveMQException )
}
///////////////////////////////////////////////////////////////////////////////
void PrimitiveMapMarshaller::marshalPrimitive( io::DataOutputStream& dataOut,
util::PrimitiveMap::ValueNode& value )
throw ( io::IOException ) {
try {
if( value.getValueType() == PrimitiveMap::BOOLEAN_TYPE )
{
dataOut.writeByte( PrimitiveMap::BOOLEAN_TYPE );
dataOut.writeBoolean( value.getBool() );
}
else if( value.getValueType() == PrimitiveMap::BYTE_TYPE )
{
dataOut.writeByte( PrimitiveMap::BYTE_TYPE );
dataOut.writeByte( value.getByte() );
}
else if( value.getValueType() == PrimitiveMap::CHAR_TYPE )
{
dataOut.writeByte( PrimitiveMap::CHAR_TYPE );
dataOut.writeChar( value.getChar() );
}
else if( value.getValueType() == PrimitiveMap::SHORT_TYPE )
{
dataOut.writeByte( PrimitiveMap::SHORT_TYPE );
dataOut.writeShort( value.getShort() );
}
else if( value.getValueType() == PrimitiveMap::INTEGER_TYPE )
{
dataOut.writeByte( PrimitiveMap::INTEGER_TYPE );
dataOut.writeInt( value.getInt() );
}
else if( value.getValueType() == PrimitiveMap::LONG_TYPE )
{
dataOut.writeByte( PrimitiveMap::LONG_TYPE );
dataOut.writeLong( value.getLong() );
}
else if( value.getValueType() == PrimitiveMap::FLOAT_TYPE )
{
dataOut.writeByte( PrimitiveMap::FLOAT_TYPE );
dataOut.writeFloat( value.getFloat() );
}
else if( value.getValueType() == PrimitiveMap::DOUBLE_TYPE )
{
dataOut.writeByte( PrimitiveMap::DOUBLE_TYPE );
dataOut.writeDouble( value.getDouble() );
}
else if( value.getValueType() == PrimitiveMap::BYTE_ARRAY_TYPE )
{
dataOut.writeByte( PrimitiveMap::BYTE_ARRAY_TYPE );
std::vector<unsigned char> data = value.getByteArray();
dataOut.writeInt( (int)data.size() );
dataOut.write( data );
}
else if( value.getValueType() == PrimitiveMap::STRING_TYPE )
{
std::string data = value.getString();
// is the string big??
if( data.size() > 8191 ) {
dataOut.writeByte( PrimitiveMap::BIG_STRING_TYPE );
} else {
dataOut.writeByte( PrimitiveMap::STRING_TYPE );
}
OpenwireStringSupport::writeString( dataOut, &data );
}
else
{
throw IOException(
__FILE__,
__LINE__,
"Object is not a primitive: ");
}
}
AMQ_CATCH_RETHROW( io::IOException )
AMQ_CATCH_EXCEPTION_CONVERT( ActiveMQException, io::IOException )
AMQ_CATCHALL_THROW( io::IOException )
}
///////////////////////////////////////////////////////////////////////////////
void PrimitiveMapMarshaller::unmarshalPrimitive( io::DataInputStream& dataIn,
const std::string& key,
util::PrimitiveMap& map )
throw ( io::IOException ) {
try {
unsigned char type = dataIn.readByte();
switch( type )
{
case PrimitiveMap::NULL_TYPE:
map.setString( key, "" );
break;
case PrimitiveMap::BYTE_TYPE:
map.setByte( key, dataIn.readByte() );
break;
case PrimitiveMap::BOOLEAN_TYPE:
map.setBool( key, dataIn.readBoolean() );
break;
case PrimitiveMap::CHAR_TYPE:
map.setChar( key, dataIn.readChar() );
break;
case PrimitiveMap::SHORT_TYPE:
map.setShort( key, dataIn.readShort() );
break;
case PrimitiveMap::INTEGER_TYPE:
map.setInt( key, dataIn.readInt() );
break;
case PrimitiveMap::LONG_TYPE:
map.setLong( key, dataIn.readLong() );
break;
case PrimitiveMap::FLOAT_TYPE:
map.setFloat( key, dataIn.readFloat() );
break;
case PrimitiveMap::DOUBLE_TYPE:
map.setDouble( key, dataIn.readDouble() );
break;
case PrimitiveMap::BYTE_ARRAY_TYPE:
{
int size = dataIn.readInt();
std::vector<unsigned char> data;
data.resize( size );
dataIn.readFully( data );
map.setByteArray( key, data );
break;
}
case PrimitiveMap::STRING_TYPE:
case PrimitiveMap::BIG_STRING_TYPE:
map.setString(
key,
OpenwireStringSupport::readString( dataIn ) );
break;
default:
throw IOException(
__FILE__,
__LINE__,
"PrimitiveMapMarshaller::unmarshalPrimitive - "
"Unsupported data type: ");
}
}
AMQ_CATCH_RETHROW( io::IOException )
AMQ_CATCH_EXCEPTION_CONVERT( ActiveMQException, io::IOException )
AMQ_CATCHALL_THROW( io::IOException )
}