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