00001 #ifndef QPID_AMQP_0_10_MAP_H
00002 #define QPID_AMQP_0_10_MAP_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qpid/Exception.h"
00026 #include "qpid/amqp_0_10/built_in_types.h"
00027 #include "qpid/amqp_0_10/UnknownType.h"
00028 #include "qpid/amqp_0_10/CodeForType.h"
00029 #include "qpid/amqp_0_10/TypeForCode.h"
00030 #include "qpid/amqp_0_10/Codec.h"
00031 #include "qpid/framing/Blob.h"
00032 #include <map>
00033 #include <string>
00034 #include <iosfwd>
00035
00036 namespace qpid {
00037 namespace amqp_0_10 {
00038
00039 class Map;
00040
00041 class MapValue {
00042 public:
00043 struct BadTypeException : public Exception {};
00044
00045 template <class R> struct Visitor { typedef R result_type; };
00046
00047 MapValue();
00048 MapValue(const MapValue& x);
00049 template <class T> explicit MapValue(const T& t);
00050 template <class T> MapValue& operator=(const T& t);
00051
00052 template <class T> T* get();
00053 template <class T> const T* get() const;
00054
00055 template <class V> typename V::result_type apply_visitor(V&);
00056 template <class V> typename V::result_type apply_visitor(const V&);
00057
00058 uint8_t getCode() const { return code; }
00059
00060 bool operator==(const MapValue&) const;
00061
00062 template <class S> void serialize(S& s) { s(code); s.split(*this); }
00063 template <class S> void encode(S& s) const {
00064 const_cast<MapValue*>(this)->apply_visitor(s);
00065 }
00066 template <class S> void decode(S& s) {
00067 DecodeVisitor<S> dv(blob, s);
00068 qpid::amqp_0_10::apply_visitor(dv, code);
00069 }
00070
00071
00072 private:
00073 static const size_t SIZE=128 < sizeof(Vbin32) ? sizeof(Vbin32) : 128;
00074 typedef framing::Blob<SIZE> Blob;
00075
00076 template <class V> struct VisitVisitor;
00077 template <class T> struct GetVisitor;
00078 template <class D> struct DecodeVisitor;
00079
00080 uint8_t code;
00081 Blob blob;
00082 };
00083
00084 class Map : public std::map<Str8, MapValue> {
00085 public:
00086 template <class S> void serialize(S& s) { s.split(*this); }
00087 template <class S> void encode(S& s) const;
00088
00089 void encode(Codec::Size& s) const { s.raw(0, contentSize() + 4); }
00090
00091 template <class S> void decode(S& s);
00092
00093 private:
00094 uint32_t contentSize() const;
00095 };
00096
00097 std::ostream& operator<<(std::ostream&, const MapValue&);
00098 std::ostream& operator<<(std::ostream&, const Map::value_type&);
00099 std::ostream& operator<<(std::ostream&, const Map&);
00100
00101 using framing::in_place;
00102
00103 template <class T> MapValue::MapValue(const T& t) : code(codeFor(t)), blob(in_place<t>()) {}
00104
00105 template <class T> MapValue& MapValue::operator=(const T& t) {
00106 code=codeFor(t);
00107 blob=t;
00108 return *this;
00109 }
00110
00111 template <class V> struct MapValue::VisitVisitor {
00112 typedef typename V::result_type result_type;
00113 V& visitor;
00114 Blob& blob;
00115 VisitVisitor(V& v, Blob& b) : visitor(v), blob(b) {}
00116
00117 template <class T> result_type operator()(T*) {
00118 return visitor(*reinterpret_cast<T*>(blob.get()));
00119 }
00120 };
00121
00122 template <class V> typename V::result_type MapValue::apply_visitor(V& v) {
00123 VisitVisitor<V> visitor(v, blob);
00124 return qpid::amqp_0_10::apply_visitor(visitor, code);
00125 }
00126
00127 template <class R> struct MapValue::GetVisitor {
00128 typedef R* result_type;
00129 const MapValue::Blob& blob;
00130
00131 GetVisitor(const MapValue::Blob& b) : blob(b) {}
00132
00133 R* operator()(R& r) { return &r; }
00134 template <class T> R* operator()(T&) { return 0; }
00135 };
00136
00137 template <class D> struct MapValue::DecodeVisitor {
00138 typedef void result_type;
00139 MapValue::Blob& blob;
00140 D& decoder;
00141 DecodeVisitor(Blob& b, D& d) : blob(b), decoder(d) {}
00142
00143 template <class T> void operator()(T*) {
00144 T t;
00145 decoder(t);
00146 blob = t;
00147 }
00148 };
00149
00150 template <class T> T* MapValue::get() { return apply_visitor(GetVisitor<T>(blob)); }
00151 template <class T> const T* MapValue::get() const { return apply_visitor(GetVisitor<const T>()); }
00152
00153 template <class V> typename V::result_type MapValue::apply_visitor(const V& v) {
00154 return apply_visitor(const_cast<V&>(v));
00155 }
00156
00157 template <class S> void Map::encode(S& s) const {
00158
00159
00160 s(contentSize());
00161 for (const_iterator i = begin(); i != end(); ++i)
00162 s(i->first)(i->second);
00163 }
00164
00165 template <class S> void Map::decode(S& s) {
00166 uint32_t decodedSize ;
00167
00168
00169
00170 s(decodedSize);
00171 typename S::ScopedLimit l(s, decodedSize);
00172
00173
00174 while (s.getLimit() > 0) {
00175 key_type k; MapValue v;
00176 s(k)(v);
00177 insert(value_type(k,v));
00178 }
00179 }
00180
00181
00182 }}
00183
00184 #endif