diff options
| author | Gordon Sim <gsim@apache.org> | 2009-08-25 17:57:34 +0000 |
|---|---|---|
| committer | Gordon Sim <gsim@apache.org> | 2009-08-25 17:57:34 +0000 |
| commit | 082fa377137d1a73382a0c3f1ab22b5abe6cb485 (patch) | |
| tree | 27375051e0f05a91ff63f123b2b027916840221c /cpp/src/qpid/messaging | |
| parent | 28e1de98b115ebc834a1e232bfd630809689a59e (diff) | |
| download | qpid-python-082fa377137d1a73382a0c3f1ab22b5abe6cb485.tar.gz | |
QPID-664: Initial checkin of high level messaging api for c++
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@807731 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/messaging')
| -rw-r--r-- | cpp/src/qpid/messaging/Address.cpp | 49 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Connection.cpp | 90 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/ConnectionImpl.h | 45 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Filter.cpp | 39 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Message.cpp | 325 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Receiver.cpp | 51 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/ReceiverImpl.h | 52 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Sender.cpp | 44 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/SenderImpl.h | 44 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Session.cpp | 117 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/SessionImpl.h | 65 | ||||
| -rw-r--r-- | cpp/src/qpid/messaging/Variant.cpp | 603 |
12 files changed, 1524 insertions, 0 deletions
diff --git a/cpp/src/qpid/messaging/Address.cpp b/cpp/src/qpid/messaging/Address.cpp new file mode 100644 index 0000000000..ed35054a00 --- /dev/null +++ b/cpp/src/qpid/messaging/Address.cpp @@ -0,0 +1,49 @@ +/* + * + * 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 "qpid/messaging/Address.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +Address::Address() {} +Address::Address(const std::string& address) : value(address) {} +Address::Address(const std::string& address, const std::string& t) : value(address), type(t) {} +Address::operator const std::string&() const { return value; } +const std::string& Address::toStr() const { return value; } +Address::operator bool() const { return !value.empty(); } +bool Address::operator !() const { return value.empty(); } + +const std::string TYPE_SEPARATOR(":"); + +std::ostream& operator<<(std::ostream& out, const Address& address) +{ + if (!address.type.empty()) { + out << address.type; + out << TYPE_SEPARATOR; + } + out << address.value; + return out; +} + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/Connection.cpp b/cpp/src/qpid/messaging/Connection.cpp new file mode 100644 index 0000000000..feb6566008 --- /dev/null +++ b/cpp/src/qpid/messaging/Connection.cpp @@ -0,0 +1,90 @@ +/* + * + * 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 "qpid/messaging/Connection.h" +#include "qpid/messaging/ConnectionImpl.h" +#include "qpid/messaging/Session.h" +#include "qpid/messaging/SessionImpl.h" +#include "qpid/client/PrivateImplRef.h" +#include "qpid/client/amqp0_10/ConnectionImpl.h" +#include "qpid/log/Statement.h" + +namespace qpid { +namespace client { + +typedef PrivateImplRef<qpid::messaging::Connection> PI; + +} + +namespace messaging { + +using qpid::client::PI; + +Connection Connection::open(const std::string& url, const Variant::Map& options) +{ + //only support amqp 0-10 at present + Connection connection(new qpid::client::amqp0_10::ConnectionImpl(url, options)); + return connection; +} + +Connection::Connection(ConnectionImpl* impl) { PI::ctor(*this, impl); } +Connection::Connection(const Connection& c) : qpid::client::Handle<ConnectionImpl>() { PI::copy(*this, c); } +Connection& Connection::operator=(const Connection& c) { return PI::assign(*this, c); } +Connection::~Connection() { PI::dtor(*this); } + +void Connection::close() { impl->close(); } +Session Connection::newSession() { return impl->newSession(); } + +InvalidOptionString::InvalidOptionString(const std::string& msg) : Exception(msg) {} + +void parseKeyValuePair(const std::string& in, Variant::Map& out) +{ + std::string::size_type i = in.find('='); + if (i == std::string::npos || i == in.size() || in.find('=', i+1) != std::string::npos) { + throw InvalidOptionString(QPID_MSG("Cannot parse name-value pair from " << in)); + } else { + out[in.substr(0, i)] = in.substr(i+1); + } +} + +void parseOptionString(const std::string& in, Variant::Map& out) +{ + std::string::size_type start = 0; + std::string::size_type i = in.find('&'); + while (i != std::string::npos) { + parseKeyValuePair(in.substr(start, i-start), out); + if (i < in.size()) { + start = i+1; + i = in.find('&', start); + } else { + i = std::string::npos; + } + } + parseKeyValuePair(in.substr(start), out); +} + +Variant::Map parseOptionString(const std::string& in) +{ + Variant::Map map; + parseOptionString(in, map); + return map; +} + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/ConnectionImpl.h b/cpp/src/qpid/messaging/ConnectionImpl.h new file mode 100644 index 0000000000..aa9e5b5fbe --- /dev/null +++ b/cpp/src/qpid/messaging/ConnectionImpl.h @@ -0,0 +1,45 @@ +#ifndef QPID_MESSAGING_CONNECTIONIMPL_H +#define QPID_MESSAGING_CONNECTIONIMPL_H + +/* + * + * 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 <string> +#include "qpid/RefCounted.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +class Session; + +class ConnectionImpl : public virtual qpid::RefCounted +{ + public: + virtual ~ConnectionImpl() {} + virtual void close() = 0; + virtual Session newSession() = 0; + private: +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_CONNECTIONIMPL_H*/ diff --git a/cpp/src/qpid/messaging/Filter.cpp b/cpp/src/qpid/messaging/Filter.cpp new file mode 100644 index 0000000000..b06cbdb373 --- /dev/null +++ b/cpp/src/qpid/messaging/Filter.cpp @@ -0,0 +1,39 @@ +/* + * + * 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 "qpid/messaging/Filter.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +Filter::Filter(std::string t, std::string pattern) : type(t) { patterns.push_back(pattern); } +Filter::Filter(std::string t, std::string pattern1, std::string pattern2) : type(t) +{ + patterns.push_back(pattern1); + patterns.push_back(pattern2); +} + +const std::string Filter::WILDCARD("WILDCARD"); +const std::string Filter::EXACT_MATCH("EXACT_MATCH"); + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/Message.cpp b/cpp/src/qpid/messaging/Message.cpp new file mode 100644 index 0000000000..e95a05db17 --- /dev/null +++ b/cpp/src/qpid/messaging/Message.cpp @@ -0,0 +1,325 @@ +/* + * + * 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 "qpid/messaging/Message.h" +#include "qpid/messaging/Address.h" +#include "qpid/messaging/Codec.h" +#include "qpid/messaging/MessageContent.h" +#include "qpid/messaging/Variant.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +namespace { +const std::string EMPTY_STRING = ""; +} + +struct MessageImpl : MessageContent +{ + Address replyTo; + std::string subject; + std::string contentType; + VariantMap headers; + + std::string bytes; + Variant content;//used only for LIST and MAP + VariantType type;//if LIST, MAP content holds the value; if VOID bytes holds the value + + void* internalId; + + MessageImpl(const std::string& c); + MessageImpl(const char* chars, size_t count); + + void setReplyTo(const Address& d); + const Address& getReplyTo() const; + + void setSubject(const std::string& s); + const std::string& getSubject() const; + + void setContentType(const std::string& s); + const std::string& getContentType() const; + + const VariantMap& getHeaders() const; + VariantMap& getHeaders(); + + void setBytes(const std::string& bytes); + void setBytes(const char* chars, size_t count); + const std::string& getBytes() const; + std::string& getBytes(); + + void setInternalId(void*); + void* getInternalId(); + + bool isVoid() const; + + const std::string& asString() const; + std::string& asString(); + + const char* asChars() const; + size_t size() const; + + const Variant::Map& asMap() const; + Variant::Map& asMap(); + bool isMap() const; + + const Variant::List& asList() const; + Variant::List& asList(); + bool isList() const; + + void clear(); + + void encode(Codec& codec); + void decode(Codec& codec); + + Variant& operator[](const std::string&); + + std::ostream& print(std::ostream& out) const; + + //operator<< for variety of types... + MessageContent& operator<<(const std::string&); + MessageContent& operator<<(const char*); + MessageContent& operator<<(bool); + MessageContent& operator<<(int8_t); + MessageContent& operator<<(int16_t); + MessageContent& operator<<(int32_t); + MessageContent& operator<<(int64_t); + MessageContent& operator<<(uint8_t); + MessageContent& operator<<(uint16_t); + MessageContent& operator<<(uint32_t); + MessageContent& operator<<(uint64_t); + MessageContent& operator<<(double); + MessageContent& operator<<(float); + + //assignment from string, map and list + MessageContent& operator=(const std::string&); + MessageContent& operator=(const char*); + MessageContent& operator=(const Variant::Map&); + MessageContent& operator=(const Variant::List&); + + template <class T> MessageContent& append(T& t); +}; + +MessageImpl::MessageImpl(const std::string& c) : bytes(c), type(VOID), internalId(0) {} +MessageImpl::MessageImpl(const char* chars, size_t count) : bytes(chars, count), type(VOID), internalId(0) {} + +void MessageImpl::setReplyTo(const Address& d) { replyTo = d; } +const Address& MessageImpl::getReplyTo() const { return replyTo; } + +void MessageImpl::setSubject(const std::string& s) { subject = s; } +const std::string& MessageImpl::getSubject() const { return subject; } + +void MessageImpl::setContentType(const std::string& s) { contentType = s; } +const std::string& MessageImpl::getContentType() const { return contentType; } + +const VariantMap& MessageImpl::getHeaders() const { return headers; } +VariantMap& MessageImpl::getHeaders() { return headers; } + +//should these methods be on MessageContent? +void MessageImpl::setBytes(const std::string& c) { clear(); bytes = c; } +void MessageImpl::setBytes(const char* chars, size_t count) { clear(); bytes.assign(chars, count); } +const std::string& MessageImpl::getBytes() const { return bytes; } +std::string& MessageImpl::getBytes() { return bytes; } + + +Variant& MessageImpl::operator[](const std::string& key) { return asMap()[key]; } + +std::ostream& MessageImpl::print(std::ostream& out) const +{ + if (type == MAP) { + return out << content.asMap(); + } else if (type == LIST) { + return out << content.asList(); + } else { + return out << bytes; + } +} + +template <class T> MessageContent& MessageImpl::append(T& t) +{ + if (type == VOID) { + //TODO: this is inefficient, probably want to hold on to the stream object + std::stringstream s; + s << bytes; + s << t; + bytes = s.str(); + } else if (type == LIST) { + content.asList().push_back(Variant(t)); + } else { + throw InvalidConversion("<< operator only valid on strings and lists"); + } + return *this; +} + +MessageContent& MessageImpl::operator<<(const std::string& v) { return append(v); } +MessageContent& MessageImpl::operator<<(const char* v) { return append(v); } +MessageContent& MessageImpl::operator<<(bool v) { return append(v); } +MessageContent& MessageImpl::operator<<(int8_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(int16_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(int32_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(int64_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(uint8_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(uint16_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(uint32_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(uint64_t v) { return append(v); } +MessageContent& MessageImpl::operator<<(double v) { return append(v); } +MessageContent& MessageImpl::operator<<(float v) { return append(v); } +MessageContent& MessageImpl::operator=(const std::string& s) +{ + type = VOID; + bytes = s; + return *this; +} +MessageContent& MessageImpl::operator=(const char* c) +{ + type = VOID; + bytes = c; + return *this; +} +MessageContent& MessageImpl::operator=(const Variant::Map& m) +{ + type = MAP; + content = m; + return *this; +} + +MessageContent& MessageImpl::operator=(const Variant::List& l) +{ + type = LIST; + content = l; + return *this; +} + +void MessageImpl::encode(Codec& codec) +{ + if (content.getType() != VOID) { + bytes = EMPTY_STRING; + codec.encode(content, bytes); + } +} + +void MessageImpl::decode(Codec& codec) +{ + codec.decode(bytes, content); + if (content.getType() == MAP) type = MAP; + else if (content.getType() == LIST) type = LIST; + else type = VOID;//TODO: what if codec set some type other than map or list?? +} + +void MessageImpl::setInternalId(void* i) { internalId = i; } +void* MessageImpl::getInternalId() { return internalId; } + +bool MessageImpl::isVoid() const { return type == VOID; } + +const std::string& MessageImpl::asString() const +{ + if (isVoid()) return getBytes(); + else return content.getString();//will throw an error +} +std::string& MessageImpl::asString() +{ + if (isVoid()) return getBytes(); + else return content.getString();//will throw an error +} + +const char* MessageImpl::asChars() const +{ + if (!isVoid()) throw InvalidConversion("Content is of structured type."); + return bytes.data(); +} +size_t MessageImpl::size() const +{ + return bytes.size(); +} + +const Variant::Map& MessageImpl::asMap() const { return content.asMap(); } +Variant::Map& MessageImpl::asMap() +{ + if (isVoid()) { + content = Variant::Map(); + type = MAP; + } + return content.asMap(); +} +bool MessageImpl::isMap() const { return type == MAP; } + +const Variant::List& MessageImpl::asList() const { return content.asList(); } +Variant::List& MessageImpl::asList() +{ + if (isVoid()) { + content = Variant::List(); + type = LIST; + } + return content.asList(); +} +bool MessageImpl::isList() const { return type == LIST; } + +void MessageImpl::clear() { bytes = EMPTY_STRING; content.reset(); type = VOID; } + + +Message::Message(const std::string& bytes) : impl(new MessageImpl(bytes)) {} +Message::Message(const char* bytes, size_t count) : impl(new MessageImpl(bytes, count)) {} + +Message::Message(const Message& m) : impl(new MessageImpl(m.getBytes())) {} +Message::~Message() { delete impl; } + +Message& Message::operator=(const Message& m) { *impl = *m.impl; return *this; } + +void Message::setReplyTo(const Address& d) { impl->setReplyTo(d); } +const Address& Message::getReplyTo() const { return impl->getReplyTo(); } + +void Message::setSubject(const std::string& s) { impl->setSubject(s); } +const std::string& Message::getSubject() const { return impl->getSubject(); } + +void Message::setContentType(const std::string& s) { impl->setContentType(s); } +const std::string& Message::getContentType() const { return impl->getContentType(); } + +const VariantMap& Message::getHeaders() const { return impl->getHeaders(); } +VariantMap& Message::getHeaders() { return impl->getHeaders(); } + +void Message::setBytes(const std::string& c) { impl->setBytes(c); } +void Message::setBytes(const char* chars, size_t count) { impl->setBytes(chars, count); } +const std::string& Message::getBytes() const { return impl->getBytes(); } +std::string& Message::getBytes() { return impl->getBytes(); } + +const char* Message::getRawContent() const { return impl->getBytes().data(); } +size_t Message::getContentSize() const { return impl->getBytes().size(); } + +MessageContent& Message::getContent() { return *impl; } +const MessageContent& Message::getContent() const { return *impl; } +void Message::setContent(const std::string& s) { *impl = s; } +void Message::setContent(const Variant::Map& m) { *impl = m; } +void Message::setContent(const Variant::List& l) { *impl = l; } + +void Message::encode(Codec& codec) { impl->encode(codec); } + +void Message::decode(Codec& codec) { impl->decode(codec); } + +void Message::setInternalId(void* i) { impl->setInternalId(i); } +void* Message::getInternalId() { return impl->getInternalId(); } + +std::ostream& operator<<(std::ostream& out, const MessageContent& content) +{ + return content.print(out); +} + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/Receiver.cpp b/cpp/src/qpid/messaging/Receiver.cpp new file mode 100644 index 0000000000..2e8b89d27f --- /dev/null +++ b/cpp/src/qpid/messaging/Receiver.cpp @@ -0,0 +1,51 @@ +/* + * + * 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 "qpid/messaging/Receiver.h" +#include "qpid/messaging/Message.h" +#include "qpid/messaging/ReceiverImpl.h" +#include "qpid/client/PrivateImplRef.h" + +namespace qpid { +namespace client { + +typedef PrivateImplRef<qpid::messaging::Receiver> PI; + +} + +namespace messaging { + +using qpid::client::PI; + +Receiver::Receiver(ReceiverImpl* impl) { PI::ctor(*this, impl); } +Receiver::Receiver(const Receiver& s) : qpid::client::Handle<ReceiverImpl>() { PI::copy(*this, s); } +Receiver::~Receiver() { PI::dtor(*this); } +Receiver& Receiver::operator=(const Receiver& s) { return PI::assign(*this, s); } +bool Receiver::get(Message& message, qpid::sys::Duration timeout) { return impl->get(message, timeout); } +Message Receiver::get(qpid::sys::Duration timeout) { return impl->get(timeout); } +bool Receiver::fetch(Message& message, qpid::sys::Duration timeout) { return impl->fetch(message, timeout); } +Message Receiver::fetch(qpid::sys::Duration timeout) { return impl->fetch(timeout); } +void Receiver::start() { impl->start(); } +void Receiver::stop() { impl->stop(); } +void Receiver::setCapacity(uint32_t c) { impl->setCapacity(c); } +void Receiver::cancel() { impl->cancel(); } +void Receiver::setListener(MessageListener* listener) { impl->setListener(listener); } + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/ReceiverImpl.h b/cpp/src/qpid/messaging/ReceiverImpl.h new file mode 100644 index 0000000000..77697b730c --- /dev/null +++ b/cpp/src/qpid/messaging/ReceiverImpl.h @@ -0,0 +1,52 @@ +#ifndef QPID_MESSAGING_RECEIVERIMPL_H +#define QPID_MESSAGING_RECEIVERIMPL_H + +/* + * + * 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 "qpid/RefCounted.h" +#include "qpid/sys/Time.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +class Message; +class MessageListener; + +class ReceiverImpl : public virtual qpid::RefCounted +{ + public: + virtual ~ReceiverImpl() {} + virtual bool get(Message& message, qpid::sys::Duration timeout) = 0; + virtual Message get(qpid::sys::Duration timeout) = 0; + virtual bool fetch(Message& message, qpid::sys::Duration timeout) = 0; + virtual Message fetch(qpid::sys::Duration timeout) = 0; + virtual void start() = 0; + virtual void stop() = 0; + virtual void setCapacity(uint32_t) = 0; + virtual void cancel() = 0; + virtual void setListener(MessageListener*) = 0; +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_RECEIVERIMPL_H*/ diff --git a/cpp/src/qpid/messaging/Sender.cpp b/cpp/src/qpid/messaging/Sender.cpp new file mode 100644 index 0000000000..12a3a8eb0f --- /dev/null +++ b/cpp/src/qpid/messaging/Sender.cpp @@ -0,0 +1,44 @@ +/* + * + * 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 "qpid/messaging/Sender.h" +#include "qpid/messaging/Message.h" +#include "qpid/messaging/SenderImpl.h" +#include "qpid/client/PrivateImplRef.h" + +namespace qpid { +namespace client { + +typedef PrivateImplRef<qpid::messaging::Sender> PI; + +} + +namespace messaging { + +using qpid::client::PI; + +Sender::Sender(SenderImpl* impl) { PI::ctor(*this, impl); } +Sender::Sender(const Sender& s) : qpid::client::Handle<SenderImpl>() { PI::copy(*this, s); } +Sender::~Sender() { PI::dtor(*this); } +Sender& Sender::operator=(const Sender& s) { return PI::assign(*this, s); } +void Sender::send(Message& message) { impl->send(message); } +void Sender::cancel() { impl->cancel(); } + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/SenderImpl.h b/cpp/src/qpid/messaging/SenderImpl.h new file mode 100644 index 0000000000..3b61a37423 --- /dev/null +++ b/cpp/src/qpid/messaging/SenderImpl.h @@ -0,0 +1,44 @@ +#ifndef QPID_MESSAGING_SENDERIMPL_H +#define QPID_MESSAGING_SENDERIMPL_H + +/* + * + * 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 "qpid/RefCounted.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +class Message; + +class SenderImpl : public virtual qpid::RefCounted +{ + public: + virtual ~SenderImpl() {} + virtual void send(Message& message) = 0; + virtual void cancel() = 0; + private: +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_SENDERIMPL_H*/ diff --git a/cpp/src/qpid/messaging/Session.cpp b/cpp/src/qpid/messaging/Session.cpp new file mode 100644 index 0000000000..284b20dacc --- /dev/null +++ b/cpp/src/qpid/messaging/Session.cpp @@ -0,0 +1,117 @@ +/* + * + * 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 "qpid/messaging/Session.h" +#include "qpid/messaging/Address.h" +#include "qpid/messaging/Filter.h" +#include "qpid/messaging/Message.h" +#include "qpid/messaging/Sender.h" +#include "qpid/messaging/Receiver.h" +#include "qpid/messaging/SessionImpl.h" +#include "qpid/client/PrivateImplRef.h" + +namespace qpid { +namespace client { + +typedef PrivateImplRef<qpid::messaging::Session> PI; + +} + +namespace messaging { + +using qpid::client::PI; + +Session::Session(SessionImpl* impl) { PI::ctor(*this, impl); } +Session::Session(const Session& s) : qpid::client::Handle<SessionImpl>() { PI::copy(*this, s); } +Session::~Session() { PI::dtor(*this); } +Session& Session::operator=(const Session& s) { return PI::assign(*this, s); } +void Session::commit() { impl->commit(); } +void Session::rollback() { impl->rollback(); } +void Session::acknowledge() { impl->acknowledge(); } +void Session::reject(Message& m) { impl->reject(m); } +void Session::close() { impl->close(); } + +Sender Session::createSender(const Address& address, const VariantMap& options) +{ + return impl->createSender(address, options); +} +Receiver Session::createReceiver(const Address& address, const VariantMap& options) +{ + return impl->createReceiver(address, options); +} +Receiver Session::createReceiver(const Address& address, const Filter& filter, const VariantMap& options) +{ + return impl->createReceiver(address, filter, options); +} + +Sender Session::createSender(const std::string& address, const VariantMap& options) +{ + return impl->createSender(Address(address), options); +} +Receiver Session::createReceiver(const std::string& address, const VariantMap& options) +{ + return impl->createReceiver(Address(address), options); +} +Receiver Session::createReceiver(const std::string& address, const Filter& filter, const VariantMap& options) +{ + return impl->createReceiver(Address(address), filter, options); +} + +Address Session::createTempQueue(const std::string& baseName) +{ + return impl->createTempQueue(baseName); +} + +void Session::sync() +{ + impl->sync(); +} + +void Session::flush() +{ + impl->flush(); +} + +bool Session::fetch(Message& message, qpid::sys::Duration timeout) +{ + return impl->fetch(message, timeout); +} + +Message Session::fetch(qpid::sys::Duration timeout) +{ + return impl->fetch(timeout); +} + +bool Session::dispatch(qpid::sys::Duration timeout) +{ + return impl->dispatch(timeout); +} + +void* Session::getLastConfirmedSent() +{ + return impl->getLastConfirmedSent(); +} + +void* Session::getLastConfirmedAcknowledged() +{ + return impl->getLastConfirmedAcknowledged(); +} + +}} // namespace qpid::messaging diff --git a/cpp/src/qpid/messaging/SessionImpl.h b/cpp/src/qpid/messaging/SessionImpl.h new file mode 100644 index 0000000000..7a7ce731f8 --- /dev/null +++ b/cpp/src/qpid/messaging/SessionImpl.h @@ -0,0 +1,65 @@ +#ifndef QPID_MESSAGING_SESSIONIMPL_H +#define QPID_MESSAGING_SESSIONIMPL_H + +/* + * + * 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 "qpid/RefCounted.h" +#include <string> +#include "qpid/messaging/Variant.h" +#include "qpid/sys/Time.h" + +namespace qpid { +namespace client { +} + +namespace messaging { + +class Address; +class Filter; +class Message; +class Sender; +class Receiver; + +class SessionImpl : public virtual qpid::RefCounted +{ + public: + virtual ~SessionImpl() {} + virtual void commit() = 0; + virtual void rollback() = 0; + virtual void acknowledge() = 0; + virtual void reject(Message&) = 0; + virtual void close() = 0; + virtual void sync() = 0; + virtual void flush() = 0; + virtual bool fetch(Message& message, qpid::sys::Duration timeout) = 0; + virtual Message fetch(qpid::sys::Duration timeout) = 0; + virtual bool dispatch(qpid::sys::Duration timeout) = 0; + virtual Address createTempQueue(const std::string& baseName) = 0; + virtual Sender createSender(const Address& address, const VariantMap& options) = 0; + virtual Receiver createReceiver(const Address& address, const VariantMap& options) = 0; + virtual Receiver createReceiver(const Address& address, const Filter& filter, const VariantMap& options) = 0; + virtual void* getLastConfirmedSent() = 0; + virtual void* getLastConfirmedAcknowledged() = 0; + private: +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_SESSIONIMPL_H*/ diff --git a/cpp/src/qpid/messaging/Variant.cpp b/cpp/src/qpid/messaging/Variant.cpp new file mode 100644 index 0000000000..59770939e1 --- /dev/null +++ b/cpp/src/qpid/messaging/Variant.cpp @@ -0,0 +1,603 @@ +/* + * + * 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 "qpid/messaging/Variant.h" +#include <boost/format.hpp> +#include <boost/lexical_cast.hpp> + +namespace qpid { +namespace client { +} + +namespace messaging { + +InvalidConversion::InvalidConversion(const std::string& msg) : Exception(msg) {} + + +namespace { +std::string EMPTY; +} + +class VariantImpl +{ + public: + VariantImpl(); + VariantImpl(bool); + VariantImpl(uint8_t); + VariantImpl(uint16_t); + VariantImpl(uint32_t); + VariantImpl(uint64_t); + VariantImpl(int8_t); + VariantImpl(int16_t); + VariantImpl(int32_t); + VariantImpl(int64_t); + VariantImpl(float); + VariantImpl(double); + VariantImpl(const std::string&); + VariantImpl(const Variant::Map&); + VariantImpl(const Variant::List&); + ~VariantImpl(); + + VariantType getType() const; + + bool asBool() const; + uint8_t asUint8() const; + uint16_t asUint16() const; + uint32_t asUint32() const; + uint64_t asUint64() const; + int8_t asInt8() const; + int16_t asInt16() const; + int32_t asInt32() const; + int64_t asInt64() const; + float asFloat() const; + double asDouble() const; + std::string asString() const; + + const Variant::Map& asMap() const; + Variant::Map& asMap(); + const Variant::List& asList() const; + Variant::List& asList(); + + const std::string& getString() const; + std::string& getString(); + + void setEncoding(const std::string&); + const std::string& getEncoding() const; + + static VariantImpl* create(const Variant&); + private: + const VariantType type; + union { + bool b; + uint8_t ui8; + uint16_t ui16; + uint32_t ui32; + uint64_t ui64; + int8_t i8; + int16_t i16; + int32_t i32; + int64_t i64; + float f; + double d; + void* v;//variable width data + } value; + std::string encoding;//optional encoding for variable length data + + std::string getTypeName(VariantType type) const; + template<class T> T convertFromString() const + { + std::string* s = reinterpret_cast<std::string*>(value.v); + try { + return boost::lexical_cast<T>(*s); + } catch(const boost::bad_lexical_cast&) { + throw InvalidConversion(QPID_MSG("Cannot convert " << *s)); + } + } +}; + + +VariantImpl::VariantImpl() : type(VOID) { value.i64 = 0; } +VariantImpl::VariantImpl(bool b) : type(BOOL) { value.b = b; } +VariantImpl::VariantImpl(uint8_t i) : type(UINT8) { value.ui8 = i; } +VariantImpl::VariantImpl(uint16_t i) : type(UINT16) { value.ui16 = i; } +VariantImpl::VariantImpl(uint32_t i) : type(UINT32) { value.ui32 = i; } +VariantImpl::VariantImpl(uint64_t i) : type(UINT64) { value.ui64 = i; } +VariantImpl::VariantImpl(int8_t i) : type(INT8) { value.i8 = i; } +VariantImpl::VariantImpl(int16_t i) : type(INT16) { value.i16 = i; } +VariantImpl::VariantImpl(int32_t i) : type(INT32) { value.i32 = i; } +VariantImpl::VariantImpl(int64_t i) : type(INT64) { value.i64 = i; } +VariantImpl::VariantImpl(float f) : type(FLOAT) { value.f = f; } +VariantImpl::VariantImpl(double d) : type(DOUBLE) { value.d = d; } +VariantImpl::VariantImpl(const std::string& s) : type(STRING) { value.v = new std::string(s); } +VariantImpl::VariantImpl(const Variant::Map& m) : type(MAP) { value.v = new Variant::Map(m); } +VariantImpl::VariantImpl(const Variant::List& l) : type(LIST) { value.v = new Variant::List(l); } + +VariantImpl::~VariantImpl() { + switch (type) { + case STRING: + delete reinterpret_cast<std::string*>(value.v); + break; + case MAP: + delete reinterpret_cast<Variant::Map*>(value.v); + break; + case LIST: + delete reinterpret_cast<Variant::List*>(value.v); + break; + default: + break; + } +} + +VariantType VariantImpl::getType() const { return type; } + +namespace { + +bool same_char(char a, char b) +{ + return toupper(a) == toupper(b); +} + +bool caseInsensitiveMatch(const std::string& a, const std::string& b) +{ + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin(), &same_char); +} + +const std::string TRUE("True"); +const std::string FALSE("False"); + +bool toBool(const std::string& s) +{ + if (caseInsensitiveMatch(s, TRUE)) return true; + if (caseInsensitiveMatch(s, FALSE)) return false; + try { return boost::lexical_cast<int>(s); } catch(const boost::bad_lexical_cast&) {} + throw InvalidConversion(QPID_MSG("Cannot convert " << s << " to bool")); +} + +} + +bool VariantImpl::asBool() const +{ + switch(type) { + case VOID: return false; + case BOOL: return value.b; + case UINT8: return value.ui8; + case UINT16: return value.ui16; + case UINT32: return value.ui32; + case UINT64: return value.ui64; + case INT8: return value.i8; + case INT16: return value.i16; + case INT32: return value.i32; + case INT64: return value.i64; + case STRING: return toBool(*reinterpret_cast<std::string*>(value.v)); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(BOOL))); + } +} +uint8_t VariantImpl::asUint8() const +{ + switch(type) { + case UINT8: return value.ui8; + case STRING: return convertFromString<uint8_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(UINT8))); + } +} +uint16_t VariantImpl::asUint16() const +{ + switch(type) { + case UINT8: return value.ui8; + case UINT16: return value.ui16; + case STRING: return convertFromString<uint16_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(UINT16))); + } +} +uint32_t VariantImpl::asUint32() const +{ + switch(type) { + case UINT8: return value.ui8; + case UINT16: return value.ui16; + case UINT32: return value.ui32; + case STRING: return convertFromString<uint32_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(UINT32))); + } +} +uint64_t VariantImpl::asUint64() const +{ + switch(type) { + case UINT8: return value.ui8; + case UINT16: return value.ui16; + case UINT32: return value.ui32; + case UINT64: return value.ui64; + case STRING: return convertFromString<uint64_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(UINT64))); + } +} +int8_t VariantImpl::asInt8() const +{ + switch(type) { + case INT8: return value.i8; + case STRING: return convertFromString<int8_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(INT8))); + } +} +int16_t VariantImpl::asInt16() const +{ + switch(type) { + case INT8: return value.i8; + case INT16: return value.i16; + case STRING: return convertFromString<int16_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(INT16))); + } +} +int32_t VariantImpl::asInt32() const +{ + switch(type) { + case INT8: return value.i8; + case INT16: return value.i16; + case INT32: return value.i32; + case STRING: return convertFromString<int32_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(INT32))); + } +} +int64_t VariantImpl::asInt64() const +{ + switch(type) { + case INT8: return value.i8; + case INT16: return value.i16; + case INT32: return value.i32; + case INT64: return value.i64; + case STRING: return convertFromString<int64_t>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(INT64))); + } +} +float VariantImpl::asFloat() const +{ + switch(type) { + case FLOAT: return value.f; + case STRING: return convertFromString<float>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(FLOAT))); + } +} +double VariantImpl::asDouble() const +{ + switch(type) { + case FLOAT: return value.f; + case DOUBLE: return value.d; + case STRING: return convertFromString<double>(); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(DOUBLE))); + } +} +std::string VariantImpl::asString() const +{ + switch(type) { + case VOID: return EMPTY; + case BOOL: return value.b ? TRUE : FALSE; + case UINT8: return boost::lexical_cast<std::string>((int) value.ui8); + case UINT16: return boost::lexical_cast<std::string>(value.ui16); + case UINT32: return boost::lexical_cast<std::string>(value.ui32); + case UINT64: return boost::lexical_cast<std::string>(value.ui64); + case INT8: return boost::lexical_cast<std::string>((int) value.i8); + case INT16: return boost::lexical_cast<std::string>(value.i16); + case INT32: return boost::lexical_cast<std::string>(value.i32); + case INT64: return boost::lexical_cast<std::string>(value.i64); + case DOUBLE: return boost::lexical_cast<std::string>(value.d); + case FLOAT: return boost::lexical_cast<std::string>(value.f); + case STRING: return *reinterpret_cast<std::string*>(value.v); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(STRING))); + } +} + +const Variant::Map& VariantImpl::asMap() const +{ + switch(type) { + case MAP: return *reinterpret_cast<Variant::Map*>(value.v); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(MAP))); + } +} + +Variant::Map& VariantImpl::asMap() +{ + switch(type) { + case MAP: return *reinterpret_cast<Variant::Map*>(value.v); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(MAP))); + } +} + +const Variant::List& VariantImpl::asList() const +{ + switch(type) { + case LIST: return *reinterpret_cast<Variant::List*>(value.v); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(LIST))); + } +} + +Variant::List& VariantImpl::asList() +{ + switch(type) { + case LIST: return *reinterpret_cast<Variant::List*>(value.v); + default: throw InvalidConversion(QPID_MSG("Cannot convert from " << getTypeName(type) << " to " << getTypeName(LIST))); + } +} + +std::string& VariantImpl::getString() +{ + switch(type) { + case STRING: return *reinterpret_cast<std::string*>(value.v); + default: throw InvalidConversion(QPID_MSG("Variant is not a string; use asString() if conversion is required.")); + } +} + +const std::string& VariantImpl::getString() const +{ + switch(type) { + case STRING: return *reinterpret_cast<std::string*>(value.v); + default: throw InvalidConversion(QPID_MSG("Variant is not a string; use asString() if conversion is required.")); + } +} + +void VariantImpl::setEncoding(const std::string& s) { encoding = s; } +const std::string& VariantImpl::getEncoding() const { return encoding; } + +std::string VariantImpl::getTypeName(VariantType type) const +{ + switch (type) { + case VOID: return "void"; + case BOOL: return "bool"; + case UINT8: return "uint8"; + case UINT16: return "uint16"; + case UINT32: return "uint32"; + case UINT64: return "uint64"; + case INT8: return "int8"; + case INT16: return "int16"; + case INT32: return "int32"; + case INT64: return "int64"; + case FLOAT: return "float"; + case DOUBLE: return "double"; + case STRING: return "string"; + case MAP: return "map"; + case LIST: return "list"; + } + return "<unknown>";//should never happen +} + +VariantImpl* VariantImpl::create(const Variant& v) +{ + switch (v.getType()) { + case BOOL: return new VariantImpl(v.asBool()); + case UINT8: return new VariantImpl(v.asUint8()); + case UINT16: return new VariantImpl(v.asUint16()); + case UINT32: return new VariantImpl(v.asUint32()); + case UINT64: return new VariantImpl(v.asUint64()); + case INT8: return new VariantImpl(v.asInt8()); + case INT16: return new VariantImpl(v.asInt16()); + case INT32: return new VariantImpl(v.asInt32()); + case INT64: return new VariantImpl(v.asInt64()); + case FLOAT: return new VariantImpl(v.asFloat()); + case DOUBLE: return new VariantImpl(v.asDouble()); + case STRING: return new VariantImpl(v.asString()); + case MAP: return new VariantImpl(v.asMap()); + case LIST: return new VariantImpl(v.asList()); + default: return new VariantImpl(); + } +} + +Variant::Variant() : impl(new VariantImpl()) {} +Variant::Variant(bool b) : impl(new VariantImpl(b)) {} +Variant::Variant(uint8_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(uint16_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(uint32_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(uint64_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(int8_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(int16_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(int32_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(int64_t i) : impl(new VariantImpl(i)) {} +Variant::Variant(float f) : impl(new VariantImpl(f)) {} +Variant::Variant(double d) : impl(new VariantImpl(d)) {} +Variant::Variant(const std::string& s) : impl(new VariantImpl(s)) {} +Variant::Variant(const char* s) : impl(new VariantImpl(std::string(s))) {} +Variant::Variant(const Map& m) : impl(new VariantImpl(m)) {} +Variant::Variant(const List& l) : impl(new VariantImpl(l)) {} +Variant::Variant(const Variant& v) : impl(VariantImpl::create(v)) {} + +Variant::~Variant() { if (impl) delete impl; } + +void Variant::reset() +{ + if (impl) delete impl; + impl = new VariantImpl(); +} + + +Variant& Variant::operator=(bool b) +{ + if (impl) delete impl; + impl = new VariantImpl(b); + return *this; +} + +Variant& Variant::operator=(uint8_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} +Variant& Variant::operator=(uint16_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} +Variant& Variant::operator=(uint32_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} +Variant& Variant::operator=(uint64_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} + +Variant& Variant::operator=(int8_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} +Variant& Variant::operator=(int16_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} +Variant& Variant::operator=(int32_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} +Variant& Variant::operator=(int64_t i) +{ + if (impl) delete impl; + impl = new VariantImpl(i); + return *this; +} + +Variant& Variant::operator=(float f) +{ + if (impl) delete impl; + impl = new VariantImpl(f); + return *this; +} +Variant& Variant::operator=(double d) +{ + if (impl) delete impl; + impl = new VariantImpl(d); + return *this; +} + +Variant& Variant::operator=(const std::string& s) +{ + if (impl) delete impl; + impl = new VariantImpl(s); + return *this; +} + +Variant& Variant::operator=(const char* s) +{ + if (impl) delete impl; + impl = new VariantImpl(std::string(s)); + return *this; +} + +Variant& Variant::operator=(const Map& m) +{ + if (impl) delete impl; + impl = new VariantImpl(m); + return *this; +} + +Variant& Variant::operator=(const List& l) +{ + if (impl) delete impl; + impl = new VariantImpl(l); + return *this; +} + +Variant& Variant::operator=(const Variant& v) +{ + if (impl) delete impl; + impl = VariantImpl::create(v); + return *this; +} + +VariantType Variant::getType() const { return impl->getType(); } +bool Variant::asBool() const { return impl->asBool(); } +uint8_t Variant::asUint8() const { return impl->asUint8(); } +uint16_t Variant::asUint16() const { return impl->asUint16(); } +uint32_t Variant::asUint32() const { return impl->asUint32(); } +uint64_t Variant::asUint64() const { return impl->asUint64(); } +int8_t Variant::asInt8() const { return impl->asInt8(); } +int16_t Variant::asInt16() const { return impl->asInt16(); } +int32_t Variant::asInt32() const { return impl->asInt32(); } +int64_t Variant::asInt64() const { return impl->asInt64(); } +float Variant::asFloat() const { return impl->asFloat(); } +double Variant::asDouble() const { return impl->asDouble(); } +std::string Variant::asString() const { return impl->asString(); } +const Variant::Map& Variant::asMap() const { return impl->asMap(); } +Variant::Map& Variant::asMap() { return impl->asMap(); } +const Variant::List& Variant::asList() const { return impl->asList(); } +Variant::List& Variant::asList() { return impl->asList(); } +const std::string& Variant::getString() const { return impl->getString(); } +std::string& Variant::getString() { return impl->getString(); } +void Variant::setEncoding(const std::string& s) { impl->setEncoding(s); } +const std::string& Variant::getEncoding() const { return impl->getEncoding(); } + +Variant::operator bool() const { return asBool(); } +Variant::operator uint8_t() const { return asUint8(); } +Variant::operator uint16_t() const { return asUint16(); } +Variant::operator uint32_t() const { return asUint32(); } +Variant::operator uint64_t() const { return asUint64(); } +Variant::operator int8_t() const { return asInt8(); } +Variant::operator int16_t() const { return asInt16(); } +Variant::operator int32_t() const { return asInt32(); } +Variant::operator int64_t() const { return asInt64(); } +Variant::operator float() const { return asFloat(); } +Variant::operator double() const { return asDouble(); } +Variant::operator const char*() const { return asString().c_str(); } + +std::ostream& operator<<(std::ostream& out, const Variant::Map& map) +{ + for (Variant::Map::const_iterator i = map.begin(); i != map.end(); ++i) { + if (i != map.begin()) out << ", "; + out << i->first << ":" << i->second; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, const Variant::List& list) +{ + for (Variant::List::const_iterator i = list.begin(); i != list.end(); ++i) { + if (i != list.begin()) out << ", "; + out << *i; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, const Variant& value) +{ + switch (value.getType()) { + case MAP: + out << "{" << value.asMap() << "}"; + break; + case LIST: + out << "[" << value.asList() << "]"; + break; + case VOID: + out << "<void>"; + break; + default: + out << value.asString(); + break; + } + return out; +} + +}} // namespace qpid::messaging |
