00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_
00023 # define WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_
00024
00025 # include <iostream>
00026
00027 # include "simple_merge.hh"
00028
00029 # include <wipal/wifi/frame/filter/merge.hh>
00030
00031 namespace wifi
00032 {
00033 namespace frame
00034 {
00035 namespace filter
00036 {
00037
00038 namespace internals
00039 {
00040
00041 template <class HT, class I1, class I2, class B1, class B2>
00042 simple_merge_iterator<HT, I1, I2, B1, B2>::
00043 simple_merge_iterator(const iterable_type& i, bool end):
00044 iterable_ (&i),
00045 next1_ (end ? i.last1_ : i.first1_),
00046 next2_ (end ? i.last2_ : i.first2_),
00047 current_ (first_packet())
00048 # ifdef WP_ENABLE_INFO
00049 , lhs_total_ (0),
00050 rhs_total_ (0),
00051 shared_ (0),
00052 total_ (0),
00053 sync_error_ (0)
00054 # endif
00055 {
00056 }
00057
00058
00059 # ifdef WP_ENABLE_INFO
00060 # define WP_increment(X) ++(X)
00061 # else // ! WP_ENABLE_INFO
00062 # define WP_increment(X) (void) 0
00063 # endif // WP_ENABLE_INFO
00064
00065 template <class HT, class I1, class I2, class B1, class B2>
00066 bool
00067 simple_merge_iterator<HT, I1, I2, B1, B2>::
00068 equal(const simple_merge_iterator& rhs) const
00069 {
00070 return next1_ == rhs.next1_ and next2_ == rhs.next2_;
00071 }
00072
00073 template <class HT, class I1, class I2, class B1, class B2>
00074 void
00075 simple_merge_iterator<HT, I1, I2, B1, B2>::increment()
00076 {
00077 typedef internals::equal<HT> equal;
00078
00079 assert(current_ == 0 or current_ == 1);
00080
00081 if (next1_ == iterable_->last1_)
00082 {
00083 ++next2_;
00084 WP_increment(rhs_total_);
00085 }
00086 else if (next2_ == iterable_->last2_)
00087 {
00088 ++next1_;
00089 WP_increment(lhs_total_);
00090 }
00091 else if (equal (*next1_, iterable_->phy_end_) == *next2_)
00092 {
00093 # ifdef WP_ENABLE_INFO
00094 {
00095 const tool::microseconds& t1 = next1_->microseconds();
00096 const tool::microseconds& t2 = next2_->microseconds();
00097
00098 if (t1 > t2)
00099 sync_error_ += tool::microseconds (t1 - t2).get_ui();
00100 else
00101 sync_error_ += tool::microseconds (t2 - t1).get_ui();
00102 }
00103 ++lhs_total_;
00104 ++rhs_total_;
00105 ++shared_;
00106 # endif // WP_ENABLE_INFO
00107 ++next1_;
00108 ++next2_;
00109 }
00110 else
00111 {
00112 if (current_)
00113 {
00114 ++next2_;
00115 WP_increment(rhs_total_);
00116 }
00117 else
00118 {
00119 ++next1_;
00120 WP_increment(lhs_total_);
00121 }
00122 }
00123 WP_increment(total_);
00124
00125 current_ = first_packet();
00126
00127 # ifdef WP_ENABLE_INFO
00128 if (current_ == -1)
00129 std::cerr << "INFO: " << shared_ << " frames shared by"
00130 " both traces.\n"
00131 << "INFO: Trace 1 has " << lhs_total_ << " frames ("
00132 << (shared_ * 100.f / lhs_total_) << "% shared).\n"
00133 << "INFO: Trace 2 has " << rhs_total_ << " frames ("
00134 << (shared_ * 100.f / rhs_total_) << "% shared).\n"
00135 << "INFO: Output has " << total_ << " frames ("
00136 << (shared_ * 100.f / total_) << "% shared).\n"
00137 << "INFO: Mean sync. error is "
00138 << (sync_error_ / shared_) << " microseconds."
00139 << std::endl;
00140 # endif // WP_ENABLE_INFO
00141 }
00142
00143 # undef WP_increment
00144
00145 template <class HT, class I1, class I2, class B1, class B2>
00146 const typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type&
00147 simple_merge_iterator<HT, I1, I2, B1, B2>::get() const
00148 {
00149 assert(current_ == 0 or current_ == 1);
00150
00151 if (current_)
00152 return *next2_;
00153 else
00154 return *next1_;
00155 }
00156
00157 template <class HT, class I1, class I2, class B1, class B2>
00158 typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type&
00159 simple_merge_iterator<HT, I1, I2, B1, B2>::get()
00160 {
00161 assert(current_ == 0 or current_ == 1);
00162
00163 if (current_)
00164 return next2_.get();
00165 else
00166 return next1_.get();
00167 }
00168
00169 template <class HT, class I1, class I2, class B1, class B2>
00170 const typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type*
00171 simple_merge_iterator<HT, I1, I2, B1, B2>::get_ptr() const
00172 {
00173 assert(current_ == 0 or current_ == 1);
00174
00175 if (current_)
00176 return next2_.get_ptr();
00177 else
00178 return next1_.get_ptr();
00179 }
00180
00181 template <class HT, class I1, class I2, class B1, class B2>
00182 typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type*
00183 simple_merge_iterator<HT, I1, I2, B1, B2>::get_ptr()
00184 {
00185 assert(current_ == 0 or current_ == 1);
00186
00187 if (current_)
00188 return next2_.get_ptr();
00189 else
00190 return next1_.get_ptr();
00191 }
00192
00193 template <class HT, class I1, class I2, class B1, class B2>
00194 int
00195 simple_merge_iterator<HT, I1, I2, B1, B2>::first_packet() const
00196 {
00197 const bool first_at_end = next1_ == iterable_->last1_;
00198 const bool second_at_end = next2_ == iterable_->last2_;
00199
00200 if (first_at_end)
00201 return second_at_end ? -1 : 1;
00202 if (second_at_end)
00203 return 0;
00204
00205 return next1_->microseconds() < next2_->microseconds() ? 0 : 1;
00206 }
00207
00208 }
00209
00210 template <class HeaderType,
00211 class InputIterator1,
00212 class InputIterator2,
00213 class Bottom>
00214 simple_merge<HeaderType, InputIterator1, InputIterator2, Bottom>::
00215 simple_merge(const InputIterator1& first1, const InputIterator1& last1,
00216 const InputIterator2& first2, const InputIterator2& last2,
00217 tool::endian::endianness phy_end):
00218 phy_end_ (phy_end),
00219 first1_ (first1),
00220 last1_ (last1),
00221 first2_ (first2),
00222 last2_ (last2)
00223 {
00224 }
00225
00226 }
00227
00228 }
00229
00230 }
00231
00232 #endif // ! WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_