ComparableAttributeSet.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef _ComparableAttributeSet_h_
00041 #define _ComparableAttributeSet_h_
00042
00043 #include <boost/shared_ptr.hpp>
00044 #include <boost/shared_array.hpp>
00045 #include <boost/noncopyable.hpp>
00046 #include <boost/mpl/list.hpp>
00047 #include <boost/asio/buffer.hpp>
00048 #include "mw/attributes/AttributeSet.h"
00049 #include "mw/attributes/filter/greater_than_or_equal_to.h"
00050 #include "mw/attributes/filter/less_than_or_equal_to.h"
00051 #include "mw/nl/awds/AWDS_Packet.h"
00052 #include "mw/nl/awds/logging.h"
00053
00054 #include "mw/attributes/access/Attribute_RT.h"
00055 #include "mw/attributes/access/AttributeSet_RT.h"
00056
00057 namespace famouso {
00058 namespace mw {
00059 namespace nl {
00060 namespace awds {
00061 namespace detail {
00066 template< typename Comparator >
00067 struct op_printer {
00068 static const char* op() {
00069 return (" ? ");
00070 }
00071 };
00072 template< >
00073 struct op_printer<famouso::mw::attributes::filter::less_than_or_equal_to> {
00074 static const char* op() {
00075 return (" <= ");
00076 }
00077 };
00078 template< >
00079 struct op_printer<famouso::mw::attributes::filter::greater_than_or_equal_to> {
00080 static const char* op() {
00081 return (" >= ");
00082 }
00083 };
00084 }
00085
00086
00087
00088
00089
00090 template< class AttrSet = famouso::mw::attributes::AttributeSet<> >
00091 class ComparableAttributeSet: boost::noncopyable {
00092
00093 public:
00095 typedef typename AttrSet::sequence AttrSeq;
00096
00097 private:
00099 typedef boost::shared_array<uint8_t> pData;
00100
00101 pData data;
00109 template< class Seq, class Itr = typename boost::mpl::begin<Seq>::type >
00110 class AttributeIterator {
00111
00113 typedef typename boost::mpl::deref<Itr>::type attrib;
00114
00116 typedef typename attrib::comparator cmp;
00117
00119 typedef typename boost::mpl::end<Seq>::type end;
00120
00124 static void echo(::logging::loggingReturnType &out, attrib *a) {
00125 if (a)
00126 out << (intmax_t) a->getValue();
00127 else
00128 out << "nd";
00129 }
00130
00142 static bool match(const attrib *a, const attrib *b) {
00143
00144 if (!b)
00145 return true;
00146
00147
00148 if (a && cmp::apply_runtime(a->getValue(), b->getValue()))
00149 return true;
00150
00151
00152 return false;
00153 }
00154
00155 public:
00156
00166 static bool match(AttrSet &a, AttrSet &b) {
00167
00168 attrib *l = a.template find_rt<attrib> ();
00169 attrib *r = b.template find_rt<attrib> ();
00170
00171 ::logging::loggingReturnType &out = log::emit<ATTR>();
00172
00173 out << "matching " << (int) attrib::id << ": ";
00174 echo(out, l);
00175 out << detail::op_printer<cmp>::op();
00176 echo(out, r);
00177 out << log::endl;
00178
00179
00180 if (!match(l, r)) {
00181 log::emit<ATTR>() << "unsuccessfull" << log::endl;
00182 return false;
00183 }
00184
00185
00186 return AttributeIterator<Seq, typename boost::mpl::next<Itr>::type>::match(a, b);
00187 }
00188
00195 static void print(::logging::loggingReturnType &out, AttrSet &a) {
00196
00197 attrib *attr = a.template find_rt<attrib> ();
00198 if (attr) {
00199
00200 out << " [" << (int) attrib::id << "]={" << (intmax_t) attr->getValue() << "}";
00201 }
00202
00203
00204 AttributeIterator<Seq, typename boost::mpl::next<Itr>::type>::print(out, a);
00205 }
00206 };
00207
00213 template< class Seq >
00214 class AttributeIterator<Seq, typename boost::mpl::end<Seq>::type> {
00215 public:
00216
00217 static bool match(const AttrSet &a, const AttrSet &b) {
00218 log::emit<ATTR>() << "successfull" << log::endl;
00219 return true;
00220 }
00221
00222 static void print(::logging::loggingReturnType &out, const AttrSet &a) {
00223 }
00224 };
00225
00226
00227
00228
00229
00230
00231 void set(uint8_t *d, uint16_t s) {
00232 static uint8_t p[1] = { 0 };
00233
00234 if (s <= 0) {
00235 s = 1;
00236 d = p;
00237 }
00238 data = pData(new uint8_t[s]);
00239 std::memcpy(data.get(), d, s);
00240
00241 }
00242
00247 static uint16_t size(uint8_t* data) {
00248
00249 if (!data)
00250 return 0;
00251
00252 typedef famouso::mw::attributes::access::AttributeSet_RT *AS;
00253
00254 const AS set_rt = reinterpret_cast<const AS> (&data[0]);
00255
00256 return set_rt->length();
00257 }
00258
00264 ComparableAttributeSet() {
00265 set(NULL, 0);
00266 }
00267
00272 AttrSet &getSet() {
00273 return *reinterpret_cast<AttrSet*> (data.get());
00274 }
00275
00276 public:
00278 typedef boost::shared_ptr<ComparableAttributeSet> type;
00279
00285 void set(awds::AWDS_Packet &p) {
00286
00287 if (p.header.type != AWDS_Packet::constants::packet_type::attributes)
00288 return;
00289
00290 set(p.data, size(p.data));
00291 }
00292
00304 static bool match(const type & a, const type & b) {
00305 return AttributeIterator<AttrSeq>::match(a->getSet(), b->getSet());
00306 }
00307
00312 void print(::logging::loggingReturnType &out) {
00313 out << ::logging::log::dec;
00314 AttributeIterator<AttrSeq>::print(out, getSet());
00315 }
00316
00321 type clone() {
00322 type res = create(getSet());
00323 return res;
00324 }
00325
00331 template< class Attrib >
00332 Attrib *find() {
00333 return getSet().template find_rt<Attrib> ();
00334 }
00335
00340 operator boost::asio::const_buffer() {
00341 uint8_t *d = data.get();
00342 return boost::asio::buffer(d, size(d));
00343 }
00344
00345
00350 uint16_t size(){
00351 return size(data.get());
00352 }
00353
00358 static type create() {
00359 type res = type(new ComparableAttributeSet());
00360 return res;
00361 }
00362
00368 static type create(AWDS_Packet &p) {
00369 type res = create();
00370 res->set(p);
00371 return res;
00372 }
00373
00382 template< class AttrSeq2 >
00383 static type create(famouso::mw::attributes::AttributeSet<AttrSeq2> &p) {
00384 type res = create();
00385 uint8_t *d = reinterpret_cast<uint8_t*> (&p);
00386 res->set(d, size(d));
00387 return res;
00388 }
00389
00397 static type create(uint8_t *d) {
00398 type res = create();
00399 if (d)
00400 res->set(d, size(d));
00401 return res;
00402 }
00403 };
00404
00405 }
00406 }
00407 }
00408 }
00409
00410 namespace logging {
00411 using famouso::mw::nl::awds::ComparableAttributeSet;
00412
00421 template< class AttrSeq >
00422 inline ::logging::loggingReturnType &operator<<(loggingReturnType &out, const boost::shared_ptr<ComparableAttributeSet<AttrSeq> > &att) {
00423 att->print(out);
00424 return out;
00425 }
00426
00427 }
00428 #endif