MultiSourceDemux.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
00041 #ifndef __MULTISOURCEDEMUX_H_2A8B3BD61E7528__
00042 #define __MULTISOURCEDEMUX_H_2A8B3BD61E7528__
00043
00044
00045 #include "debug.h"
00046
00047 #include "mw/afp/defrag/Defragmenter.h"
00048 #include "mw/afp/defrag/detail/PointerMap.h"
00049 #include "mw/afp/defrag/NoEventSeqHeaderSupport.h"
00050
00051
00052 namespace famouso {
00053 namespace mw {
00054 namespace afp {
00055 namespace defrag {
00056
00057
00061 template <typename DCP, class Subject_t>
00062 struct SubjectDemuxKey {
00063 const Subject_t subject;
00064
00065 enum { uses_subject = 1 };
00066
00067 bool operator<(const SubjectDemuxKey & v2) const {
00068 return subject < v2.subject;
00069 }
00070
00071 bool operator==(const SubjectDemuxKey & v2) const {
00072 return subject == v2.subject;
00073 }
00074
00075 SubjectDemuxKey(const Headers<DCP> & header, const Subject_t & subj) :
00076 subject(subj) {
00077 }
00078 };
00079
00080
00081
00082
00102 template <class DCP>
00103 class MultiSourceDemux {
00104
00105 typedef typename DCP::SizeProp::elen_t elen_t;
00106 typedef typename DCP::SizeProp::flen_t flen_t;
00107 typedef typename DCP::SizeProp::fcount_t fcount_t;
00108
00109 typedef typename DCP::EventDemuxKey KeyType;
00110 typedef typename DCP::Allocator Allocator;
00111
00112 public:
00113
00114 typedef NoEventSeqHeaderSupport<DCP> EventSeqHeaderPolicy;
00115
00116 private:
00117
00122 template <class KeyType>
00123 class Event {
00124
00125 typedef typename DCP::SizeProp::flen_t flen_t;
00126
00127 public:
00129 Defragmenter<DCP> def;
00130
00132 KeyType key;
00133
00135 Event(flen_t max_payload, const KeyType & key)
00136 : def(max_payload), key(key) {
00137 }
00138
00140 ~Event() {
00141 }
00142
00144 const KeyType & get_key() {
00145 return key;
00146 }
00147
00149 void * to_handle() {
00150 return reinterpret_cast<void *>(this);
00151 }
00152
00154 static Event * from_handle(void * handle) {
00155 return reinterpret_cast<Event *>(handle);
00156 }
00157 };
00158
00160 flen_t mtu;
00161
00162 typedef detail::PointerMap < KeyType, Event<KeyType>, DCP::old_event_ids > EventMap;
00163
00165 EventMap events;
00166
00167 public:
00168
00170 MultiSourceDemux(flen_t mtu)
00171 : mtu(mtu) {
00172 }
00173
00175 ~MultiSourceDemux() {
00176 typename EventMap::iterator it = events.begin();
00177 Event<KeyType> * event;
00178 for (; it != events.end(); ++it) {
00179 event = *it;
00180 Allocator::destroy(event);
00181 }
00182 }
00183
00190 void * get_defragmenter_handle(const Headers<DCP> & header, const KeyType & event_key) {
00191 typename EventMap::iterator it = events.find(event_key);
00192 Event<KeyType> * event;
00193
00194
00195 if (header.first_fragment) {
00196
00197
00198
00199
00200
00201
00202
00203 if (it != events.end()) {
00204 free_defragmenter((*it)->to_handle());
00205 }
00206
00207
00208
00209 FAMOUSO_ASSERT(mtu > header.length());
00210 event = new (Allocator()) Event<KeyType>(mtu - header.ext_length(), event_key);
00211
00212 if (!event)
00213 goto out_of_mem_error;
00214 if (!events.insert(event))
00215 goto out_of_mem_error;
00216
00217 ::logging::log::emit< ::logging::Info>()
00218 << PROGMEMSTRING("AFP: defrag fragment ")
00219 << ::logging::log::dec << (unsigned int)header.fseq
00220 << PROGMEMSTRING(" of NEW event")
00221 << ::logging::log::endl;
00222 } else {
00223
00224
00225
00226
00227
00228
00229
00230 if (it == events.end())
00231 return 0;
00232
00233 event = *it;
00234
00235 ::logging::log::emit< ::logging::Info>()
00236 << PROGMEMSTRING("AFP: defrag fragment ")
00237 << ::logging::log::dec << (unsigned int)header.fseq
00238 << PROGMEMSTRING(" of event")
00239 << ::logging::log::endl;
00240 }
00241
00242 return event->to_handle();
00243
00244 out_of_mem_error:
00245 ::logging::log::emit< ::logging::Warning>()
00246 << PROGMEMSTRING("AFP: Out of memory -> drop")
00247 << ::logging::log::endl;
00248 return 0;
00249 }
00250
00252 Defragmenter<DCP> * get_defragmenter(void * handle) {
00253 return & Event<KeyType>::from_handle(handle)->def;
00254 }
00255
00260 void free_defragmenter(void * handle) {
00261 Event<KeyType> * e = Event<KeyType>::from_handle(handle);
00262 events.erase(e->get_key());
00263 Allocator::destroy(e);
00264 }
00265 };
00266
00267
00268 }
00269 }
00270 }
00271 }
00272
00273
00274 #endif // __MULTISOURCEDEMUX_H_2A8B3BD61E7528__
00275