data.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester 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, MA  02110-1301, USA.
00018 
00019 #ifndef QOLYESTER_UTL_DATA_HXX
00020 # define QOLYESTER_UTL_DATA_HXX 1
00021 
00022 # include <iostream>
00023 # include "data.hh"
00024 # include "meta.hh"
00025 
00026 namespace olsr {
00027 
00028   namespace utl {
00029 
00030     /*--------------.
00031     | shared_data.  |
00032     `--------------*/
00033 
00034     namespace internal {
00035 
00036       shared_data::shared_data(unsigned usecount,
00037                                u_int8_t* buffer,
00038                                ::size_t size)
00039         : usecount (usecount),
00040           buffer (buffer),
00041           size (size)
00042       {
00043       }
00044 
00045     } // End of namespace internal.
00046 
00047     /*------------------------------.
00048     | Constructors and destructor.  |
00049     `------------------------------*/
00050 
00051     template <class Self>
00052     Data_<Self>::Data_()
00053       : data_ (0),
00054         instance_size_ (0),
00055         offset_ (0)
00056     {
00057     }
00058 
00059     template <class Self>
00060     Data_<Self>::Data_(const ::size_t size)
00061       : data_ (new internal::shared_data (1, new u_int8_t[size], size)),
00062         instance_size_ (size),
00063         offset_ (0)
00064     {
00065     }
00066 
00067     template <class Self>
00068     Data_<Self>::Data_(const Data_& other)
00069       : data_ (other.data_),
00070         instance_size_ (other.instance_size_),
00071         offset_ (other.offset_)
00072     {
00073       assert(not data_ or data_->buffer and data_->usecount);
00074       use();
00075     }
00076 
00077     template <class Self>
00078     template <class T>
00079     Data_<Self>::Data_(const Data_<T>& other)
00080       : data_ (other.data_),
00081         instance_size_ (other.instance_size_),
00082         offset_ (other.offset_)
00083     {
00084       i_static_assert(internal::convert<T, Self>::valid);
00085       assert(not data_ or data_->buffer and data_->usecount);
00086       use();
00087     }
00088 
00089     template <class Self>
00090     Data_<Self>::~Data_()
00091     {
00092       unuse();
00093     }
00094 
00095     /*--------------.
00096     | Affectation.  |
00097     `--------------*/
00098 
00099     template <class Self>
00100     template <class T>
00101     Self&
00102     Data_<Self>::operator = (const Data_<T>& other)
00103     {
00104       i_static_assert(internal::convert<T, Self>::valid);
00105 
00106       if (static_cast<const void*> (&other) != this) {
00107         unuse();
00108 
00109         data_ = other.data_;
00110         offset_ = other.offset_;
00111         instance_size_ = other.instance_size_;
00112 
00113         use();
00114       }
00115 
00116       assert(not data_ or data_->buffer and data_->usecount);
00117 
00118       return exact();
00119     }
00120 
00121     template <class Self>
00122     Self&
00123     Data_<Self>::operator = (const Data_<Self>& other)
00124     {
00125       return operator=<Self>(other);
00126     }
00127 
00128     /*----------------.
00129     | Misc. methods.  |
00130     `----------------*/
00131 
00132     template <class Self>
00133     bool
00134     Data_<Self>::empty() const
00135     {
00136       return data_ == 0;
00137     }
00138 
00139     template <class Self>
00140     ::size_t
00141     Data_<Self>::size() const
00142     {
00143       return instance_size_;
00144     }
00145 
00146     /*-------------------.
00147     | Resizing methods.  |
00148     `-------------------*/
00149 
00150     template <class Self>
00151     void
00152     Data_<Self>::fit(unsigned len)
00153     {
00154       assert(offset_ + len <= data_->size);
00155       instance_size_ = len;
00156     }
00157 
00158     template <class Self>
00159     Self
00160     Data_<Self>::shrink_by(unsigned len) const
00161     {
00162       assert(len <= instance_size_);
00163 
00164       Self      tmp (exact());
00165       tmp.instance_size_ -= len;
00166       return tmp;
00167     }
00168 
00169     template <class Self>
00170     Self
00171     Data_<Self>::shrink_to(unsigned len) const
00172     {
00173       Self      tmp (exact());
00174       tmp.fit(len);
00175       return tmp;
00176     }
00177 
00178     template <class Self>
00179     Self
00180     Data_<Self>::operator + (unsigned offset) const
00181     {
00182       Self      tmp (exact());
00183       tmp += offset;
00184       return tmp;
00185     }
00186 
00187     template <class Self>
00188     Self&
00189     Data_<Self>::operator += (unsigned offset)
00190     {
00191       assert(offset_ + offset <= data_->size);
00192 
00193       offset_ += offset;
00194       instance_size_ -= offset;
00195       return exact();
00196     }
00197 
00198     template <class Self>
00199     template <class T>
00200     ::size_t
00201     Data_<Self>::operator - (const Data_<T>& rhs) const
00202     {
00203       assert(rhs.instance_size_ <= instance_size_);
00204 
00205       return instance_size_ - rhs.instance_size_;
00206     }
00207 
00208     /*-------------.
00209     | Raw access.  |
00210     `-------------*/
00211 
00212     template <class Self>
00213     const u_int8_t*
00214     Data_<Self>::raw() const
00215     {
00216       return data_->buffer + offset_;
00217     }
00218 
00219     template <class Self>
00220     void
00221     Data_<Self>::dump(u_int8_t* p) const
00222     {
00223       memcpy(p, data_->buffer + offset_, instance_size_);
00224     }
00225 
00226     template <class Self>
00227     void
00228     Data_<Self>::dump(Data_<Data>& d) const
00229     {
00230       assert(d.instance_size_ >= instance_size_);
00231 
00232       memcpy(d.data_->buffer + d.offset_,
00233              data_->buffer + offset_,
00234              instance_size_);
00235     }
00236 
00237     /*----------.
00238     | exact().  |
00239     `----------*/
00240 
00241     template <class Self>
00242     Self&
00243     Data_<Self>::exact()
00244     {
00245       return *static_cast<Self*> (this);
00246     }
00247 
00248     template <class Self>
00249     const Self&
00250     Data_<Self>::exact() const
00251     {
00252       return *static_cast<const Self*> (this);
00253     }
00254 
00255     /*------------------.
00256     | Private methods.  |
00257     `------------------*/
00258 
00259     template <class Self>
00260     void
00261     Data_<Self>::use()
00262     {
00263       if (data_) {
00264         // Avoid wrap-around conditions.
00265         assert(data_->usecount < std::numeric_limits<unsigned>::max());
00266         ++data_->usecount;
00267       }
00268     }
00269 
00270     template <class Self>
00271     void
00272     Data_<Self>::unuse()
00273     {
00274       if (data_) {
00275         assert(data_->usecount);
00276         if (not --data_->usecount) {
00277           delete[] data_->buffer;
00278           delete data_;
00279           data_ = 0;
00280         }
00281       }
00282     }
00283 
00284     /*-------.
00285     | Data.  |
00286     `-------*/
00287 
00288     inline
00289     Data::Data() : Data_<Data> ()
00290     {
00291     }
00292 
00293     inline
00294     Data::Data(::size_t size) : Data_<Data> (size)
00295     {
00296     }
00297 
00298     inline
00299     u_int8_t*
00300     Data::raw()
00301     {
00302       return data_->buffer + offset_;
00303     }
00304 
00305     /*------------.
00306     | ConstData.  |
00307     `------------*/
00308 
00309     inline
00310     ConstData::ConstData() : Data_<ConstData> ()
00311     {
00312     }
00313 
00314     inline
00315     ConstData::ConstData(::size_t size) : Data_<ConstData> (size)
00316     {
00317     }
00318 
00319     ConstData::ConstData(const Data& d) : Data_<ConstData> (d)
00320     {
00321     }
00322 
00323     inline
00324     ConstData&
00325     ConstData::operator = (const Data& d)
00326     {
00327       return Data_<ConstData>::operator = (d);
00328     }
00329 
00330   } // namespace utl
00331 
00332 } // namespace olsr
00333 
00334 #endif // ! QOLYESTER_UTL_DATA_HXX

Generated on Mon Sep 10 17:02:11 2007 for Qolyester daemon by  doxygen 1.5.1