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