00001 #ifndef QPID_FRAMING_AMQHEADERBODY_H
00002 #define QPID_FRAMING_AMQHEADERBODY_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "amqp_types.h"
00025 #include "AMQBody.h"
00026 #include "Buffer.h"
00027 #include "qpid/framing/DeliveryProperties.h"
00028 #include "qpid/framing/MessageProperties.h"
00029 #include "qpid/CommonImportExport.h"
00030 #include <iostream>
00031
00032 #include <boost/optional.hpp>
00033
00034
00035 namespace qpid {
00036 namespace framing {
00037
00038 class AMQHeaderBody : public AMQBody
00039 {
00040 template <class T> struct OptProps { boost::optional<T> props; };
00041 template <class Base, class T>
00042 struct PropSet : public Base, public OptProps<T> {
00043 uint32_t encodedSize() const {
00044 const boost::optional<T>& p=this->OptProps<T>::props;
00045 return (p ? p->encodedSize() : 0) + Base::encodedSize();
00046 }
00047 void encode(Buffer& buffer) const {
00048 const boost::optional<T>& p=this->OptProps<T>::props;
00049 if (p) p->encode(buffer);
00050 Base::encode(buffer);
00051 }
00052 bool decode(Buffer& buffer, uint32_t size, uint16_t type) {
00053 boost::optional<T>& p=this->OptProps<T>::props;
00054 if (type == T::TYPE) {
00055 p=T();
00056 p->decodeStructBody(buffer, size);
00057 return true;
00058 }
00059 else
00060 return Base::decode(buffer, size, type);
00061 }
00062 void print(std::ostream& out) const {
00063 const boost::optional<T>& p=this->OptProps<T>::props;
00064 if (p) out << *p;
00065 Base::print(out);
00066 }
00067 };
00068
00069 struct Empty {
00070 uint32_t encodedSize() const { return 0; }
00071 void encode(Buffer&) const {};
00072 bool decode(Buffer&, uint32_t, uint16_t) const { return false; };
00073 void print(std::ostream&) const {}
00074 };
00075
00076
00077 typedef PropSet<PropSet<Empty, DeliveryProperties>, MessageProperties> Properties;
00078
00079 Properties properties;
00080
00081 public:
00082
00083 inline uint8_t type() const { return HEADER_BODY; }
00084
00085 QPID_COMMON_EXTERN uint32_t encodedSize() const;
00086 QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
00087 QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size);
00088 QPID_COMMON_EXTERN uint64_t getContentLength() const;
00089 QPID_COMMON_EXTERN void print(std::ostream& out) const;
00090 QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor&) const;
00091
00092 template <class T> T* get(bool create) {
00093 boost::optional<T>& p=properties.OptProps<T>::props;
00094 if (create && !p) p=T();
00095 return p.get_ptr();
00096 }
00097
00098 template <class T> const T* get() const {
00099 return properties.OptProps<T>::props.get_ptr();
00100 }
00101
00102 boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
00103 };
00104
00105 }}
00106
00107
00108
00109 #endif