00001
00002
00003
00004
00005
00006
00007
00008 #include "dds/DCPS/ReceivedDataElementList.h"
00009 #include "dds/DCPS/DataReaderImpl.h"
00010 #include "ace/Truncate.h"
00011
00012 #include <utility>
00013 #include <algorithm>
00014
00015 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00016
00017 namespace TAO {
00018 namespace DCPS {
00019
00020
00021
00022 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00023 ZeroCopyDataSeq<Sample_T, DEF_MAX>::ZeroCopyVector::ZeroCopyVector(
00024 const size_t init_size,
00025 ACE_Allocator* alloc)
00026 : ACE_Vector<OpenDDS::DCPS::ReceivedDataElement*, DEF_MAX> (init_size, alloc)
00027 {
00028 }
00029
00030 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00031 void
00032 ZeroCopyDataSeq<Sample_T, DEF_MAX>::ZeroCopyVector::swap(ZeroCopyVector& rhs)
00033 {
00034
00035
00036 ACE_Array<OpenDDS::DCPS::ReceivedDataElement*>::swap(rhs);
00037 std::swap(this->length_, rhs.length_);
00038 std::swap(this->curr_max_size_, rhs.curr_max_size_);
00039 }
00040
00041
00042
00043 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00044 ZeroCopyDataSeq<Sample_T, DEF_MAX>::ZeroCopyDataSeq(
00045 CORBA::ULong maximum ,
00046 CORBA::ULong init_size ,
00047 ACE_Allocator* alloc )
00048 : loaner_(0)
00049 , ptrs_((maximum == 0) ? init_size : 0
00050 , alloc ? alloc : &default_allocator_)
00051 , sc_maximum_(maximum)
00052 , sc_length_(0)
00053 , sc_buffer_(sc_maximum_ ? allocbuf(sc_maximum_) : 0)
00054 , sc_release_(sc_maximum_)
00055 {
00056 }
00057
00058 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00059 ZeroCopyDataSeq<Sample_T, DEF_MAX>::ZeroCopyDataSeq(
00060 CORBA::ULong maximum,
00061 CORBA::ULong length,
00062 Sample_T* buffer,
00063 CORBA::Boolean release )
00064 : loaner_(0)
00065 , ptrs_(0)
00066 , sc_maximum_(maximum)
00067 , sc_length_(length)
00068 , sc_buffer_(buffer)
00069 , sc_release_(release)
00070 {
00071 }
00072
00073 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00074 ZeroCopyDataSeq<Sample_T, DEF_MAX>&
00075 ZeroCopyDataSeq<Sample_T, DEF_MAX>::operator=(
00076 const ZeroCopyDataSeq& frm)
00077 {
00078 if (this != &frm) {
00079 ZeroCopyDataSeq<Sample_T, DEF_MAX> temp(frm);
00080 swap(temp);
00081 }
00082
00083 return *this;
00084 }
00085
00086 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00087 void
00088 ZeroCopyDataSeq<Sample_T, DEF_MAX>::swap(ZeroCopyDataSeq& frm)
00089 {
00090 bool thisUsedDefAlloc = ptrs_.allocator_ == &default_allocator_;
00091 bool thisUsedLocalBuffer = ptrs_.array_ == default_allocator_.pool();
00092 bool frmUsedDefAlloc = frm.ptrs_.allocator_ == &frm.default_allocator_;
00093 bool frmUsedLocalBuffer = frm.ptrs_.array_ == frm.default_allocator_.pool();
00094
00095 std::swap(loaner_, frm.loaner_);
00096 std::swap(default_allocator_, frm.default_allocator_);
00097 ptrs_.swap(frm.ptrs_);
00098 std::swap(sc_maximum_, frm.sc_maximum_);
00099 std::swap(sc_length_, frm.sc_length_);
00100 std::swap(sc_buffer_, frm.sc_buffer_);
00101 std::swap(sc_release_, frm.sc_release_);
00102
00103 if (thisUsedDefAlloc) frm.ptrs_.allocator_ = &frm.default_allocator_;
00104
00105 if (thisUsedLocalBuffer) frm.ptrs_.array_ = frm.default_allocator_.pool();
00106
00107 if (frmUsedDefAlloc) ptrs_.allocator_ = &default_allocator_;
00108
00109 if (frmUsedLocalBuffer) ptrs_.array_ = default_allocator_.pool();
00110 }
00111
00112 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00113 ZeroCopyDataSeq<Sample_T, DEF_MAX>::~ZeroCopyDataSeq()
00114 {
00115 if (loaner_) loaner_->auto_return_loan(this);
00116
00117 if (sc_release_ && sc_buffer_) freebuf(sc_buffer_);
00118 }
00119
00120 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00121 bool
00122 ZeroCopyDataSeq<Sample_T, DEF_MAX>::is_zero_copy() const
00123 {
00124 return sc_maximum_ == 0;
00125 }
00126
00127 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00128 CORBA::ULong
00129 ZeroCopyDataSeq<Sample_T, DEF_MAX>::maximum() const
00130 {
00131 return sc_maximum_;
00132 }
00133
00134 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00135 CORBA::ULong
00136 ZeroCopyDataSeq<Sample_T, DEF_MAX>::max_slots() const
00137 {
00138 return is_zero_copy() ? static_cast<CORBA::ULong>(ptrs_.max_size())
00139 : sc_maximum_;
00140 }
00141
00142 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00143 CORBA::ULong
00144 ZeroCopyDataSeq<Sample_T, DEF_MAX>::length() const
00145 {
00146 return is_zero_copy() ? static_cast<CORBA::ULong>(ptrs_.size()) : sc_length_;
00147 }
00148
00149 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00150 const Sample_T&
00151 ZeroCopyDataSeq<Sample_T, DEF_MAX>::operator[](CORBA::ULong i) const
00152 {
00153 if (is_zero_copy()) {
00154 if (ptrs_[i]->registered_data_) {
00155 return *static_cast<const Sample_T*>(ptrs_[i]->registered_data_);
00156 }
00157 return default_;
00158
00159 } else {
00160 return sc_buffer_[i];
00161 }
00162 }
00163
00164 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00165 Sample_T&
00166 ZeroCopyDataSeq<Sample_T, DEF_MAX>::operator[](CORBA::ULong i)
00167 {
00168 if (is_zero_copy()) {
00169 if (ptrs_[i]->registered_data_) {
00170 return *static_cast<Sample_T*>(ptrs_[i]->registered_data_);
00171 }
00172 return default_;
00173
00174 } else {
00175 return sc_buffer_[i];
00176 }
00177 }
00178
00179 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00180 CORBA::Boolean
00181 ZeroCopyDataSeq<Sample_T, DEF_MAX>::release() const
00182 {
00183 return sc_release_;
00184 }
00185
00186 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00187 void
00188 ZeroCopyDataSeq<Sample_T, DEF_MAX>::replace(
00189 CORBA::ULong maximum,
00190 CORBA::ULong length,
00191 Sample_T* buffer,
00192 CORBA::Boolean release )
00193 {
00194 ZeroCopyDataSeq<Sample_T, DEF_MAX> newOne(maximum, length, buffer, release);
00195 swap(newOne);
00196 }
00197
00198 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00199 void
00200 ZeroCopyDataSeq<Sample_T, DEF_MAX>::make_single_copy(CORBA::ULong maximum)
00201 {
00202 CORBA::ULong currentSize(static_cast<CORBA::ULong>(ptrs_.size()));
00203 ZeroCopyDataSeq<Sample_T, DEF_MAX> sc((std::max)(maximum, currentSize));
00204 sc.length(currentSize);
00205
00206 for (CORBA::ULong i(0); i < ptrs_.size(); ++i) {
00207 sc[i] = (*this)[i];
00208 }
00209
00210 swap(sc);
00211 }
00212
00213 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00214 const Sample_T*
00215 ZeroCopyDataSeq<Sample_T, DEF_MAX>::get_buffer() const
00216 {
00217
00218
00219
00220 if (is_zero_copy())
00221 const_cast<ZeroCopyDataSeq*>(this)->make_single_copy(max_slots());
00222
00223 if (!sc_buffer_) {
00224 sc_buffer_ = allocbuf(sc_maximum_);
00225 sc_release_ = true;
00226 }
00227
00228 return sc_buffer_;
00229 }
00230
00231
00232 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00233 Sample_T*
00234 ZeroCopyDataSeq<Sample_T, DEF_MAX>::allocbuf(CORBA::ULong nelems)
00235 {
00236 return new Sample_T[nelems];
00237 }
00238
00239
00240 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00241 void
00242 ZeroCopyDataSeq<Sample_T, DEF_MAX>::freebuf(Sample_T* buffer)
00243 {
00244 delete[] buffer;
00245 }
00246
00247 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00248 void
00249 ZeroCopyDataSeq<Sample_T, DEF_MAX>::internal_set_length(CORBA::ULong len)
00250 {
00251 if (!is_zero_copy() || len < ptrs_.size()) {
00252 length(len);
00253
00254 } else if (len > ptrs_.size()) {
00255
00256 ptrs_.resize((std::max)(len, CORBA::ULong(ptrs_.size()) * 2), 0);
00257
00258 ptrs_.resize(len, 0);
00259 }
00260 }
00261
00262 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00263 void
00264 ZeroCopyDataSeq<Sample_T, DEF_MAX>::set_loaner(
00265 OpenDDS::DCPS::DataReaderImpl* loaner)
00266 {
00267 loaner_ = loaner;
00268 }
00269
00270 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00271 void
00272 ZeroCopyDataSeq<Sample_T, DEF_MAX>::assign_ptr(
00273 CORBA::ULong ii,
00274 OpenDDS::DCPS::ReceivedDataElement* item)
00275 {
00276 ACE_ASSERT(is_zero_copy());
00277 item->inc_ref();
00278 ++item->zero_copy_cnt_;
00279 ptrs_[ii] = item;
00280 }
00281
00282 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00283 OpenDDS::DCPS::ReceivedDataElement*
00284 ZeroCopyDataSeq<Sample_T, DEF_MAX>::get_ptr(CORBA::ULong ii) const
00285 {
00286 ACE_ASSERT(is_zero_copy());
00287 return ptrs_[ii];
00288 }
00289
00290 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
00291 void
00292 ZeroCopyDataSeq<Sample_T, DEF_MAX>::assign_sample(
00293 CORBA::ULong ii, const Sample_T& sample)
00294 {
00295 ACE_ASSERT(!is_zero_copy());
00296 sc_buffer_[ii] = sample;
00297 }
00298
00299 }
00300 }
00301
00302 TAO_END_VERSIONED_NAMESPACE_DECL