00001 #ifndef guard_unbounded_octet_sequence_hpp
00002 #define guard_unbounded_octet_sequence_hpp
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "tao/orbconf.h"
00013
00014 #include "tao/Unbounded_Value_Sequence_T.h"
00015 #include "ace/OS_NS_string.h"
00016
00017 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00018
00019 #include "tao/TAO_Export.h"
00020 #include "tao/Unbounded_Value_Allocation_Traits_T.h"
00021 #include "tao/Value_Traits_T.h"
00022 #include "tao/Range_Checking_T.h"
00023
00024 #include "tao/Basic_Types.h"
00025 #include "ace/Message_Block.h"
00026 #include "ace/OS_Memory.h"
00027 #include "ace/checked_iterator.h"
00028
00029 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00030
00031 namespace TAO
00032 {
00033 template<>
00034 class TAO_Export unbounded_value_sequence<CORBA::Octet>
00035 {
00036 public:
00037 typedef CORBA::Octet value_type;
00038 typedef CORBA::Octet element_type;
00039 typedef CORBA::Octet const const_value_type;
00040 typedef value_type & subscript_type;
00041 typedef value_type const & const_subscript_type;
00042 typedef ::CORBA::ULong size_type;
00043
00044 typedef details::unbounded_value_allocation_traits<value_type,true> allocation_traits;
00045 typedef details::value_traits<value_type,true> element_traits;
00046 typedef details::generic_sequence<value_type, allocation_traits, element_traits> implementation_type;
00047 typedef details::range_checking<value_type,true> range;
00048
00049 inline unbounded_value_sequence<CORBA::Octet>()
00050 : maximum_ (allocation_traits::default_maximum())
00051 , length_ (0)
00052 , buffer_ (allocation_traits::default_buffer_allocation())
00053 , release_ (buffer_ != 0)
00054 , mb_ (0)
00055 {}
00056 inline explicit unbounded_value_sequence<CORBA::Octet>(CORBA::ULong maximum)
00057 : maximum_(maximum)
00058 , length_(0)
00059 , buffer_(allocbuf(maximum_))
00060 , release_(true)
00061 , mb_ (0)
00062 {}
00063 inline unbounded_value_sequence<CORBA::Octet>(
00064 CORBA::ULong maximum,
00065 CORBA::ULong length,
00066 value_type * data,
00067 CORBA::Boolean release = false)
00068 : maximum_ (maximum),
00069 length_ (length),
00070 buffer_ (data),
00071 release_ (release),
00072 mb_ (0)
00073 {}
00074 inline ~unbounded_value_sequence<CORBA::Octet>() {
00075 if (mb_)
00076 ACE_Message_Block::release (mb_);
00077 if (release_)
00078 freebuf(buffer_);
00079 }
00080
00081
00082 inline unbounded_value_sequence<CORBA::Octet> (CORBA::ULong length,
00083 const ACE_Message_Block* mb)
00084 : maximum_ (length)
00085 , length_ (length)
00086 , buffer_ (reinterpret_cast <CORBA::Octet *>(mb->rd_ptr ()))
00087 , release_ (false)
00088 , mb_(0) {
00089
00090 ACE_Message_Block::Message_Flags const flg = mb->self_flags ();
00091
00092
00093
00094
00095
00096
00097 if (ACE_BIT_DISABLED (flg,
00098 ACE_Message_Block::DONT_DELETE))
00099 {
00100 this->mb_ = ACE_Message_Block::duplicate (mb);
00101 }
00102 else
00103 {
00104
00105
00106 ACE_Message_Block msgb (*mb, ACE_CDR::MAX_ALIGNMENT);
00107
00108
00109 char *start = ACE_ptr_align_binary (mb->base (),
00110 ACE_CDR::MAX_ALIGNMENT);
00111
00112
00113 size_t const rd_pos = mb->rd_ptr () - start;
00114 size_t const wr_pos = mb->wr_ptr () - start;
00115
00116 this->mb_ = ACE_Message_Block::duplicate (&msgb);
00117
00118 this->mb_->rd_ptr (rd_pos);
00119 this->mb_->wr_ptr (wr_pos);
00120 }
00121 }
00122 inline CORBA::ULong maximum() const {
00123 return maximum_;
00124 }
00125 inline CORBA::Boolean release() const {
00126 return release_;
00127 }
00128 inline CORBA::ULong length() const {
00129 return length_;
00130 }
00131 inline void length(CORBA::ULong length) {
00132 if (length <= maximum_)
00133 {
00134 if (this->mb_ == 0)
00135 {
00136 length_ = length;
00137 }
00138 else
00139 {
00140 unbounded_value_sequence<CORBA::Octet> tmp(length);
00141 tmp.length_ = length;
00142 element_traits::copy_range(
00143 buffer_,
00144 buffer_ + length,
00145 ACE_make_checked_array_iterator (tmp.buffer_, tmp.length_));
00146 swap(tmp);
00147 }
00148 return;
00149 }
00150
00151 unbounded_value_sequence<CORBA::Octet> tmp(length);
00152 tmp.length_ = length;
00153 element_traits::copy_range(
00154 buffer_,
00155 buffer_ + length_,
00156 ACE_make_checked_array_iterator (tmp.buffer_, tmp.length_));
00157 swap(tmp);
00158 }
00159 inline value_type const & operator[](CORBA::ULong i) const {
00160 range::check(i, length_, maximum_, "operator[]() const");
00161 return buffer_[i];
00162 }
00163 inline value_type & operator[](CORBA::ULong i) {
00164 range::check(i, length_, maximum_, "operator[]() non-const");
00165 return buffer_[i];
00166 }
00167 inline void replace(
00168 CORBA::ULong maximum,
00169 CORBA::ULong length,
00170 value_type * data,
00171 CORBA::Boolean release = false) {
00172 unbounded_value_sequence<CORBA::Octet> tmp(maximum, length, data, release);
00173 swap(tmp);
00174 }
00175 inline value_type const * get_buffer() const {
00176 if (buffer_ == 0)
00177 {
00178 buffer_ = allocbuf(maximum_);
00179 release_ = true;
00180 }
00181 return buffer_;
00182 }
00183 inline value_type * get_buffer(CORBA::Boolean orphan = false) {
00184 if (orphan && !release_)
00185 {
00186 return 0;
00187 }
00188 if (buffer_ == 0)
00189 {
00190 buffer_ = allocbuf(maximum_);
00191 if (!orphan)
00192 {
00193 release_ = true;
00194 }
00195 }
00196 if (!orphan)
00197 {
00198 return buffer_;
00199 }
00200
00201 unbounded_value_sequence<CORBA::Octet> tmp;
00202 swap(tmp);
00203 tmp.release_ = false;
00204
00205 return tmp.buffer_;
00206 }
00207
00208
00209
00210 inline bool operator== (const unbounded_value_sequence<CORBA::Octet> & rhs) const {
00211 unbounded_value_sequence<CORBA::Octet> const & lhs = *this;
00212 CORBA::ULong const len = lhs.length();
00213
00214
00215
00216 return
00217 (len == rhs.length()
00218 && (len == 0
00219 ? true
00220 : ACE_OS::memcmp(&lhs[0], &rhs[0], len) == 0));
00221 }
00222
00223 inline bool operator!= (const unbounded_value_sequence<CORBA::Octet> & rhs) const
00224 {
00225 return !this->operator==(rhs);
00226 }
00227
00228 inline void swap(unbounded_value_sequence & rhs) throw() {
00229 std::swap (mb_, rhs.mb_);
00230 std::swap (maximum_, rhs.maximum_);
00231 std::swap (length_, rhs.length_);
00232 std::swap (buffer_, rhs.buffer_);
00233 std::swap (release_, rhs.release_);
00234 }
00235 static value_type * allocbuf(CORBA::ULong maximum) {
00236 return allocation_traits::allocbuf(maximum);
00237 }
00238 static void freebuf(value_type * buffer) {
00239 allocation_traits::freebuf(buffer);
00240 }
00241
00242
00243
00244 inline ACE_Message_Block* mb (void) const {
00245 return mb_;
00246 }
00247
00248
00249
00250 inline void replace (CORBA::ULong length, const ACE_Message_Block* mb) {
00251 unbounded_value_sequence<CORBA::Octet> s (length, mb);
00252 swap (s);
00253 }
00254
00255 unbounded_value_sequence<CORBA::Octet> (
00256 const unbounded_value_sequence<CORBA::Octet> &rhs)
00257 : maximum_ (0)
00258 , length_ (0)
00259 , buffer_(0)
00260 , release_(false)
00261 , mb_ (0)
00262 {
00263 if (rhs.maximum_ == 0 || rhs.buffer_ == 0)
00264 {
00265 maximum_ = rhs.maximum_;
00266 length_ = rhs.length_;
00267 return;
00268 }
00269 unbounded_value_sequence<CORBA::Octet> tmp(rhs.maximum_);
00270 tmp.length_ = rhs.length_;
00271 if (rhs.mb_ == 0)
00272 {
00273 ACE_OS::memcpy (tmp.buffer_,
00274 rhs.buffer_,
00275 rhs.length_);
00276 }
00277 else
00278 {
00279 size_t offset = 0;
00280 for (const ACE_Message_Block *i = rhs.mb_; i != 0; i = i->cont ())
00281 {
00282 ACE_OS::memcpy (tmp.buffer_ + offset,
00283 i->rd_ptr (),
00284 i->length ());
00285
00286 offset += i->length ();
00287 }
00288 }
00289 swap(tmp);
00290 }
00291
00292 unbounded_value_sequence<CORBA::Octet> &
00293 operator= (const unbounded_value_sequence<CORBA::Octet> & rhs)
00294 {
00295 unbounded_value_sequence<CORBA::Octet> tmp(rhs);
00296 swap(tmp);
00297 return * this;
00298 }
00299
00300 private:
00301
00302 CORBA::ULong maximum_;
00303
00304
00305 CORBA::ULong length_;
00306
00307
00308
00309 mutable value_type * buffer_;
00310
00311
00312
00313 mutable CORBA::Boolean release_;
00314 ACE_Message_Block* mb_;
00315 };
00316
00317 }
00318
00319 TAO_END_VERSIONED_NAMESPACE_DECL
00320
00321 #endif
00322
00323 #if (TAO_NO_COPY_OCTET_SEQUENCES == 0)
00324
00325
00326
00327
00328
00329 inline
00330 bool
00331 operator== (const TAO_VERSIONED_NAMESPACE_NAME::TAO::unbounded_value_sequence<CORBA::Octet> & lhs,
00332 const TAO_VERSIONED_NAMESPACE_NAME::TAO::unbounded_value_sequence<CORBA::Octet> & rhs)
00333 {
00334 ::CORBA::ULong const rlen = rhs.length ();
00335
00336 if (rlen != lhs.length ())
00337 {
00338 return false;
00339 }
00340
00341 const CORBA::Octet * rhs_buff = rhs.get_buffer ();
00342 const CORBA::Octet * lhs_buff = lhs.get_buffer ();
00343 const bool result = (ACE_OS::memcmp (lhs_buff, rhs_buff, rlen) == 0);
00344
00345 return result;
00346 }
00347
00348 inline
00349 bool
00350 operator!= (const TAO_VERSIONED_NAMESPACE_NAME::TAO::unbounded_value_sequence<CORBA::Octet> & lhs,
00351 const TAO_VERSIONED_NAMESPACE_NAME::TAO::unbounded_value_sequence<CORBA::Octet> & rhs)
00352 {
00353 return !(lhs == rhs);
00354 }
00355 #endif
00356
00357 #endif // guard_unbounded_octet_sequence_hpp