You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2009/08/26 18:55:44 UTC

svn commit: r808121 - in /qpid/trunk/qpid/cpp: examples/messaging/ include/qpid/messaging/ src/ src/qpid/client/amqp0_10/ src/qpid/messaging/ src/tests/

Author: gsim
Date: Wed Aug 26 16:55:43 2009
New Revision: 808121

URL: http://svn.apache.org/viewvc?rev=808121&view=rev
Log:
Hide internal message ID behind API


Added:
    qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.cpp
    qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.h
Modified:
    qpid/trunk/qpid/cpp/examples/messaging/server.cpp
    qpid/trunk/qpid/cpp/include/qpid/messaging/Message.h
    qpid/trunk/qpid/cpp/src/CMakeLists.txt
    qpid/trunk/qpid/cpp/src/Makefile.am
    qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
    qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
    qpid/trunk/qpid/cpp/src/qpid/messaging/Message.cpp
    qpid/trunk/qpid/cpp/src/tests/MessagingSessionTests.cpp

Modified: qpid/trunk/qpid/cpp/examples/messaging/server.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/examples/messaging/server.cpp?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/examples/messaging/server.cpp (original)
+++ qpid/trunk/qpid/cpp/examples/messaging/server.cpp Wed Aug 26 16:55:43 2009
@@ -44,9 +44,7 @@
     try {
         Connection connection = Connection::open(url);
         Session session = connection.newSession();
-        VariantMap options;
-        options["auto_acknowledge"] = 0;
-        Receiver receiver = session.createReceiver("service_queue", options);
+        Receiver receiver = session.createReceiver("service_queue");
 
         while (true) {
             Message request = receiver.fetch();

Modified: qpid/trunk/qpid/cpp/include/qpid/messaging/Message.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qpid/messaging/Message.h?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qpid/messaging/Message.h (original)
+++ qpid/trunk/qpid/cpp/include/qpid/messaging/Message.h Wed Aug 26 16:55:43 2009
@@ -79,11 +79,9 @@
     QPID_CLIENT_EXTERN void encode(Codec&);
     QPID_CLIENT_EXTERN void decode(Codec&);
 
-    //TODO: move this out of the public API
-    QPID_CLIENT_EXTERN void setInternalId(void*);
-    QPID_CLIENT_EXTERN void* getInternalId();
   private:
     MessageImpl* impl;
+  friend class MessageImplAccess;
 };
 }} // namespace qpid::messaging
 

Modified: qpid/trunk/qpid/cpp/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/CMakeLists.txt?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/src/CMakeLists.txt Wed Aug 26 16:55:43 2009
@@ -528,6 +528,8 @@
      qpid/messaging/ConnectionImpl.h
      qpid/messaging/Filter.cpp
      qpid/messaging/Message.cpp
+     qpid/messaging/MessageImpl.h
+     qpid/messaging/MessageImpl.cpp
      qpid/messaging/Receiver.cpp
      qpid/messaging/ReceiverImpl.h
      qpid/messaging/Session.cpp

Modified: qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/Makefile.am?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ qpid/trunk/qpid/cpp/src/Makefile.am Wed Aug 26 16:55:43 2009
@@ -686,6 +686,8 @@
   qpid/messaging/Connection.cpp			\
   qpid/messaging/Filter.cpp			\
   qpid/messaging/Message.cpp			\
+  qpid/messaging/MessageImpl.h			\
+  qpid/messaging/MessageImpl.cpp		\
   qpid/messaging/Sender.cpp			\
   qpid/messaging/Receiver.cpp			\
   qpid/messaging/Session.cpp			\

Modified: qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp Wed Aug 26 16:55:43 2009
@@ -26,6 +26,7 @@
 #include "qpid/log/Statement.h"
 #include "qpid/messaging/Address.h"
 #include "qpid/messaging/Message.h"
+#include "qpid/messaging/MessageImpl.h"
 #include "qpid/messaging/Variant.h"
 #include "qpid/framing/DeliveryProperties.h"
 #include "qpid/framing/FrameSet.h"
@@ -41,6 +42,7 @@
 using namespace qpid::framing::message;
 using qpid::sys::AbsTime;
 using qpid::sys::Duration;
+using qpid::messaging::MessageImplAccess;
 using qpid::messaging::Variant;
 
 namespace {
@@ -219,9 +221,8 @@
 void populate(qpid::messaging::Message& message, FrameSet& command)
 {
     //need to be able to link the message back to the transfer it was delivered by
-    //e.g. for rejecting. TODO: hide this from API
-    uint32_t commandId = command.getId();
-    message.setInternalId(reinterpret_cast<void*>(commandId));
+    //e.g. for rejecting.
+    MessageImplAccess::get(message).setInternalId(command.getId());
         
     command.getContent(message.getBytes());
 

Modified: qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp Wed Aug 26 16:55:43 2009
@@ -29,6 +29,7 @@
 #include "qpid/messaging/Address.h"
 #include "qpid/messaging/Filter.h"
 #include "qpid/messaging/Message.h"
+#include "qpid/messaging/MessageImpl.h"
 #include "qpid/messaging/MessageListener.h"
 #include "qpid/messaging/Sender.h"
 #include "qpid/messaging/Receiver.h"
@@ -39,6 +40,7 @@
 #include <boost/intrusive_ptr.hpp>
 
 using qpid::messaging::Filter;
+using qpid::messaging::MessageImplAccess;
 using qpid::messaging::Sender;
 using qpid::messaging::Receiver;
 using qpid::messaging::VariantMap;
@@ -78,16 +80,8 @@
 void SessionImpl::reject(qpid::messaging::Message& m)
 {
     qpid::sys::Mutex::ScopedLock l(lock);
-    //TODO: how do I get the id of the original transfer command? think this through some more...
-
-    // [tross] The following hack was added to get this code to compile on a 64-bit machine.
-    //         It should be functionally equivalent to the original on a 32-bit architecture
-    //         but is almost certainly not what was intended by the author.
-    uint64_t rawId(reinterpret_cast<uint64_t>(m.getInternalId()));
-    SequenceNumber id((uint32_t) ((rawId & 0xFFFFFFFF) ^ ((rawId >> 32) & 0xFFFFFFFF)));
-
     SequenceSet set;
-    set.add(id);
+    set.add(MessageImplAccess::get(m).getInternalId());
     session.messageReject(set);
 }
 

Modified: qpid/trunk/qpid/cpp/src/qpid/messaging/Message.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/Message.cpp?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/Message.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/Message.cpp Wed Aug 26 16:55:43 2009
@@ -19,263 +19,11 @@
  *
  */
 #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"
+#include "qpid/messaging/MessageImpl.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)) {}
 
@@ -314,9 +62,6 @@
 
 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);

Added: qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.cpp?rev=808121&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.cpp Wed Aug 26 16:55:43 2009
@@ -0,0 +1,192 @@
+/*
+ *
+ * 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 "MessageImpl.h"
+#include "qpid/messaging/Message.h"
+
+namespace qpid {
+namespace messaging {
+
+namespace {
+const std::string EMPTY_STRING = "";
+}
+
+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(qpid::framing::SequenceNumber i) { internalId = i; }
+qpid::framing::SequenceNumber 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; } 
+
+MessageImpl& MessageImplAccess::get(Message& msg)
+{
+    return *msg.impl;
+}
+
+}} // namespace qpid::messaging

Added: qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.h?rev=808121&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.h (added)
+++ qpid/trunk/qpid/cpp/src/qpid/messaging/MessageImpl.h Wed Aug 26 16:55:43 2009
@@ -0,0 +1,132 @@
+#ifndef QPID_MESSAGING_MESSAGEIMPL_H
+#define QPID_MESSAGING_MESSAGEIMPL_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/messaging/Address.h"
+#include "qpid/messaging/Codec.h"
+#include "qpid/messaging/MessageContent.h"
+#include "qpid/messaging/Variant.h"
+#include "qpid/framing/SequenceNumber.h"
+
+namespace qpid {
+namespace messaging {
+
+struct MessageImpl : MessageContent
+{
+    Address replyTo;
+    std::string subject;
+    std::string contentType;
+    Variant::Map 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
+
+    qpid::framing::SequenceNumber 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 Variant::Map& getHeaders() const;
+    Variant::Map& 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(qpid::framing::SequenceNumber id);
+    qpid::framing::SequenceNumber 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);
+};
+
+class Message;
+
+/**
+ * Provides access to the internal MessageImpl for a message which is
+ * useful when accessing any message state not exposed directly
+ * through the public API.
+ */
+struct MessageImplAccess
+{
+    static MessageImpl& get(Message&);
+};
+
+}} // namespace qpid::messaging
+
+#endif  /*!QPID_MESSAGING_MESSAGEIMPL_H*/

Modified: qpid/trunk/qpid/cpp/src/tests/MessagingSessionTests.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/MessagingSessionTests.cpp?rev=808121&r1=808120&r2=808121&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/MessagingSessionTests.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/MessagingSessionTests.cpp Wed Aug 26 16:55:43 2009
@@ -322,4 +322,21 @@
     fix.session.acknowledge();
 }
 
+QPID_AUTO_TEST_CASE(testReject)
+{
+    QueueFixture fix;
+    Sender sender = fix.session.createSender(fix.queue);
+    Message m1("reject-me");
+    sender.send(m1);
+    Message m2("accept-me");
+    sender.send(m2);
+    Receiver receiver = fix.session.createReceiver(fix.queue);
+    Message in = receiver.fetch(5 * qpid::sys::TIME_SEC);
+    BOOST_CHECK_EQUAL(in.getBytes(), m1.getBytes());
+    fix.session.reject(in);
+    in = receiver.fetch(5 * qpid::sys::TIME_SEC);
+    BOOST_CHECK_EQUAL(in.getBytes(), m2.getBytes());
+    fix.session.acknowledge();    
+}
+
 QPID_AUTO_TEST_SUITE_END()



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org