include/wipal/wifi/frame/filter/simple_merge.hxx

00001 /*
00002  * WiPal - A library and a set of tools to manipulate wireless traces.
00003  * Copyright (C) 2007  Universite Pierre et Marie Curie - Paris 6
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  * MA  02110-1301  USA
00019  *
00020  * Author: Thomas Claveirole <thomas.claveirole@lip6.fr>
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 ENABLE_INFO
00049         , lhs_total_ (0),
00050           rhs_total_ (0),
00051           shared_ (0),
00052           total_ (0),
00053           sync_error_ (0)
00054 # endif // ENABLE_INFO
00055         {
00056         }
00057 
00058 
00059 # ifdef ENABLE_INFO
00060 #  define wp_increment(X) ++(X)
00061 # else // ! ENABLE_INFO
00062 #  define wp_increment(X) (void) 0
00063 # endif // 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 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_ += mpz_class (t1 - t2).get_ui();
00100                 else
00101                   sync_error_ += mpz_class (t2 - t1).get_ui();
00102               }
00103               ++lhs_total_;
00104               ++rhs_total_;
00105               ++shared_;
00106 # endif // 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 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 // 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       } // End of namespace internals.
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     } // End of namespace wifi::frame::filter.
00227 
00228   } // End of namespace wifi::frame.
00229 
00230 } // End of namespace wifi.
00231 
00232 #endif // ! WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_

Generated on Wed Jan 16 16:15:14 2008 for wipal by  doxygen 1.5.4