OpenDDS  Snapshot(2023/04/28-20:55)
ZeroCopySeq_T.inl
Go to the documentation of this file.
1 /*
2  *
3  *
4  * Distributed under the OpenDDS License.
5  * See: http://www.opendds.org/license.html
6  */
7 
9 
10 #include <ace/Truncate.h>
11 
12 #include <utility>
13 #include <algorithm>
14 
16 
17 namespace TAO {
18 namespace DCPS {
19 
20 //ZeroCopyVector implementation
21 
22 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
24  const size_t init_size,
25  ACE_Allocator* alloc)
26  : ACE_Vector<OpenDDS::DCPS::ReceivedDataElement*, DEF_MAX> (init_size, alloc)
27 {
28 }
29 
30 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
31 void
33 {
34  // Later versions of ACE do have a working ACE_Vector<T,MAX>::swap so we must
35  // delegate up to ACE_Array<T> to get consistent swap behavior.
37  std::swap(this->length_, rhs.length_);
39 }
40 
41 //ZeroCopyDataSeq implementation
42 
43 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
45  CORBA::ULong maximum /* = 0 */,
46  CORBA::ULong init_size /* = DEF_MAX */,
47  ACE_Allocator* alloc /* = 0 */)
48  : loaner_(0)
49  , ptrs_((maximum == 0) ? init_size : 0
50  , alloc ? alloc : &default_allocator_)
51  , sc_maximum_(maximum)
52  , sc_length_(0)
55 {
56 }
57 
58 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
62  Sample_T* buffer,
63  CORBA::Boolean release /* = false */)
64  : loaner_(0)
65  , ptrs_(0)
66  , sc_maximum_(maximum)
67  , sc_length_(length)
68  , sc_buffer_(buffer)
69  , sc_release_(release)
70 {
71 }
72 
73 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
76  const ZeroCopyDataSeq& frm)
77 {
78  if (this != &frm) {
80  swap(temp);
81  }
82 
83  return *this;
84 }
85 
86 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
87 void
89 {
90  bool thisUsedDefAlloc = ptrs_.allocator_ == &default_allocator_;
91  bool thisUsedLocalBuffer = ptrs_.array_ == default_allocator_.pool();
92  bool frmUsedDefAlloc = frm.ptrs_.allocator_ == &frm.default_allocator_;
93  bool frmUsedLocalBuffer = frm.ptrs_.array_ == frm.default_allocator_.pool();
94 
97  ptrs_.swap(frm.ptrs_);
102 
103  if (thisUsedDefAlloc) frm.ptrs_.allocator_ = &frm.default_allocator_;
104 
105  if (thisUsedLocalBuffer) frm.ptrs_.array_ = frm.default_allocator_.pool();
106 
107  if (frmUsedDefAlloc) ptrs_.allocator_ = &default_allocator_;
108 
109  if (frmUsedLocalBuffer) ptrs_.array_ = default_allocator_.pool();
110 }
111 
112 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
114 {
115  if (!this->release())
116  {
117  this->length(0);
118  }
119 
121 }
122 
123 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
124 bool
126 {
127  return sc_maximum_ == 0;
128 }
129 
130 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
133 {
134  return sc_maximum_;
135 }
136 
137 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
140 {
141  return is_zero_copy() ? static_cast<CORBA::ULong>(ptrs_.max_size())
142  : sc_maximum_;
143 }
144 
145 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
148 {
149  return is_zero_copy() ? static_cast<CORBA::ULong>(ptrs_.size()) : sc_length_;
150 }
151 
152 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
153 const Sample_T&
155 {
156  if (is_zero_copy()) {
157  if (ptrs_[i]->registered_data_) {
158  return *static_cast<const Sample_T*>(ptrs_[i]->registered_data_);
159  }
160  return default_;
161 
162  } else {
163  return sc_buffer_[i];
164  }
165 }
166 
167 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
168 Sample_T&
170 {
171  if (is_zero_copy()) {
172  if (ptrs_[i]->registered_data_) {
173  return *static_cast<Sample_T*>(ptrs_[i]->registered_data_);
174  }
175  return default_;
176 
177  } else {
178  return sc_buffer_[i];
179  }
180 }
181 
182 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
185 {
186  return sc_release_; //will always be false in zero-copy mode
187 }
188 
189 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
190 void
194  Sample_T* buffer,
195  CORBA::Boolean release /* = false */)
196 {
197  ZeroCopyDataSeq<Sample_T, DEF_MAX> newOne(maximum, length, buffer, release);
198  swap(newOne);
199 }
200 
201 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
202 void
204 {
205  CORBA::ULong currentSize(static_cast<CORBA::ULong>(ptrs_.size()));
206  ZeroCopyDataSeq<Sample_T, DEF_MAX> sc((std::max)(maximum, currentSize));
207  sc.length(currentSize);
208 
209  for (CORBA::ULong i(0); i < ptrs_.size(); ++i) {
210  sc[i] = (*this)[i];
211  }
212 
213  swap(sc);
214 }
215 
216 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
217 const Sample_T*
219 {
220  //If we're currently zero-copy we must become single copy in order to return
221  //a contiguous buffer. The only way to do this and meet the CORBA/C++ spec
222  //interface is to cast-away the constness.
223  if (is_zero_copy())
224  const_cast<ZeroCopyDataSeq*>(this)->make_single_copy(max_slots());
225 
226  if (!sc_buffer_) {
228  sc_release_ = true;
229  }
230 
231  return sc_buffer_;
232 }
233 
234 /*static*/
235 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
236 Sample_T*
238 {
239  return new Sample_T[nelems];
240 }
241 
242 /*static*/
243 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
244 void
246 {
247  delete[] buffer;
248 }
249 
250 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
251 void
253 {
254  if (!is_zero_copy() || len < ptrs_.size()) {
255  length(len);
256 
257  } else if (len > ptrs_.size()) {
258  //We need the vector to grow efficiently (not reallocate on each call)...
259  ptrs_.resize((std::max)(len, CORBA::ULong(ptrs_.size()) * 2), 0);
260  //...but maintain the invariant that the size of ptrs_ is our length
261  ptrs_.resize(len, 0);
262  }
263 }
264 
265 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
266 void
269 {
270  loaner_ = loaner;
271 }
272 
273 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
274 void
276  CORBA::ULong ii,
278 {
280  if (ptrs_[ii]) {
281  --ptrs_[ii]->zero_copy_cnt_;
282  ptrs_[ii]->dec_ref();
283  }
284 
285  item->inc_ref();
286  ++item->zero_copy_cnt_;
287  ptrs_[ii] = item;
288 }
289 
290 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
293 {
295  return ptrs_[ii];
296 }
297 
298 template <class Sample_T, size_t DEF_MAX> ACE_INLINE
299 void
301  CORBA::ULong ii, const Sample_T& sample)
302 {
304  sc_buffer_[ii] = sample;
305 }
306 
307 } // namespace DCPS
308 } // namespace TAO
309 
void swap(MessageBlock &lhs, MessageBlock &rhs)
size_type max_size(void) const
#define TAO_BEGIN_VERSIONED_NAMESPACE_DECL
const Sample_T & operator[](CORBA::ULong i) const
ZeroCopyDataSeq & operator=(const ZeroCopyDataSeq &frm)
size_t size(void) const
CORBA::ULong length() const
CORBA::ULong max_slots() const
CORBA::Boolean release() const
#define OPENDDS_ASSERT(C)
Definition: Definitions.h:72
void swap(ACE_Array_Base< T > &array)
Ptr_Seq_Type ptrs_
array of pointers if the sequence is supporting zero-copy reads
ACE_CDR::ULong ULong
void assign_ptr(CORBA::ULong ii, OpenDDS::DCPS::ReceivedDataElement *item)
ACE_CDR::Boolean Boolean
void swap(ZeroCopyDataSeq &frm)
OpenDDS::DCPS::DataReaderImpl * loaner_
The loaner that loaned its samples.
OpenDDS::DCPS::ReceivedDataElement * get_ptr(CORBA::ULong ii) const
Implements the DDS::DataReader interface.
ACE_Allocator * allocator_
void make_single_copy(CORBA::ULong maximum)
static Sample_T * allocbuf(CORBA::ULong nelems)
void replace(CORBA::ULong max, CORBA::ULong length, Sample_T *buffer, CORBA::Boolean release=false)
static void freebuf(Sample_T *buffer)
const Sample_T * get_buffer() const
ZeroCopyDataSeq(CORBA::ULong maximum=0, CORBA::ULong init_size=DEF_MAX, ACE_Allocator *alloc=0)
ZeroCopyVector(const size_t init_size=DEF_MAX, ACE_Allocator *alloc=0)
void assign_sample(CORBA::ULong ii, const Sample_T &sample)
CORBA::ULong maximum() const
#define ACE_INLINE
void internal_set_length(CORBA::ULong len)
void length(CORBA::ULong length)
#define TAO_END_VERSIONED_NAMESPACE_DECL
void resize(const size_t new_size, const T &t)
void set_loaner(OpenDDS::DCPS::DataReaderImpl *loaner)
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
value_type * array_
OpenDDS::DCPS::FirstTimeFastAllocator< OpenDDS::DCPS::ReceivedDataElement *, DEF_MAX > default_allocator_
the default allocator