blob: 09a9d948d5bc0b6e66a50999371fb4ca608eb57b [file] [log] [blame]
#ifndef QPID_MESSAGING_AMQP_ENCODEDMESSAGE_H
#define QPID_MESSAGING_AMQP_ENCODEDMESSAGE_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/amqp/CharSequence.h"
#include "qpid/amqp/MessageId.h"
#include "qpid/amqp/MessageReader.h"
#include "qpid/sys/IntegerTypes.h"
#include "qpid/types/Variant.h"
#include <boost/optional.hpp>
namespace qpid {
namespace amqp {
struct Descriptor;
}
namespace messaging {
class Address;
class MessageImpl;
namespace amqp {
/**
* Used to 'lazy-decode' an AMQP 1.0 message.
*
* There are four categories of data item:
*
* (i) simple, fixed width primitives - priority, ttl, durability,
* delivery count - for which lazy-decoding doesn't buy much. These
* are decoded unconditionally on an initial scan of the message.
*
* (ii) standard variable length string properties - subject,
* message-id, user-id etc - which require conversion to a std::string
* for returning to the application. By delaying the conversion of
* these to a std::string we can avoid allocation & copying until it
* is actually required. The initial scan of the message merely
* records the position of these strings within the raw message data.
*
* (iii) custom, application defined headers. These form a map, and
* again, delaying the creation of that map until it is actually
* required can be advantageous. The initial scan of the message merely
* records the position of this section within the raw message data.
*
* (iv) the body content. This may be retreived as a std::string, or
* as a char*. Avoiding conversion to the string until it is required
* is advantageous. The initial scan of the message merely records the
* position of this section within the raw message data.
*
* At present the Message class only explicitly exposes some of the
* standard property and headers defined by AMQP 1.0. The remainder
* will have to be accessed through the message 'headers' map, using
* the 'x-amqp-' prefix.
*/
class EncodedMessage
{
public:
EncodedMessage();
EncodedMessage(size_t);
EncodedMessage(const EncodedMessage&);
~EncodedMessage();
size_t getSize() const;
char* getData();
const char* getData() const;
void trim(size_t);
void resize(size_t);
void getReplyTo(qpid::messaging::Address&) const;
void getSubject(std::string&) const;
void getContentType(std::string&) const;
void getMessageId(std::string&) const;
void getUserId(std::string&) const;
void getCorrelationId(std::string&) const;
void init(qpid::messaging::MessageImpl&);
void populate(qpid::types::Variant::Map&) const;
void getBody(std::string&) const;
qpid::amqp::CharSequence getBareMessage() const;
qpid::amqp::CharSequence getBody() const;
bool hasHeaderChanged(const qpid::messaging::MessageImpl&) const;
private:
size_t size;
char* data;
class InitialScan : public qpid::amqp::MessageReader
{
public:
InitialScan(EncodedMessage& e, qpid::messaging::MessageImpl& m);
//header:
void onDurable(bool b);
void onPriority(uint8_t i);
void onTtl(uint32_t i);
void onFirstAcquirer(bool b);
void onDeliveryCount(uint32_t i);
//properties:
void onMessageId(uint64_t);
void onMessageId(const qpid::amqp::CharSequence&, qpid::types::VariantType);
void onUserId(const qpid::amqp::CharSequence& v);
void onTo(const qpid::amqp::CharSequence& v);
void onSubject(const qpid::amqp::CharSequence& v);
void onReplyTo(const qpid::amqp::CharSequence& v);
void onCorrelationId(uint64_t);
void onCorrelationId(const qpid::amqp::CharSequence&, qpid::types::VariantType);
void onContentType(const qpid::amqp::CharSequence& v);
void onContentEncoding(const qpid::amqp::CharSequence& v);
void onAbsoluteExpiryTime(int64_t i);
void onCreationTime(int64_t);
void onGroupId(const qpid::amqp::CharSequence&);
void onGroupSequence(uint32_t);
void onReplyToGroupId(const qpid::amqp::CharSequence&);
void onApplicationProperties(const qpid::amqp::CharSequence&);
void onDeliveryAnnotations(const qpid::amqp::CharSequence&);
void onMessageAnnotations(const qpid::amqp::CharSequence&);
void onBody(const qpid::amqp::CharSequence&, const qpid::amqp::Descriptor&);
void onBody(const qpid::types::Variant&, const qpid::amqp::Descriptor&);
void onFooter(const qpid::amqp::CharSequence&);
private:
EncodedMessage& em;
qpid::messaging::MessageImpl& mi;
};
//header:
boost::optional<bool> durable;
boost::optional<uint8_t> priority;
boost::optional<uint32_t> ttl;
boost::optional<bool> firstAcquirer;
boost::optional<uint32_t> deliveryCount;
//annotations:
qpid::amqp::CharSequence deliveryAnnotations;
qpid::amqp::CharSequence messageAnnotations;
qpid::amqp::CharSequence bareMessage;//properties, application-properties and content
//properties:
qpid::amqp::MessageId messageId;
qpid::amqp::CharSequence userId;
qpid::amqp::CharSequence to;
qpid::amqp::CharSequence subject;
qpid::amqp::CharSequence replyTo;
qpid::amqp::MessageId correlationId;
qpid::amqp::CharSequence contentType;
qpid::amqp::CharSequence contentEncoding;
boost::optional<int64_t> absoluteExpiryTime;
boost::optional<int64_t> creationTime;
qpid::amqp::CharSequence groupId;
boost::optional<uint32_t> groupSequence;
qpid::amqp::CharSequence replyToGroupId;
//application-properties:
qpid::amqp::CharSequence applicationProperties;
qpid::amqp::CharSequence body;
//footer:
qpid::amqp::CharSequence footer;
void init();
//not implemented:
EncodedMessage& operator=(const EncodedMessage&);
};
}}} // namespace qpid::messaging::amqp
#endif /*!QPID_MESSAGING_ENCODEDMESSAGE_H*/