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