00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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 }
00046
00047
00048
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
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
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
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
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
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
00257
00258
00259 template <class Self>
00260 void
00261 Data_<Self>::use()
00262 {
00263 if (data_) {
00264
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
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
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 }
00331
00332 }
00333
00334 #endif // ! QOLYESTER_UTL_DATA_HXX