mirror of https://github.com/apache/activemq.git
443 lines
15 KiB
C++
443 lines
15 KiB
C++
/*
|
|
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 "marshal/BaseDataStreamMarshaller.h"
|
|
#include "marshal/BrokerIdMarshaller.h"
|
|
#include "marshal/BrokerInfoMarshaller.h"
|
|
#include "command/AbstractCommand.h"
|
|
|
|
#include "command/BrokerId.h"
|
|
#include "command/BrokerInfo.h"
|
|
#include "command/IDataStructure.h"
|
|
|
|
using namespace ActiveMQ::Marshalling;
|
|
using namespace ActiveMQ::Command;
|
|
using namespace ActiveMQ::IO;
|
|
using std::auto_ptr;
|
|
using boost::shared_ptr;
|
|
|
|
shared_ptr<BrokerError>
|
|
BaseDataStreamMarshaller::unmarshalBrokerError(ProtocolFormat& wireFormat,
|
|
BinaryReader& dataIn,
|
|
BooleanStream& bs) {
|
|
return shared_ptr<BrokerError>();
|
|
}
|
|
|
|
auto_ptr<IDataStructure>
|
|
BaseDataStreamMarshaller::unmarshalCachedObject(ProtocolFormat& wireFormat,
|
|
BinaryReader& dataIn,
|
|
BooleanStream& bs) {
|
|
return unmarshalNestedObject(wireFormat, dataIn, bs);
|
|
}
|
|
|
|
auto_ptr<IDataStructure>
|
|
BaseDataStreamMarshaller::unmarshalNestedObject(ProtocolFormat& wireFormat,
|
|
BinaryReader& dataIn,
|
|
BooleanStream& bs) {
|
|
if (bs.readBoolean()) {
|
|
unsigned char type = dataIn.readByte();
|
|
BaseDataStreamMarshaller *marsh = wireFormat.getMarshaller(type);
|
|
if (marsh == NULL)
|
|
return auto_ptr<IDataStructure>(NULL);
|
|
|
|
auto_ptr<IDataStructure> ret(marsh->createCommand());
|
|
BaseCommand *test = dynamic_cast<BaseCommand*>(ret.get());
|
|
if (test && test->isMarshalAware())
|
|
bs.readBoolean(); // don't care what this is; should always be false since we don't do caching
|
|
marsh->unmarshal(wireFormat,
|
|
*ret,
|
|
dataIn,
|
|
bs);
|
|
return ret;
|
|
}
|
|
else
|
|
return auto_ptr<IDataStructure>(NULL);
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1BrokerError(ProtocolFormat& wireFormat,
|
|
const shared_ptr<const BrokerError>& o,
|
|
BooleanStream& bs) {
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2BrokerError(ProtocolFormat& wireFormat,
|
|
const shared_ptr<const BrokerError>& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1CachedObject(ProtocolFormat& wireFormat,
|
|
const AbstractCommand& o,
|
|
BooleanStream& bs) {
|
|
|
|
return marshal1NestedObject(wireFormat, o, bs);
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2CachedObject(ProtocolFormat& wireFormat,
|
|
const AbstractCommand& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
marshal2NestedObject(wireFormat, o, dataOut, bs);
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1NestedObject(ProtocolFormat& wireFormat,
|
|
const AbstractCommand& o,
|
|
BooleanStream& bs) {
|
|
bs.writeBoolean(true);
|
|
return 1 + wireFormat.getMarshaller(o.getCommandType())->marshal1(wireFormat,
|
|
o,
|
|
bs);
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2NestedObject(ProtocolFormat& wireFormat,
|
|
const AbstractCommand& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
if (bs.readBoolean()) {
|
|
unsigned char type = o.getCommandType();
|
|
dataOut.write(&type, 1);
|
|
|
|
wireFormat.getMarshaller(type)->marshal2(wireFormat,
|
|
o,
|
|
dataOut,
|
|
bs);
|
|
}
|
|
}
|
|
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1CachedObject(ProtocolFormat& wireFormat,
|
|
const shared_ptr<const IDataStructure>& o,
|
|
BooleanStream& bs) {
|
|
|
|
return marshal1NestedObject(wireFormat, o, bs);
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2CachedObject(ProtocolFormat& wireFormat,
|
|
const shared_ptr<const IDataStructure>& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
marshal2NestedObject(wireFormat, o, dataOut, bs);
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1NestedObject(ProtocolFormat& wireFormat,
|
|
const shared_ptr<const IDataStructure>& o,
|
|
BooleanStream& bs) {
|
|
|
|
bs.writeBoolean(o != NULL);
|
|
if (o != NULL) {
|
|
return 1 + wireFormat.getMarshaller(o->getCommandType())->marshal1(wireFormat,
|
|
*o,
|
|
bs);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2NestedObject(ProtocolFormat& wireFormat,
|
|
const shared_ptr<const IDataStructure>& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
if (bs.readBoolean()) {
|
|
unsigned char type = o->getCommandType();
|
|
dataOut.write(&type, 1);
|
|
wireFormat.getMarshaller(type)->marshal2(wireFormat,
|
|
*o,
|
|
dataOut,
|
|
bs);
|
|
}
|
|
}
|
|
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1CachedObject(ProtocolFormat& wireFormat,
|
|
const IDataStructure& o,
|
|
BooleanStream& bs) {
|
|
return marshal1NestedObject(wireFormat, o, bs);
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2CachedObject(ProtocolFormat& wireFormat,
|
|
const IDataStructure& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
marshal2NestedObject(wireFormat, o, dataOut, bs);
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1NestedObject(ProtocolFormat& wireFormat,
|
|
const IDataStructure& o,
|
|
BooleanStream& bs) {
|
|
return marshal1NestedObject(wireFormat, o, bs);
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::marshal2NestedObject(ProtocolFormat& wireFormat,
|
|
const IDataStructure& o,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
marshal2NestedObject(wireFormat, o, dataOut, bs);
|
|
}
|
|
|
|
namespace ActiveMQ {
|
|
namespace Marshalling {
|
|
|
|
template<>
|
|
void
|
|
BaseDataStreamMarshaller::marshal2ObjectArray(ProtocolFormat& wireFormat,
|
|
const vector<shared_ptr<const BrokerId> >& arr,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
if (bs.readBoolean()) {
|
|
dataOut.writeShort(arr.size());
|
|
for (vector<shared_ptr<const BrokerId> >::const_iterator i = arr.begin();
|
|
i != arr.end();
|
|
++i)
|
|
marshal2NestedObject(wireFormat,
|
|
*i,
|
|
dataOut,
|
|
bs);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void
|
|
BaseDataStreamMarshaller::marshal2ObjectArray(ProtocolFormat& wireFormat,
|
|
const vector<shared_ptr<const IDataStructure> >& arr,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
if (bs.readBoolean()) {
|
|
dataOut.writeShort(arr.size());
|
|
for (vector<shared_ptr<const IDataStructure> >::const_iterator i = arr.begin();
|
|
i != arr.end();
|
|
++i)
|
|
marshal2NestedObject(wireFormat,
|
|
*i,
|
|
dataOut,
|
|
bs);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
void
|
|
BaseDataStreamMarshaller::marshal2ObjectArray(ProtocolFormat& wireFormat,
|
|
const vector<shared_ptr<const BrokerInfo> >& arr,
|
|
BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
|
|
if (bs.readBoolean()) {
|
|
dataOut.writeShort(arr.size());
|
|
for (vector<shared_ptr<const BrokerInfo> >::const_iterator i = arr.begin();
|
|
i != arr.end();
|
|
++i)
|
|
marshal2NestedObject(wireFormat,
|
|
*i,
|
|
dataOut,
|
|
bs);
|
|
}
|
|
}
|
|
|
|
template<>
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1ObjectArray(ProtocolFormat& wireFormat,
|
|
const vector<shared_ptr<const BrokerId> >& arr,
|
|
BooleanStream& bs) {
|
|
|
|
unsigned int ret = 0;
|
|
if (!arr.empty()) {
|
|
bs.writeBoolean(true);
|
|
ret += 2;
|
|
|
|
for (vector<shared_ptr<const BrokerId> >::const_iterator i = arr.begin();
|
|
i != arr.end(); ++i) {
|
|
ret += marshal1NestedObject(wireFormat, *i, bs);
|
|
}
|
|
}
|
|
else
|
|
bs.writeBoolean(false);
|
|
|
|
return ret;
|
|
}
|
|
|
|
template<>
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1ObjectArray(ProtocolFormat& wireFormat,
|
|
const vector<shared_ptr<const IDataStructure> >& arr,
|
|
BooleanStream& bs) {
|
|
|
|
return 0;
|
|
}
|
|
|
|
template<>
|
|
size_t
|
|
BaseDataStreamMarshaller::marshal1ObjectArray(ProtocolFormat& wireFormat,
|
|
const vector<shared_ptr<const BrokerInfo> >& arr,
|
|
BooleanStream& bs) {
|
|
|
|
|
|
unsigned int ret = 0;
|
|
if (!arr.empty()) {
|
|
bs.writeBoolean(true);
|
|
ret += 2;
|
|
|
|
for (vector<shared_ptr<const BrokerInfo> >::const_iterator i = arr.begin();
|
|
i != arr.end(); ++i) {
|
|
ret += marshal1NestedObject(wireFormat, *(*i), bs);
|
|
}
|
|
}
|
|
else
|
|
bs.writeBoolean(false);
|
|
|
|
return ret;
|
|
}
|
|
|
|
};
|
|
};
|
|
|
|
int64_t
|
|
BaseDataStreamMarshaller::unmarshalLong(ProtocolFormat& wireFormat, BinaryReader& dataIn, BooleanStream& bs) {
|
|
if (bs.readBoolean()) {
|
|
if (bs.readBoolean()) {
|
|
return dataIn.readLong();
|
|
}
|
|
else {
|
|
return (int64_t)dataIn.readInt();
|
|
}
|
|
}
|
|
else {
|
|
if (bs.readBoolean()) {
|
|
return (int64_t)dataIn.readShort();
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::writeLong1(int64_t o, BooleanStream& bs) {
|
|
if( o == 0 ) {
|
|
bs.writeBoolean(false);
|
|
bs.writeBoolean(false);
|
|
return 0;
|
|
} else if ( (o & 0xFFFFFFFFFFFF0000LL ) == 0 ) {
|
|
bs.writeBoolean(false);
|
|
bs.writeBoolean(true);
|
|
return 2;
|
|
} else if ( (o & 0xFFFFFFFF00000000LL ) == 0) {
|
|
bs.writeBoolean(true);
|
|
bs.writeBoolean(false);
|
|
return 4;
|
|
} else {
|
|
bs.writeBoolean(true);
|
|
bs.writeBoolean(true);
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::writeLong2(int64_t o, BinaryWriter& dataOut, BooleanStream& bs) {
|
|
if( bs.readBoolean() ) {
|
|
if( bs.readBoolean() ) {
|
|
dataOut.writeLong(o);
|
|
} else {
|
|
dataOut.writeInt((int) o);
|
|
}
|
|
} else {
|
|
if( bs.readBoolean() ) {
|
|
dataOut.writeShort((int) o);
|
|
}
|
|
}
|
|
}
|
|
|
|
size_t
|
|
BaseDataStreamMarshaller::writeString1(const std::string& str, BooleanStream& bs) {
|
|
size_t rc = 0;
|
|
|
|
if (!str.empty()) {
|
|
bs.writeBoolean(true);
|
|
rc += 2;
|
|
rc += str.length();
|
|
bs.writeBoolean(true);
|
|
}
|
|
else
|
|
bs.writeBoolean(false);
|
|
return rc;
|
|
}
|
|
|
|
void
|
|
BaseDataStreamMarshaller::writeString2(const std::string& str, BinaryWriter& dataOut,
|
|
BooleanStream& bs) {
|
|
if (bs.readBoolean()) {
|
|
if (bs.readBoolean()) {
|
|
dataOut.writeString(str);
|
|
}
|
|
}
|
|
}
|
|
|
|
vector<uint8_t>
|
|
BaseDataStreamMarshaller::unmarshalConstByteSequence(ProtocolFormat& wf,
|
|
BinaryReader& dataIn,
|
|
BooleanStream& bs,
|
|
size_t num) {
|
|
vector<uint8_t> ret;
|
|
ret.resize(num);
|
|
dataIn.read(&(ret[0]), num);
|
|
return ret;
|
|
}
|
|
|
|
vector<uint8_t>
|
|
BaseDataStreamMarshaller::unmarshalByteSequence(ProtocolFormat& wf,
|
|
BinaryReader& dataIn,
|
|
BooleanStream& bs) {
|
|
vector<uint8_t> ret;
|
|
if (bs.readBoolean()) {
|
|
int size = dataIn.readInt();
|
|
ret.resize(size);
|
|
dataIn.read(&(ret[0]), size);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
std::string
|
|
BaseDataStreamMarshaller::unmarshalString(ProtocolFormat& wireFormat,
|
|
ActiveMQ::IO::BinaryReader& dataIn,
|
|
ActiveMQ::IO::BooleanStream& bs) {
|
|
if (bs.readBoolean()) {
|
|
bs.readBoolean(); // don't care about UTFness for now
|
|
return dataIn.readString();
|
|
}
|
|
else
|
|
return "";
|
|
}
|