include/trace-tools/wifi/frame/filter/simple_merge.hxx

00001 /*
00002  * trace-tools - 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 "simple_merge.hh"
00026 
00027 # include <trace-tools/prism_header.hh>
00028 # include <trace-tools/wifi/frame/filter/time_adjuster.hh>
00029 
00030 namespace wifi
00031 {
00032   namespace frame
00033   {
00034     namespace filter
00035     {
00036 
00037       namespace internals
00038       {
00039 
00040         template <class HT, class I1, class I2, class B1, class B2>
00041         simple_merge_iterator<HT, I1, I2, B1, B2>::
00042         simple_merge_iterator(const iterable_type& i, bool end):
00043           iterable_ (&i),
00044           next1_ (end ? i.last1_ : i.first1_),
00045           next2_ (end ? i.last2_ : i.first2_),
00046           current_ (first_packet())
00047         {
00048         }
00049 
00050         template <class HT, class I1, class I2, class B1, class B2>
00051         bool
00052         simple_merge_iterator<HT, I1, I2, B1, B2>::
00053         equal(const simple_merge_iterator& rhs) const
00054         {
00055           return next1_ == rhs.next1_ and next2_ == rhs.next2_;
00056         }
00057 
00058         template <class HT, class I1, class I2, class B1, class B2>
00059         void
00060         simple_merge_iterator<HT, I1, I2, B1, B2>::increment()
00061         {
00062           assert(current_ == 0 or current_ == 1);
00063 
00064           if (next1_ == iterable_->last1_)
00065             ++next2_;
00066           else if (next2_ == iterable_->last2_)
00067             ++next1_;
00068           else if (internals::equal<HT>(*next1_, *next2_, iterable_->phy_end_))
00069             {
00070               ++next1_;
00071               ++next2_;
00072             }
00073           else
00074             {
00075               if (current_)
00076                 ++next2_;
00077               else
00078                 ++next1_;
00079             }
00080           current_ = first_packet();
00081         }
00082 
00083         template <class HT, class I1, class I2, class B1, class B2>
00084         const typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type&
00085         simple_merge_iterator<HT, I1, I2, B1, B2>::get() const
00086         {
00087           assert(current_ == 0 or current_ == 1);
00088 
00089           if (current_)
00090             return *next2_;
00091           else
00092             return *next1_;
00093         }
00094 
00095         template <class HT, class I1, class I2, class B1, class B2>
00096         typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type&
00097         simple_merge_iterator<HT, I1, I2, B1, B2>::get()
00098         {
00099           assert(current_ == 0 or current_ == 1);
00100 
00101           if (current_)
00102             return next2_.get();
00103           else
00104             return next1_.get();
00105         }
00106 
00107         template <class HT, class I1, class I2, class B1, class B2>
00108         const typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type*
00109         simple_merge_iterator<HT, I1, I2, B1, B2>::get_ptr() const
00110         {
00111           assert(current_ == 0 or current_ == 1);
00112 
00113           if (current_)
00114             return next2_.get_ptr();
00115           else
00116             return next1_.get_ptr();
00117         }
00118 
00119         template <class HT, class I1, class I2, class B1, class B2>
00120         typename simple_merge_iterator<HT, I1, I2, B1, B2>::value_type*
00121         simple_merge_iterator<HT, I1, I2, B1, B2>::get_ptr()
00122         {
00123           assert(current_ == 0 or current_ == 1);
00124 
00125           if (current_)
00126             return next2_.get_ptr();
00127           else
00128             return next1_.get_ptr();
00129         }
00130 
00131         template <class HT, class I1, class I2, class B1, class B2>
00132         int
00133         simple_merge_iterator<HT, I1, I2, B1, B2>::first_packet() const
00134         {
00135           const bool first_at_end       = next1_ == iterable_->last1_;
00136           const bool second_at_end      = next2_ == iterable_->last2_;
00137 
00138           if (first_at_end)
00139             return second_at_end ? -1 : 1;
00140           if (second_at_end)
00141             return 0;
00142 
00143           return next1_->microseconds() < next2_->microseconds() ? 0 : 1;
00144         }
00145 
00146         template <>
00147         inline
00148         bool
00149         equal<prism::header>(const pcapxx::frame_descriptor&    lhs,
00150                              const pcapxx::frame_descriptor&    rhs,
00151                              tool::endian::endianness           phy_end)
00152         {
00153           using tool::endian::need_swap;
00154 
00155           typedef prism::header         bt;
00156           typedef pcapxx::pkthdr        pt;
00157 
00158           const pt* const lp = lhs.pcap_header().get();
00159           const bool      ls = need_swap(phy_end, lp->swapped);
00160           const bt* const lb = reinterpret_cast<const bt*> (lhs.bytes().get());
00161 
00162           const pt* const rp = rhs.pcap_header().get();
00163           const bool      rs = need_swap(phy_end, rp->swapped);
00164           const bt* const rb = reinterpret_cast<const bt*> (rhs.bytes().get());
00165 
00166           return eq_time_and_80211(lb, lp->caplen, ls,
00167                                    rb, rp->caplen, rs);
00168         }
00169 
00170       } // End of namespace internals.
00171 
00172 
00173       template <class HeaderType,
00174                 class InputIterator1,
00175                 class InputIterator2,
00176                 class Bottom>
00177       simple_merge<HeaderType, InputIterator1, InputIterator2, Bottom>::
00178       simple_merge(const InputIterator1& first1, const InputIterator1& last1,
00179                    const InputIterator2& first2, const InputIterator2& last2,
00180                    tool::endian::endianness     phy_end):
00181         phy_end_ (phy_end),
00182         first1_ (first1),
00183         last1_ (last1),
00184         first2_ (first2),
00185         last2_ (last2)
00186       {
00187       }
00188 
00189       namespace internals
00190       {
00191 
00192         template <class HT, class I, class F>
00193         struct provide_simple_merge
00194         {
00195           provide_simple_merge(const I&                 first1,
00196                                const I&                 last1,
00197                                F&                       func,
00198                                bool                     filter_prism,
00199                                tool::endian::endianness phy_end):
00200             first1_ (first1),
00201             last1_ (last1),
00202             func_ (func),
00203             filter_prism_ (filter_prism),
00204             phy_end_ (phy_end)
00205           {
00206           }
00207 
00208           template <class TimeAdjuster>
00209           void
00210           operator () (const TimeAdjuster& a)
00211           {
00212             if (filter_prism_)
00213               {
00214                 typedef non_noisy_prism<I>                      nnp;
00215                 typedef typename nnp::const_iterator            n_iterator;
00216                 typedef microseconds_stamper<n_iterator, HT>    us_stamper;
00217                 typedef typename us_stamper::const_iterator     u_iterator;
00218                 typedef typename TimeAdjuster::const_iterator   a_iterator;
00219                 typedef simple_merge<HT, u_iterator, a_iterator> merger;
00220 
00221                 nnp             n (first1_, last1_);
00222                 us_stamper      s (n.begin(), n.end(), phy_end_);
00223                 merger          m (s.begin(), s.end(),
00224                                    a.begin(), a.end(), phy_end_);
00225 
00226                 func_(m);
00227               }
00228             else
00229               {
00230                 typedef microseconds_stamper<I, HT>             us_stamper;
00231                 typedef typename us_stamper::const_iterator     u_iterator;
00232                 typedef typename TimeAdjuster::const_iterator   a_iterator;
00233                 typedef simple_merge<HT, u_iterator, a_iterator> merger;
00234 
00235                 us_stamper      s (first1_, last1_, phy_end_);
00236                 merger          m (s.begin(), s.end(),
00237                                    a.begin(), a.end(), phy_end_);
00238 
00239                 func_(m);
00240               }
00241           }
00242 
00243         private:
00244           const I&                      first1_;
00245           const I&                      last1_;
00246           F&                            func_;
00247           bool                          filter_prism_;
00248           tool::endian::endianness      phy_end_;
00249         };
00250 
00251       }
00252 
00253       template <class U, class HT, template <class, class, class> class Int,
00254                 class I1, class I2, class F>
00255       void
00256       provide_simple_merge(const I1& first1, const I1& last1,
00257                            const I2& first2, const I2& last2,
00258                            addr_mapping&                mapping,
00259                            F&                           func,
00260                            bool                         filter_prism,
00261                            tool::endian::endianness     phy_end)
00262       {
00263         internals::provide_simple_merge<HT, I1, F> func2 (first1, last1,
00264                                                           func,
00265                                                           filter_prism,
00266                                                           phy_end);
00267 
00268         provide_time_adjuster<U, HT, Int>(first1, last1,
00269                                           first2, last2,
00270                                           mapping, func2,
00271                                           filter_prism, phy_end);
00272       }
00273 
00274     } // End of namespace wifi::frame::filter.
00275 
00276   } // End of namespace wifi::frame.
00277 
00278 } // End of namespace wifi.
00279 
00280 #endif // ! WIFI_FRAME_FILTER_SIMPLE_MERGE_HXX_

Generated on Tue Nov 13 13:48:01 2007 for trace-tools by  doxygen 1.5.3-20071008