CDR_Stream.cpp

Go to the documentation of this file.
00001 #include "ace/CDR_Stream.h"
00002 #include "ace/SString.h"
00003 #include "ace/Auto_Ptr.h"
00004 
00005 #if !defined (__ACE_INLINE__)
00006 # include "ace/CDR_Stream.inl"
00007 #endif /* ! __ACE_INLINE__ */
00008 
00009 ACE_RCSID (ace,
00010            CDR_Stream,
00011            "$Id: CDR_Stream.cpp 79347 2007-08-15 11:10:02Z johnnyw $")
00012 
00013 // ****************************************************************
00014 
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 size_t ACE_OutputCDR::wchar_maxbytes_ = sizeof (ACE_CDR::WChar);
00018 
00019 ACE_OutputCDR::ACE_OutputCDR (size_t size,
00020                               int byte_order,
00021                               ACE_Allocator *buffer_allocator,
00022                               ACE_Allocator *data_block_allocator,
00023                               ACE_Allocator *message_block_allocator,
00024                               size_t memcpy_tradeoff,
00025                               ACE_CDR::Octet major_version,
00026                               ACE_CDR::Octet minor_version)
00027   :  start_ ((size ? size : (size_t) ACE_CDR::DEFAULT_BUFSIZE) + ACE_CDR::MAX_ALIGNMENT,
00028              ACE_Message_Block::MB_DATA,
00029              0,
00030              0,
00031              buffer_allocator,
00032              0,
00033              0,
00034              ACE_Time_Value::zero,
00035              ACE_Time_Value::max_time,
00036              data_block_allocator,
00037              message_block_allocator),
00038 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00039      current_alignment_ (0),
00040 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00041      current_is_writable_ (true),
00042      do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00043      good_bit_ (true),
00044      memcpy_tradeoff_ (memcpy_tradeoff),
00045      major_version_ (major_version),
00046      minor_version_ (minor_version),
00047      char_translator_ (0),
00048      wchar_translator_ (0)
00049 
00050 {
00051   ACE_CDR::mb_align (&this->start_);
00052   this->current_ = &this->start_;
00053 }
00054 
00055 ACE_OutputCDR::ACE_OutputCDR (char *data,
00056                               size_t size,
00057                               int byte_order,
00058                               ACE_Allocator *buffer_allocator,
00059                               ACE_Allocator *data_block_allocator,
00060                               ACE_Allocator *message_block_allocator,
00061                               size_t memcpy_tradeoff,
00062                               ACE_CDR::Octet major_version,
00063                               ACE_CDR::Octet minor_version)
00064   :  start_ (size,
00065              ACE_Message_Block::MB_DATA,
00066              0,
00067              data,
00068              buffer_allocator,
00069              0,
00070              0,
00071              ACE_Time_Value::zero,
00072              ACE_Time_Value::max_time,
00073              data_block_allocator,
00074              message_block_allocator),
00075 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00076      current_alignment_ (0),
00077 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00078      current_is_writable_ (true),
00079      do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00080      good_bit_ (true),
00081      memcpy_tradeoff_ (memcpy_tradeoff),
00082      major_version_ (major_version),
00083      minor_version_ (minor_version),
00084      char_translator_ (0),
00085      wchar_translator_ (0)
00086 {
00087   // We cannot trust the buffer to be properly aligned
00088   ACE_CDR::mb_align (&this->start_);
00089   this->current_ = &this->start_;
00090 }
00091 
00092 ACE_OutputCDR::ACE_OutputCDR (ACE_Data_Block *data_block,
00093                               int byte_order,
00094                               ACE_Allocator *message_block_allocator,
00095                               size_t memcpy_tradeoff,
00096                               ACE_CDR::Octet major_version,
00097                               ACE_CDR::Octet minor_version)
00098   :  start_ (data_block,
00099              ACE_Message_Block::DONT_DELETE,
00100              message_block_allocator),
00101 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00102      current_alignment_ (0),
00103 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00104      current_is_writable_ (true),
00105      do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00106      good_bit_ (true),
00107      memcpy_tradeoff_ (memcpy_tradeoff),
00108      major_version_ (major_version),
00109      minor_version_ (minor_version),
00110      char_translator_ (0),
00111      wchar_translator_ (0)
00112 {
00113   // We cannot trust the buffer to be properly aligned
00114   ACE_CDR::mb_align (&this->start_);
00115   this->current_ = &this->start_;
00116 }
00117 
00118 ACE_OutputCDR::ACE_OutputCDR (ACE_Message_Block *data,
00119                               int byte_order,
00120                               size_t memcpy_tradeoff,
00121                               ACE_CDR::Octet major_version,
00122                               ACE_CDR::Octet minor_version)
00123   :  start_ (data->data_block ()->duplicate ()),
00124 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00125      current_alignment_ (0),
00126 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00127      current_is_writable_ (true),
00128      do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00129      good_bit_ (true),
00130      memcpy_tradeoff_ (memcpy_tradeoff),
00131      major_version_ (major_version),
00132      minor_version_ (minor_version),
00133      char_translator_ (0),
00134      wchar_translator_ (0)
00135 {
00136   // We cannot trust the buffer to be properly aligned
00137   ACE_CDR::mb_align (&this->start_);
00138   this->current_ = &this->start_;
00139 }
00140 
00141 /*static*/ void
00142 ACE_OutputCDR::wchar_maxbytes (size_t maxbytes)
00143 {
00144   ACE_OutputCDR::wchar_maxbytes_ = maxbytes;
00145 }
00146 
00147 /*static*/ size_t
00148 ACE_OutputCDR::wchar_maxbytes ()
00149 {
00150   return ACE_OutputCDR::wchar_maxbytes_;
00151 }
00152 
00153 int
00154 ACE_OutputCDR::grow_and_adjust (size_t size,
00155                                 size_t align,
00156                                 char*& buf)
00157 {
00158   if (!this->current_is_writable_
00159       || this->current_->cont () == 0
00160       || this->current_->cont ()->size () < size + ACE_CDR::MAX_ALIGNMENT)
00161     {
00162       // Calculate the new buffer's length; if growing for encode, we
00163       // don't grow in "small" chunks because of the cost.
00164       size_t cursize = this->current_->size ();
00165       if (this->current_->cont () != 0)
00166         cursize = this->current_->cont ()->size ();
00167       size_t minsize = size;
00168 
00169 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00170       minsize += ACE_CDR::MAX_ALIGNMENT;
00171 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00172 
00173       // Make sure that there is enough room for <minsize> bytes, but
00174       // also make it bigger than whatever our current size is.
00175       if (minsize < cursize)
00176         minsize = cursize;
00177 
00178       size_t const newsize = ACE_CDR::next_size (minsize);
00179 
00180       this->good_bit_ = false;
00181       ACE_Message_Block* tmp = 0;
00182       ACE_NEW_RETURN (tmp,
00183                       ACE_Message_Block (newsize,
00184                                          ACE_Message_Block::MB_DATA,
00185                                          0,
00186                                          0,
00187                                          this->current_->data_block ()->allocator_strategy (),
00188                                          0,
00189                                          0,
00190                                          ACE_Time_Value::zero,
00191                                          ACE_Time_Value::max_time,
00192                                          this->current_->data_block ()->data_block_allocator ()),
00193                       -1);
00194 
00195       // Message block initialization may fail while the construction
00196       // succeds.  Since as a matter of policy, ACE may throw no
00197       // exceptions, we have to do a separate check like this.
00198       if (tmp != 0 && tmp->size () < newsize)
00199         {
00200           delete tmp;
00201           errno = ENOMEM;
00202           return -1;
00203         }
00204 
00205       this->good_bit_ = true;
00206 
00207 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00208       // The new block must start with the same alignment as the
00209       // previous block finished.
00210       ptrdiff_t const tmpalign =
00211         reinterpret_cast<ptrdiff_t> (tmp->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT;
00212       ptrdiff_t const curalign =
00213         static_cast<ptrdiff_t> (this->current_alignment_) % ACE_CDR::MAX_ALIGNMENT;
00214       ptrdiff_t offset = curalign - tmpalign;
00215       if (offset < 0)
00216         offset += ACE_CDR::MAX_ALIGNMENT;
00217       tmp->rd_ptr (static_cast<size_t> (offset));
00218       tmp->wr_ptr (tmp->rd_ptr ());
00219 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00220 
00221       // grow the chain and set the current block.
00222       tmp->cont (this->current_->cont ());
00223       this->current_->cont (tmp);
00224     }
00225   this->current_ = this->current_->cont ();
00226   this->current_is_writable_ = true;
00227 
00228   return this->adjust (size, align, buf);
00229 }
00230 
00231 ACE_CDR::Boolean
00232 ACE_OutputCDR::write_wchar (ACE_CDR::WChar x)
00233 {
00234   if (this->wchar_translator_ != 0)
00235     return (this->good_bit_ = this->wchar_translator_->write_wchar (*this, x));
00236   if (ACE_OutputCDR::wchar_maxbytes_ == 0)
00237     {
00238       errno = EACCES;
00239       return (this->good_bit_ = false);
00240     }
00241   if (static_cast<ACE_CDR::Short> (major_version_) == 1
00242       && static_cast<ACE_CDR::Short> (minor_version_) == 2)
00243     {
00244       ACE_CDR::Octet len =
00245         static_cast<ACE_CDR::Octet> (ACE_OutputCDR::wchar_maxbytes_);
00246       if (this->write_1 (&len))
00247         {
00248           if (ACE_OutputCDR::wchar_maxbytes_ == sizeof(ACE_CDR::WChar))
00249             return
00250               this->write_octet_array (
00251                                        reinterpret_cast<const ACE_CDR::Octet*> (&x),
00252                                        static_cast<ACE_CDR::ULong> (len));
00253           else
00254             if (ACE_OutputCDR::wchar_maxbytes_ == 2)
00255               {
00256                 ACE_CDR::Short sx = static_cast<ACE_CDR::Short> (x);
00257                 return
00258                   this->write_octet_array (
00259                                            reinterpret_cast<const ACE_CDR::Octet*> (&sx),
00260                                            static_cast<ACE_CDR::ULong> (len));
00261               }
00262             else
00263               {
00264                 ACE_CDR::Octet ox = static_cast<ACE_CDR::Octet> (x);
00265                 return
00266                   this->write_octet_array (
00267                                            reinterpret_cast<const ACE_CDR::Octet*> (&ox),
00268                                            static_cast<ACE_CDR::ULong> (len));
00269               }
00270         }
00271     }
00272   else if (static_cast<ACE_CDR::Short> (minor_version_) == 0)
00273     { // wchar is not allowed with GIOP 1.0.
00274       errno = EINVAL;
00275       return (this->good_bit_ = false);
00276     }
00277   if (ACE_OutputCDR::wchar_maxbytes_ == sizeof (ACE_CDR::WChar))
00278     {
00279       void const * const temp = &x;
00280       return
00281         this->write_4 (reinterpret_cast<const ACE_CDR::ULong *> (temp));
00282     }
00283   else if (ACE_OutputCDR::wchar_maxbytes_ == 2)
00284     {
00285       ACE_CDR::Short sx = static_cast<ACE_CDR::Short> (x);
00286       return this->write_2 (reinterpret_cast<const ACE_CDR::UShort *> (&sx));
00287     }
00288   ACE_CDR::Octet ox = static_cast<ACE_CDR::Octet> (x);
00289   return this->write_1 (reinterpret_cast<const ACE_CDR::Octet *> (&ox));
00290 }
00291 
00292 ACE_CDR::Boolean
00293 ACE_OutputCDR::write_string (ACE_CDR::ULong len,
00294                              const ACE_CDR::Char *x)
00295 {
00296   // @@ This is a slight violation of "Optimize for the common case",
00297   // i.e. normally the translator will be 0, but OTOH the code is
00298   // smaller and should be better for the cache ;-) ;-)
00299   if (this->char_translator_ != 0)
00300     return this->char_translator_->write_string (*this, len, x);
00301 
00302   if (len != 0)
00303     {
00304       if (this->write_ulong (len + 1))
00305         return this->write_char_array (x, len + 1);
00306     }
00307   else
00308     {
00309       // Be nice to programmers: treat nulls as empty strings not
00310       // errors. (OMG-IDL supports languages that don't use the C/C++
00311       // notion of null v. empty strings; nulls aren't part of the OMG-IDL
00312       // string model.)
00313       if (this->write_ulong (1))
00314         return this->write_char (0);
00315     }
00316 
00317   return (this->good_bit_ = false);
00318 }
00319 
00320 ACE_CDR::Boolean
00321 ACE_OutputCDR::write_string (const ACE_CString &x)
00322 {
00323   // @@ Leave this method in here, not the `.i' file so that we don't
00324   //    have to unnecessarily pull in the `ace/SString.h' header.
00325   return this->write_string (static_cast<ACE_CDR::ULong> (x.length ()),
00326                              x.c_str());
00327 }
00328 
00329 ACE_CDR::Boolean
00330 ACE_OutputCDR::write_wstring (ACE_CDR::ULong len,
00331                               const ACE_CDR::WChar *x)
00332 {
00333   // @@ This is a slight violation of "Optimize for the common case",
00334   // i.e. normally the translator will be 0, but OTOH the code is
00335   // smaller and should be better for the cache ;-) ;-)
00336   // What do we do for GIOP 1.2???
00337   if (this->wchar_translator_ != 0)
00338     return this->wchar_translator_->write_wstring (*this, len, x);
00339   if (ACE_OutputCDR::wchar_maxbytes_ == 0)
00340     {
00341       errno = EACCES;
00342       return (this->good_bit_ = false);
00343     }
00344 
00345   if (static_cast<ACE_CDR::Short> (this->major_version_) == 1
00346       && static_cast<ACE_CDR::Short> (this->minor_version_) == 2)
00347     {
00348       if (x != 0)
00349         {
00350           //In GIOP 1.2 the length field contains the number of bytes
00351           //the wstring occupies rather than number of wchars
00352           //Taking sizeof might not be a good way! This is a temporary fix.
00353           if (this->write_ulong (ACE_OutputCDR::wchar_maxbytes_ * len))
00354             return this->write_wchar_array (x, len);
00355         }
00356       else
00357         //In GIOP 1.2 zero length wstrings are legal
00358         return this->write_ulong (0);
00359     }
00360 
00361   else
00362     if (x != 0)
00363       {
00364         if (this->write_ulong (len + 1))
00365           return this->write_wchar_array (x, len + 1);
00366       }
00367     else if (this->write_ulong (1))
00368       return this->write_wchar (0);
00369   return (this->good_bit_ = false);
00370 }
00371 
00372 ACE_CDR::Boolean
00373 ACE_OutputCDR::write_octet_array_mb (const ACE_Message_Block* mb)
00374 {
00375   // If the buffer is small and it fits in the current message
00376   // block it is be cheaper just to copy the buffer.
00377   for (const ACE_Message_Block* i = mb;
00378        i != 0;
00379        i = i->cont ())
00380     {
00381       size_t const length = i->length ();
00382 
00383       // If the mb does not own its data we are forced to make a copy.
00384       if (ACE_BIT_ENABLED (i->flags (),
00385                            ACE_Message_Block::DONT_DELETE))
00386         {
00387           if (! this->write_array (i->rd_ptr (),
00388                                    ACE_CDR::OCTET_SIZE,
00389                                    ACE_CDR::OCTET_ALIGN,
00390                                    static_cast<ACE_CDR::ULong> (length)))
00391             return (this->good_bit_ = false);
00392           continue;
00393         }
00394 
00395       if (length < this->memcpy_tradeoff_
00396           && this->current_->wr_ptr () + length < this->current_->end ())
00397         {
00398           if (! this->write_array (i->rd_ptr (),
00399                                    ACE_CDR::OCTET_SIZE,
00400                                    ACE_CDR::OCTET_ALIGN,
00401                                    static_cast<ACE_CDR::ULong> (length)))
00402             return (this->good_bit_ = false);
00403           continue;
00404         }
00405 
00406       ACE_Message_Block* cont = 0;
00407       this->good_bit_ = false;
00408       ACE_NEW_RETURN (cont,
00409                       ACE_Message_Block (i->data_block ()->duplicate ()),
00410                       false);
00411       this->good_bit_ = true;
00412 
00413       if (this->current_->cont () != 0)
00414         ACE_Message_Block::release (this->current_->cont ());
00415       cont->rd_ptr (i->rd_ptr ());
00416       cont->wr_ptr (i->wr_ptr ());
00417 
00418       this->current_->cont (cont);
00419       this->current_ = cont;
00420       this->current_is_writable_ = false;
00421 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00422       this->current_alignment_ =
00423         (this->current_alignment_ + cont->length ()) % ACE_CDR::MAX_ALIGNMENT;
00424 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00425     }
00426 
00427   return true;
00428 }
00429 
00430 ACE_CDR::Boolean
00431 ACE_OutputCDR::write_1 (const ACE_CDR::Octet *x)
00432 {
00433   char *buf = 0;
00434   if (this->adjust (1, buf) == 0)
00435     {
00436       *reinterpret_cast<ACE_CDR::Octet*> (buf) = *x;
00437       return true;
00438     }
00439 
00440   return false;
00441 }
00442 
00443 ACE_CDR::Boolean
00444 ACE_OutputCDR::write_2 (const ACE_CDR::UShort *x)
00445 {
00446   char *buf = 0;
00447   if (this->adjust (ACE_CDR::SHORT_SIZE, buf) == 0)
00448     {
00449 #if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00450       *reinterpret_cast<ACE_CDR::UShort*> (buf) = *x;
00451       return true;
00452 #else
00453       if (!this->do_byte_swap_)
00454         {
00455           *reinterpret_cast<ACE_CDR::UShort *> (buf) = *x;
00456           return true;
00457         }
00458       else
00459         {
00460           ACE_CDR::swap_2 (reinterpret_cast<const char*> (x), buf);
00461           return true;
00462         }
00463 #endif /* ACE_ENABLE_SWAP_ON_WRITE */
00464     }
00465 
00466   return false;
00467 }
00468 
00469 ACE_CDR::Boolean
00470 ACE_OutputCDR::write_4 (const ACE_CDR::ULong *x)
00471 {
00472   char *buf = 0;
00473   if (this->adjust (ACE_CDR::LONG_SIZE, buf) == 0)
00474     {
00475 #if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00476       *reinterpret_cast<ACE_CDR::ULong*> (buf) = *x;
00477       return true;
00478 #else
00479       if (!this->do_byte_swap_)
00480         {
00481           *reinterpret_cast<ACE_CDR::ULong *> (buf) = *x;
00482           return true;
00483         }
00484       else
00485         {
00486           ACE_CDR::swap_4 (reinterpret_cast<const char*> (x), buf);
00487           return true;
00488         }
00489 #endif /* ACE_ENABLE_SWAP_ON_WRITE */
00490     }
00491 
00492   return false;
00493 }
00494 
00495 ACE_CDR::Boolean
00496 ACE_OutputCDR::write_8 (const ACE_CDR::ULongLong *x)
00497 {
00498   char *buf = 0;
00499 
00500   if (this->adjust (ACE_CDR::LONGLONG_SIZE, buf) == 0)
00501     {
00502 #if defined (__arm__)
00503       // Convert to Intel format (12345678 => 56781234)
00504       const char *orig = reinterpret_cast<const char *> (x);
00505       char *target = buf;
00506       register ACE_UINT32 x =
00507         *reinterpret_cast<const ACE_UINT32 *> (orig);
00508       register ACE_UINT32 y =
00509         *reinterpret_cast<const ACE_UINT32 *> (orig + 4);
00510       *reinterpret_cast<ACE_UINT32 *> (target) = y;
00511       *reinterpret_cast<ACE_UINT32 *> (target + 4) = x;
00512       return true;
00513 #else
00514 #  if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00515       *reinterpret_cast<ACE_CDR::ULongLong *> (buf) = *x;
00516       return true;
00517 #  else
00518       if (!this->do_byte_swap_)
00519         {
00520           *reinterpret_cast<ACE_CDR::ULongLong *> (buf) = *x;
00521           return true;
00522         }
00523       else
00524         {
00525           ACE_CDR::swap_8 (reinterpret_cast<const char*> (x), buf);
00526           return true;
00527         }
00528 #  endif /* ACE_ENABLE_SWAP_ON_WRITE */
00529 #endif /* !__arm__ */
00530      }
00531 
00532   return false;
00533 }
00534 
00535 ACE_CDR::Boolean
00536 ACE_OutputCDR::write_16 (const ACE_CDR::LongDouble *x)
00537 {
00538   char* buf = 0;
00539   if (this->adjust (ACE_CDR::LONGDOUBLE_SIZE,
00540                     ACE_CDR::LONGDOUBLE_ALIGN,
00541                     buf) == 0)
00542     {
00543 #if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00544       *reinterpret_cast<ACE_CDR::LongDouble*> (buf) = *x;
00545       return 1;
00546 #else
00547       if (!this->do_byte_swap_)
00548         {
00549           *reinterpret_cast<ACE_CDR::LongDouble *> (buf) = *x;
00550           return true;
00551         }
00552       else
00553         {
00554           ACE_CDR::swap_16 (reinterpret_cast<const char*> (x), buf);
00555           return true;
00556         }
00557 #endif /* ACE_ENABLE_SWAP_ON_WRITE */
00558     }
00559 
00560   return false;
00561 }
00562 
00563 ACE_CDR::Boolean
00564 ACE_OutputCDR::write_wchar_array_i (const ACE_CDR::WChar *x,
00565                                     ACE_CDR::ULong length)
00566 {
00567   if (length == 0)
00568     return true;
00569   char* buf = 0;
00570   size_t const align = (ACE_OutputCDR::wchar_maxbytes_ == 2) ?
00571     ACE_CDR::SHORT_ALIGN :
00572     ACE_CDR::OCTET_ALIGN;
00573 
00574   if (this->adjust (ACE_OutputCDR::wchar_maxbytes_ * length, align, buf) == 0)
00575     {
00576       if (ACE_OutputCDR::wchar_maxbytes_ == 2)
00577         {
00578           ACE_CDR::UShort *sb = reinterpret_cast<ACE_CDR::UShort *> (buf);
00579           for (size_t i = 0; i < length; ++i)
00580 #if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00581             sb[i] = static_cast<ACE_CDR::UShort> (x[i]);
00582 #else
00583               if (!this->do_byte_swap_)
00584               sb[i] = static_cast<ACE_CDR::UShort> (x[i]);
00585             else
00586               {
00587                 ACE_CDR::UShort sx = static_cast<ACE_CDR::UShort> (x[i]);
00588                 ACE_CDR::swap_2 (reinterpret_cast<char *> (&sx), &buf[i * 2]);
00589               }
00590 #endif /* ACE_ENABLE_SWAP_ON_WRITE */
00591         }
00592       else
00593         {
00594           for (size_t i = 0; i < length; ++i)
00595             buf[i] = static_cast<char> (x[i]);
00596         }
00597       return this->good_bit_;
00598     }
00599   return false;
00600 }
00601 
00602 
00603 ACE_CDR::Boolean
00604 ACE_OutputCDR::write_array (const void *x,
00605                             size_t size,
00606                             size_t align,
00607                             ACE_CDR::ULong length)
00608 {
00609   if (length == 0)
00610     return true;
00611   char *buf = 0;
00612   if (this->adjust (size * length, align, buf) == 0)
00613     {
00614 #if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00615       ACE_OS::memcpy (buf, x, size*length);
00616       return true;
00617 #else
00618       if (!this->do_byte_swap_ || size == 1)
00619         {
00620           ACE_OS::memcpy (buf, x, size*length);
00621           return true;
00622         }
00623       else
00624         {
00625           const char *source = reinterpret_cast<const char *> (x);
00626           switch (size)
00627             {
00628             case 2:
00629               ACE_CDR::swap_2_array (source, buf, length);
00630               return true;
00631             case 4:
00632               ACE_CDR::swap_4_array (source, buf, length);
00633               return true;
00634             case 8:
00635               ACE_CDR::swap_8_array (source, buf, length);
00636               return true;
00637             case 16:
00638               ACE_CDR::swap_16_array (source, buf, length);
00639               return true;
00640             default:
00641               // TODO: print something?
00642               this->good_bit_ = false;
00643               return false;
00644             }
00645         }
00646 #endif /* ACE_ENABLE_SWAP_ON_WRITE */
00647     }
00648   this->good_bit_ = false;
00649   return false;
00650 }
00651 
00652 
00653 ACE_CDR::Boolean
00654 ACE_OutputCDR::replace (ACE_CDR::Long x, char* loc)
00655 {
00656   if (this->find (loc) == 0)
00657     return false;
00658 
00659 #if !defined (ACE_ENABLE_SWAP_ON_WRITE)
00660   *reinterpret_cast<ACE_CDR::Long*> (loc) = x;
00661 #else
00662   if (!this->do_byte_swap_)
00663   {
00664     *reinterpret_cast<ACE_CDR::Long *> (loc) = x;
00665   }
00666   else
00667   {
00668     ACE_CDR::swap_4 (reinterpret_cast<const char*> (&x), loc);
00669   }
00670 #endif /* ACE_ENABLE_SWAP_ON_WRITE */
00671 
00672   return true;
00673 }
00674 
00675 
00676 ACE_CDR::Boolean
00677 ACE_OutputCDR::write_boolean_array (const ACE_CDR::Boolean* x,
00678                                     ACE_CDR::ULong length)
00679 {
00680   // It is hard to optimize this, the spec requires that on the wire
00681   // booleans be represented as a byte with value 0 or 1, but in
00682   // memory it is possible (though very unlikely) that a boolean has
00683   // a non-zero value (different from 1).
00684   // We resort to a simple loop.
00685   ACE_CDR::Boolean const * const end = x + length;
00686 
00687   for (ACE_CDR::Boolean const * i = x;
00688        i != end && this->good_bit ();
00689        ++i)
00690     (void) this->write_boolean (*i);
00691 
00692   return this->good_bit ();
00693 }
00694 
00695 
00696 int
00697 ACE_OutputCDR::consolidate (void)
00698 {
00699   // Optimize by only doing something if we need to
00700   if (this->current_ != &this->start_)
00701     {
00702       // Set the number of bytes in the top-level block, reallocating
00703       // if necessary.  The rd_ptr and wr_ptr remain at the original offsets
00704       // into the buffer, even if it is reallocated.
00705       // Return an error if the allocation failed.
00706       size_t newsize =
00707         ACE_CDR::first_size (this->total_length ()
00708                              + ACE_CDR::MAX_ALIGNMENT);
00709       if (this->start_.size (newsize) < 0)
00710         {
00711           return -1;
00712         }
00713 
00714       // Consolidate the chain into the first block.  NOTE that
00715       // ACE_CDR::consolidate can not be used since we don't want to
00716       // overwrite what is already in the first block. We just append it since
00717       // the read and write pointers weren't affected by the resizing above.
00718       // We also don't have to worry about alignment since the start block is
00719       // already aligned.
00720       // NOTE also we know there is a continuation since we checked for it
00721       // above.  There is therefore no reason to check for a 0 continuation
00722       // field here.
00723       ACE_Message_Block *cont = this->start_.cont ();
00724       for (const ACE_Message_Block* i = cont; i != 0; i = i->cont ())
00725         {
00726           this->start_.copy (i->rd_ptr (), i->length ());
00727         }
00728 
00729       // Release the old blocks that were consolidated and reset the
00730       // current_ and current_is_writable_ to reflect the single used block.
00731       ACE_Message_Block::release (cont);
00732       this->start_.cont (0);
00733       this->current_ = &this->start_;
00734       this->current_is_writable_ = true;
00735     }
00736 
00737   return 0;
00738 }
00739 
00740 
00741 ACE_Message_Block*
00742 ACE_OutputCDR::find (char* loc)
00743 {
00744   ACE_Message_Block* mb = 0;
00745   for (mb = &this->start_; mb != 0; mb = mb->cont ())
00746   {
00747     if (loc <= mb->wr_ptr () && loc >= mb->rd_ptr ())
00748     {
00749       break;
00750     }
00751   }
00752 
00753   return mb;
00754 }
00755 
00756 
00757 // ****************************************************************
00758 
00759 ACE_InputCDR::ACE_InputCDR (const char *buf,
00760                             size_t bufsiz,
00761                             int byte_order,
00762                             ACE_CDR::Octet major_version,
00763                             ACE_CDR::Octet minor_version)
00764   : start_ (buf, bufsiz),
00765     do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00766     good_bit_ (true),
00767     major_version_ (major_version),
00768     minor_version_ (minor_version),
00769     char_translator_ (0),
00770     wchar_translator_ (0)
00771 {
00772   this->start_.wr_ptr (bufsiz);
00773 }
00774 
00775 ACE_InputCDR::ACE_InputCDR (size_t bufsiz,
00776                             int byte_order,
00777                             ACE_CDR::Octet major_version,
00778                             ACE_CDR::Octet minor_version)
00779   : start_ (bufsiz),
00780     do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00781     good_bit_ (true),
00782     major_version_ (major_version),
00783     minor_version_ (minor_version),
00784     char_translator_ (0),
00785     wchar_translator_ (0)
00786 {
00787 }
00788 
00789 ACE_InputCDR::ACE_InputCDR (const ACE_Message_Block *data,
00790                             int byte_order,
00791                             ACE_CDR::Octet major_version,
00792                             ACE_CDR::Octet minor_version,
00793                             ACE_Lock* lock)
00794 : start_ (0, ACE_Message_Block::MB_DATA, 0, 0, 0, lock),
00795     good_bit_ (true),
00796     major_version_ (major_version),
00797     minor_version_ (minor_version),
00798     char_translator_ (0),
00799     wchar_translator_ (0)
00800 
00801 {
00802   this->reset (data, byte_order);
00803 }
00804 
00805 ACE_InputCDR::ACE_InputCDR (ACE_Data_Block *data,
00806                             ACE_Message_Block::Message_Flags flag,
00807                             int byte_order,
00808                             ACE_CDR::Octet major_version,
00809                             ACE_CDR::Octet minor_version)
00810   : start_ (data, flag),
00811     do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00812     good_bit_ (true),
00813     major_version_ (major_version),
00814     minor_version_ (minor_version),
00815     char_translator_ (0),
00816     wchar_translator_ (0)
00817 
00818 {
00819 }
00820 
00821 ACE_InputCDR::ACE_InputCDR (ACE_Data_Block *data,
00822                             ACE_Message_Block::Message_Flags flag,
00823                             size_t rd_pos,
00824                             size_t wr_pos,
00825                             int byte_order,
00826                             ACE_CDR::Octet major_version,
00827                             ACE_CDR::Octet minor_version)
00828   : start_ (data, flag),
00829     do_byte_swap_ (byte_order != ACE_CDR_BYTE_ORDER),
00830     good_bit_ (true),
00831     major_version_ (major_version),
00832     minor_version_ (minor_version),
00833     char_translator_ (0),
00834     wchar_translator_ (0)
00835 
00836 {
00837   // Set the read pointer
00838   this->start_.rd_ptr (rd_pos);
00839 
00840   // Set the write pointer after doing a sanity check.
00841   char* wrpos = this->start_.base () + wr_pos;
00842 
00843   if (this->start_.end () >= wrpos)
00844     {
00845       this->start_.wr_ptr (wr_pos);
00846     }
00847 }
00848 
00849 
00850 ACE_InputCDR::ACE_InputCDR (const ACE_InputCDR& rhs,
00851                             size_t size,
00852                             ACE_CDR::Long offset)
00853   : start_ (rhs.start_,
00854             ACE_CDR::MAX_ALIGNMENT),
00855     do_byte_swap_ (rhs.do_byte_swap_),
00856     good_bit_ (true),
00857     major_version_ (rhs.major_version_),
00858     minor_version_ (rhs.minor_version_),
00859     char_translator_ (rhs.char_translator_),
00860     wchar_translator_ (rhs.wchar_translator_)
00861 
00862 {
00863 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00864   // Align the base pointer assuming that the incoming stream is also
00865   // aligned the way we are aligned
00866   char *incoming_start = ACE_ptr_align_binary (rhs.start_.base (),
00867                                                ACE_CDR::MAX_ALIGNMENT);
00868 #else
00869   char *incoming_start = rhs.start_.base ();
00870 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00871 
00872   const size_t newpos =
00873     (rhs.start_.rd_ptr() - incoming_start)  + offset;
00874 
00875   if (newpos <= this->start_.space ()
00876       && newpos + size <= this->start_.space ())
00877     {
00878       this->start_.rd_ptr (newpos);
00879       this->start_.wr_ptr (newpos + size);
00880     }
00881   else
00882     this->good_bit_ = false;
00883 }
00884 
00885 ACE_InputCDR::ACE_InputCDR (const ACE_InputCDR& rhs,
00886                             size_t size)
00887   : start_ (rhs.start_,
00888             ACE_CDR::MAX_ALIGNMENT),
00889     do_byte_swap_ (rhs.do_byte_swap_),
00890     good_bit_ (true),
00891     major_version_ (rhs.major_version_),
00892     minor_version_ (rhs.minor_version_),
00893     char_translator_ (rhs.char_translator_),
00894     wchar_translator_ (rhs.wchar_translator_)
00895 
00896 {
00897 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00898   // Align the base pointer assuming that the incoming stream is also
00899   // aligned the way we are aligned
00900   char *incoming_start = ACE_ptr_align_binary (rhs.start_.base (),
00901                                                ACE_CDR::MAX_ALIGNMENT);
00902 #else
00903   char *incoming_start = rhs.start_.base ();
00904 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00905 
00906   const size_t newpos =
00907     rhs.start_.rd_ptr() - incoming_start;
00908 
00909   if (newpos <= this->start_.space ()
00910       && newpos + size <= this->start_.space ())
00911     {
00912       // Notice that ACE_Message_Block::duplicate may leave the
00913       // wr_ptr() with a higher value than what we actually want.
00914       this->start_.rd_ptr (newpos);
00915       this->start_.wr_ptr (newpos + size);
00916 
00917       ACE_CDR::Octet byte_order = 0;
00918       (void) this->read_octet (byte_order);
00919       this->do_byte_swap_ = (byte_order != ACE_CDR_BYTE_ORDER);
00920     }
00921   else
00922     this->good_bit_ = false;
00923 }
00924 
00925 ACE_InputCDR::ACE_InputCDR (const ACE_InputCDR& rhs)
00926   : start_ (rhs.start_,
00927             ACE_CDR::MAX_ALIGNMENT),
00928     do_byte_swap_ (rhs.do_byte_swap_),
00929     good_bit_ (true),
00930     major_version_ (rhs.major_version_),
00931     minor_version_ (rhs.minor_version_),
00932     char_translator_ (rhs.char_translator_),
00933     wchar_translator_ (rhs.wchar_translator_)
00934 {
00935 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00936   char *buf = ACE_ptr_align_binary (rhs.start_.base (),
00937                                     ACE_CDR::MAX_ALIGNMENT);
00938 #else
00939   char *buf = rhs.start_.base ();
00940 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00941 
00942   size_t rd_offset = rhs.start_.rd_ptr () - buf;
00943   size_t wr_offset = rhs.start_.wr_ptr () - buf;
00944   this->start_.rd_ptr (rd_offset);
00945   this->start_.wr_ptr (wr_offset);
00946 }
00947 
00948 ACE_InputCDR::ACE_InputCDR (ACE_InputCDR::Transfer_Contents x)
00949   : start_ (x.rhs_.start_.data_block ()),
00950     do_byte_swap_ (x.rhs_.do_byte_swap_),
00951     good_bit_ (true),
00952     major_version_ (x.rhs_.major_version_),
00953     minor_version_ (x.rhs_.minor_version_),
00954     char_translator_ (x.rhs_.char_translator_),
00955     wchar_translator_ (x.rhs_.wchar_translator_)
00956 {
00957 
00958   this->start_.rd_ptr (x.rhs_.start_.rd_ptr ());
00959   this->start_.wr_ptr (x.rhs_.start_.wr_ptr ());
00960 
00961   ACE_Data_Block* db = this->start_.data_block ()->clone_nocopy ();
00962   (void) x.rhs_.start_.replace_data_block (db);
00963 }
00964 
00965 ACE_InputCDR&
00966 ACE_InputCDR::operator= (const ACE_InputCDR& rhs)
00967 {
00968   if (this != &rhs)
00969     {
00970       this->start_.data_block (rhs.start_.data_block ()->duplicate ());
00971       this->start_.rd_ptr (rhs.start_.rd_ptr ());
00972       this->start_.wr_ptr (rhs.start_.wr_ptr ());
00973       this->do_byte_swap_ = rhs.do_byte_swap_;
00974       this->good_bit_ = true;
00975       this->char_translator_ = rhs.char_translator_;
00976       this->major_version_ = rhs.major_version_;
00977       this->minor_version_ = rhs.minor_version_;
00978     }
00979   return *this;
00980 }
00981 
00982 ACE_InputCDR::ACE_InputCDR (const ACE_OutputCDR& rhs,
00983                             ACE_Allocator* buffer_allocator,
00984                             ACE_Allocator* data_block_allocator,
00985                             ACE_Allocator* message_block_allocator)
00986   : start_ (rhs.total_length () + ACE_CDR::MAX_ALIGNMENT,
00987             ACE_Message_Block::MB_DATA,
00988             0,
00989             0,
00990             buffer_allocator,
00991             0,
00992             0,
00993             ACE_Time_Value::zero,
00994             ACE_Time_Value::max_time,
00995             data_block_allocator,
00996             message_block_allocator),
00997     do_byte_swap_ (rhs.do_byte_swap_),
00998     good_bit_ (true),
00999     major_version_ (rhs.major_version_),
01000     minor_version_ (rhs.minor_version_),
01001     char_translator_ (rhs.char_translator_),
01002     wchar_translator_ (rhs.wchar_translator_)
01003 {
01004   ACE_CDR::mb_align (&this->start_);
01005   for (const ACE_Message_Block *i = rhs.begin ();
01006        i != rhs.end ();
01007        i = i->cont ())
01008     this->start_.copy (i->rd_ptr (), i->length ());
01009 }
01010 
01011 ACE_CDR::Boolean
01012 ACE_InputCDR::skip_wchar (void)
01013 {
01014   if (static_cast<ACE_CDR::Short> (major_version_) == 1
01015       && static_cast<ACE_CDR::Short> (minor_version_) == 2)
01016     {
01017       ACE_CDR::Octet len;
01018       if (this->read_1 (&len))
01019         return this->skip_bytes (static_cast<size_t> (len));
01020     }
01021   else
01022     {
01023       ACE_CDR::WChar x;
01024       void * const temp = &x;
01025       if (ACE_OutputCDR::wchar_maxbytes_ == 2)
01026         return this->read_2 (reinterpret_cast<ACE_CDR::UShort *> (temp));
01027       else
01028         return this->read_4 (reinterpret_cast<ACE_CDR::ULong *> (temp));
01029     }
01030 
01031   return (this->good_bit_ = false);
01032 }
01033 
01034 ACE_CDR::Boolean
01035 ACE_InputCDR::read_wchar (ACE_CDR::WChar& x)
01036 {
01037   if (this->wchar_translator_ != 0)
01038     {
01039       this->good_bit_ = this->wchar_translator_->read_wchar (*this,x);
01040       return this->good_bit_;
01041     }
01042   if (ACE_OutputCDR::wchar_maxbytes_ == 0)
01043     {
01044       errno = EACCES;
01045       return (this->good_bit_ = false);
01046     }
01047 
01048   if (ACE_OutputCDR::wchar_maxbytes_ == sizeof (ACE_CDR::WChar))
01049     {
01050       if (static_cast<ACE_CDR::Short> (major_version_) == 1
01051           && static_cast<ACE_CDR::Short> (minor_version_) == 2)
01052         {
01053           ACE_CDR::Octet len;
01054 
01055           if (this->read_1 (&len))
01056             return this->read_array
01057               (reinterpret_cast<ACE_CDR::Octet*> (&x),
01058                static_cast<ACE_CDR::ULong> (len),
01059                ACE_CDR::OCTET_ALIGN,
01060                1);
01061 
01062           else
01063             return (this->good_bit_ = false);
01064         }
01065 
01066       void * const temp = &x;
01067       if (sizeof (ACE_CDR::WChar) == 2)
01068         return this->read_2 (reinterpret_cast<ACE_CDR::UShort *> (temp));
01069       else
01070         return this->read_4 (reinterpret_cast<ACE_CDR::ULong *> (temp));
01071     }
01072 
01073   if (static_cast<ACE_CDR::Short> (major_version_) == 1
01074       && static_cast<ACE_CDR::Short> (minor_version_) == 2)
01075     {
01076       ACE_CDR::Octet len;
01077 
01078       if (this->read_1 (&len))
01079         {
01080           if (len == 2)
01081             {
01082               ACE_CDR::Short sx;
01083               if (this->read_array
01084                   (reinterpret_cast<ACE_CDR::Octet*> (&sx),
01085                    static_cast<ACE_CDR::ULong> (len),
01086                    ACE_CDR::OCTET_ALIGN,
01087                    1))
01088                 {
01089                   x = static_cast<ACE_CDR::WChar> (sx);
01090                   return true;
01091                 }
01092             }
01093           else
01094             {
01095               ACE_CDR::Octet ox;
01096               if (this->read_array
01097                   (reinterpret_cast<ACE_CDR::Octet*> (&ox),
01098                    static_cast<ACE_CDR::ULong> (len),
01099                    ACE_CDR::OCTET_ALIGN,
01100                    1))
01101                 {
01102                   x = static_cast<ACE_CDR::WChar> (ox);
01103                   return true;
01104                 }
01105             }
01106         }
01107     }
01108   else
01109     {
01110       if (ACE_OutputCDR::wchar_maxbytes_ == 2)
01111         {
01112           ACE_CDR::UShort sx;
01113           if (this->read_2 (reinterpret_cast<ACE_CDR::UShort *> (&sx)))
01114             {
01115               x = static_cast<ACE_CDR::WChar> (sx);
01116               return true;
01117             }
01118         }
01119       else
01120         {
01121           ACE_CDR::Octet ox;
01122           if (this->read_1 (&ox))
01123             {
01124               x = static_cast<ACE_CDR::WChar> (ox);
01125               return true;
01126             }
01127 
01128         }
01129     }
01130   return (this->good_bit_ = false);
01131 }
01132 
01133 ACE_CDR::Boolean
01134 ACE_InputCDR::read_string (ACE_CDR::Char *&x)
01135 {
01136   // @@ This is a slight violation of "Optimize for the common case",
01137   // i.e. normally the translator will be 0, but OTOH the code is
01138   // smaller and should be better for the cache ;-) ;-)
01139   if (this->char_translator_ != 0)
01140     {
01141       this->good_bit_ = this->char_translator_->read_string (*this, x);
01142       return this->good_bit_;
01143     }
01144 
01145   ACE_CDR::ULong len = 0;
01146 
01147   if (!this->read_ulong (len))
01148     return false;
01149 
01150   // A check for the length being too great is done later in the
01151   // call to read_char_array but we want to have it done before
01152   // the memory is allocated.
01153   if (len > 0 && len <= this->length())
01154     {
01155       ACE_NEW_RETURN (x,
01156                       ACE_CDR::Char[len],
01157                       0);
01158 
01159       ACE_Auto_Basic_Array_Ptr<ACE_CDR::Char> safe_data (x);
01160 
01161       if (this->read_char_array (x, len))
01162         {
01163           (void) safe_data.release ();
01164           return true;
01165         }
01166     }
01167   else if (len == 0)
01168     {
01169       // Convert any null strings to empty strings since empty
01170       // strings can cause crashes. (See bug 58.)
01171       ACE_NEW_RETURN (x,
01172                       ACE_CDR::Char[1],
01173                       0);
01174       ACE_OS::strcpy (const_cast<char *&> (x), "");
01175       return true;
01176     }
01177 
01178   x = 0;
01179   return (this->good_bit_ = false);
01180 }
01181 
01182 ACE_CDR::Boolean
01183 ACE_InputCDR::read_string (ACE_CString &x)
01184 {
01185   ACE_CDR::Char * data = 0;
01186   if (this->read_string (data))
01187     {
01188       ACE_Auto_Basic_Array_Ptr<ACE_CDR::Char> safe_data (data);
01189       x = data;
01190       return true;
01191     }
01192 
01193   x = "";
01194   return (this->good_bit_ = false);
01195 }
01196 
01197 ACE_CDR::Boolean
01198 ACE_InputCDR::read_wstring (ACE_CDR::WChar*& x)
01199 {
01200   // @@ This is a slight violation of "Optimize for the common case",
01201   // i.e. normally the translator will be 0, but OTOH the code is
01202   // smaller and should be better for the cache ;-) ;-)
01203   if (this->wchar_translator_ != 0)
01204     {
01205       this->good_bit_ = this->wchar_translator_->read_wstring (*this, x);
01206       return this->good_bit_;
01207     }
01208   if (ACE_OutputCDR::wchar_maxbytes_ == 0)
01209     {
01210       errno = EACCES;
01211       return (this->good_bit_ = false);
01212     }
01213 
01214   ACE_CDR::ULong len = 0;
01215   if (!this->read_ulong (len))
01216     return false;
01217 
01218   // A check for the length being too great is done later in the
01219   // call to read_char_array but we want to have it done before
01220   // the memory is allocated.
01221   if (len > 0 && len <= this->length ())
01222     {
01223       ACE_Auto_Basic_Array_Ptr<ACE_CDR::WChar> safe_data;
01224 
01225       if (static_cast<ACE_CDR::Short> (this->major_version_) == 1
01226           && static_cast<ACE_CDR::Short> (this->minor_version_) == 2)
01227         {
01228           len /= ACE_OutputCDR::wchar_maxbytes_;
01229 
01230           //allocating one extra for the null character needed by applications
01231           ACE_NEW_RETURN (x,
01232                           ACE_CDR::WChar [len + 1],
01233                           false);
01234 
01235           ACE_auto_ptr_reset (safe_data, x);
01236 
01237           if (this->read_wchar_array (x, len))
01238             {
01239 
01240               //Null character used by applications to find the end of
01241               //the wstring
01242               //Is this okay with the GIOP 1.2 spec??
01243               x[len] = '\x00';
01244 
01245               (void) safe_data.release ();
01246 
01247               return true;
01248             }
01249         }
01250       else
01251         {
01252           ACE_NEW_RETURN (x,
01253                           ACE_CDR::WChar [len],
01254                           false);
01255 
01256           ACE_auto_ptr_reset (safe_data, x);
01257 
01258           if (this->read_wchar_array (x, len))
01259             {
01260               (void) safe_data.release ();
01261 
01262               return true;
01263             }
01264         }
01265     }
01266   else if (len == 0)
01267     {
01268       // Convert any null strings to empty strings since empty
01269       // strings can cause crashes. (See bug 58.)
01270       ACE_NEW_RETURN (x,
01271                       ACE_CDR::WChar[1],
01272                       false);
01273       x[0] = '\x00';
01274       return true;
01275     }
01276 
01277   this->good_bit_ = false;
01278   x = 0;
01279   return false;
01280 }
01281 
01282 ACE_CDR::Boolean
01283 ACE_InputCDR::read_array (void* x,
01284                           size_t size,
01285                           size_t align,
01286                           ACE_CDR::ULong length)
01287 {
01288   if (length == 0)
01289     return true;
01290   char* buf = 0;
01291 
01292   if (this->adjust (size * length, align, buf) == 0)
01293     {
01294 #if defined (ACE_DISABLE_SWAP_ON_READ)
01295       ACE_OS::memcpy (x, buf, size*length);
01296 #else
01297       if (!this->do_byte_swap_ || size == 1)
01298         ACE_OS::memcpy (x, buf, size*length);
01299       else
01300         {
01301           char *target = reinterpret_cast<char*> (x);
01302           switch (size)
01303             {
01304             case 2:
01305               ACE_CDR::swap_2_array (buf, target, length);
01306               break;
01307             case 4:
01308               ACE_CDR::swap_4_array (buf, target, length);
01309               break;
01310             case 8:
01311               ACE_CDR::swap_8_array (buf, target, length);
01312               break;
01313             case 16:
01314               ACE_CDR::swap_16_array (buf, target, length);
01315               break;
01316             default:
01317               // TODO: print something?
01318               this->good_bit_ = false;
01319               return false;
01320             }
01321         }
01322 #endif /* ACE_DISABLE_SWAP_ON_READ */
01323       return this->good_bit_;
01324     }
01325   return false;
01326 }
01327 
01328 ACE_CDR::Boolean
01329 ACE_InputCDR::read_wchar_array_i (ACE_CDR::WChar* x,
01330                                   ACE_CDR::ULong length)
01331 {
01332   if (length == 0)
01333     return true;
01334   char* buf = 0;
01335   size_t const align = (ACE_OutputCDR::wchar_maxbytes_ == 2) ?
01336     ACE_CDR::SHORT_ALIGN :
01337     ACE_CDR::OCTET_ALIGN;
01338 
01339   if (this->adjust (ACE_OutputCDR::wchar_maxbytes_ * length, align, buf) == 0)
01340     {
01341       if (ACE_OutputCDR::wchar_maxbytes_ == 2)
01342         {
01343           ACE_CDR::UShort *sb = reinterpret_cast<ACE_CDR::UShort *> (buf);
01344           for (size_t i = 0; i < length; ++i)
01345 #if defined (ACE_DISABLE_SWAP_ON_READ)
01346             x[i] = static_cast<ACE_CDR::WChar> (sb[i]);
01347 #else
01348             if (!this->do_byte_swap_)
01349               x[i] = static_cast<ACE_CDR::WChar> (sb[i]);
01350             else
01351               {
01352                 ACE_CDR::UShort sx;
01353                 ACE_CDR::swap_2 (&buf[i * 2], reinterpret_cast<char *> (&sx));
01354                 x[i] = static_cast<ACE_CDR::WChar> (sx);
01355               }
01356 #endif /* ACE_DISABLE_SWAP_ON_READ */
01357         }
01358       else
01359         {
01360           for (size_t i = 0; i < length; ++i)
01361             x[i] = static_cast<ACE_CDR::Octet> (buf[i]);
01362         }
01363       return this->good_bit_;
01364     }
01365   return false;
01366 }
01367 
01368 
01369 ACE_CDR::Boolean
01370 ACE_InputCDR::read_boolean_array (ACE_CDR::Boolean *x,
01371                                   ACE_CDR::ULong length)
01372 {
01373   // Make sure the length of the array isn't greater than the length of
01374   // the stream.
01375   if (length > this->length ())
01376     {
01377       this->good_bit_ = false;
01378       return false;
01379     }
01380 
01381   // It is hard to optimize this, the spec requires that on the wire
01382   // booleans be represented as a byte with value 0 or 1, but in
01383   // memory it is possible (though very unlikely) that a boolean has
01384   // a non-zero value (different from 1).
01385   // We resort to a simple loop.
01386   for (ACE_CDR::ULong i = 0; i != length && this->good_bit_; ++i)
01387     (void) this->read_boolean (x[i]);
01388 
01389   return this->good_bit_;
01390 }
01391 
01392 ACE_CDR::Boolean
01393 ACE_InputCDR::read_1 (ACE_CDR::Octet *x)
01394 {
01395   if (this->rd_ptr () < this->wr_ptr ())
01396     {
01397       *x = *reinterpret_cast<ACE_CDR::Octet*> (this->rd_ptr ());
01398       this->start_.rd_ptr (1);
01399       return true;
01400     }
01401 
01402   this->good_bit_ = false;
01403   return false;
01404 }
01405 
01406 ACE_CDR::Boolean
01407 ACE_InputCDR::read_2 (ACE_CDR::UShort *x)
01408 {
01409   char *buf = 0;
01410   if (this->adjust (ACE_CDR::SHORT_SIZE, buf) == 0)
01411     {
01412 #if !defined (ACE_DISABLE_SWAP_ON_READ)
01413       if (!this->do_byte_swap_)
01414         *x = *reinterpret_cast<ACE_CDR::UShort*> (buf);
01415       else
01416         ACE_CDR::swap_2 (buf, reinterpret_cast<char*> (x));
01417 #else
01418       *x = *reinterpret_cast<ACE_CDR::UShort*> (buf);
01419 #endif /* ACE_DISABLE_SWAP_ON_READ */
01420       return true;
01421     }
01422   this->good_bit_ = false;
01423   return false;
01424 }
01425 
01426 ACE_CDR::Boolean
01427 ACE_InputCDR::read_4 (ACE_CDR::ULong *x)
01428 {
01429   char *buf = 0;
01430   if (this->adjust (ACE_CDR::LONG_SIZE, buf) == 0)
01431     {
01432 #if !defined (ACE_DISABLE_SWAP_ON_READ)
01433       if (!this->do_byte_swap_)
01434         *x = *reinterpret_cast<ACE_CDR::ULong*> (buf);
01435       else
01436         ACE_CDR::swap_4 (buf, reinterpret_cast<char*> (x));
01437 #else
01438       *x = *reinterpret_cast<ACE_CDR::ULong*> (buf);
01439 #endif /* ACE_DISABLE_SWAP_ON_READ */
01440       return true;
01441     }
01442   this->good_bit_ = false;
01443   return false;
01444 }
01445 
01446 ACE_CDR::Boolean
01447 ACE_InputCDR::read_8 (ACE_CDR::ULongLong *x)
01448 {
01449   char *buf = 0;
01450 
01451   if (this->adjust (ACE_CDR::LONGLONG_SIZE, buf) == 0)
01452     {
01453 #if !defined (ACE_DISABLE_SWAP_ON_READ)
01454 #  if defined (__arm__)
01455       if (!this->do_byte_swap_)
01456         {
01457           // Convert from Intel format (12345678 => 56781234)
01458           const char *orig = buf;
01459           char *target = reinterpret_cast<char *> (x);
01460           register ACE_UINT32 x =
01461             *reinterpret_cast<const ACE_UINT32 *> (orig);
01462           register ACE_UINT32 y =
01463             *reinterpret_cast<const ACE_UINT32 *> (orig + 4);
01464           *reinterpret_cast<ACE_UINT32 *> (target) = y;
01465           *reinterpret_cast<ACE_UINT32 *> (target + 4) = x;
01466         }
01467       else
01468         {
01469           // Convert from Sparc format (12345678 => 43218765)
01470           const char *orig = buf;
01471           char *target = reinterpret_cast<char *> (x);
01472           register ACE_UINT32 x =
01473             *reinterpret_cast<const ACE_UINT32 *> (orig);
01474           register ACE_UINT32 y =
01475             *reinterpret_cast<const ACE_UINT32 *> (orig + 4);
01476           x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
01477           y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24);
01478           *reinterpret_cast<ACE_UINT32 *> (target) = x;
01479           *reinterpret_cast<ACE_UINT32 *> (target + 4) = y;
01480         }
01481 #  else
01482       if (!this->do_byte_swap_)
01483         *x = *reinterpret_cast<ACE_CDR::ULongLong *> (buf);
01484       else
01485         ACE_CDR::swap_8 (buf, reinterpret_cast<char *> (x));
01486 #  endif /* !__arm__ */
01487 #else
01488       *x = *reinterpret_cast<ACE_CDR::ULongLong *> (buf);
01489 #endif /* ACE_DISABLE_SWAP_ON_READ */
01490       return true;
01491     }
01492 
01493   this->good_bit_ = false;
01494   return false;
01495 }
01496 
01497 ACE_CDR::Boolean
01498 ACE_InputCDR::read_16 (ACE_CDR::LongDouble *x)
01499 {
01500   char *buf = 0;
01501   if (this->adjust (ACE_CDR::LONGDOUBLE_SIZE,
01502                     ACE_CDR::LONGDOUBLE_ALIGN,
01503                     buf) == 0)
01504     {
01505 #if !defined (ACE_DISABLE_SWAP_ON_READ)
01506       if (!this->do_byte_swap_)
01507         *x = *reinterpret_cast<ACE_CDR::LongDouble *> (buf);
01508       else
01509         ACE_CDR::swap_16 (buf, reinterpret_cast<char*> (x));
01510 #else
01511       *x = *reinterpret_cast<ACE_CDR::LongDouble*> (buf);
01512 #endif /* ACE_DISABLE_SWAP_ON_READ */
01513       return true;
01514     }
01515 
01516   this->good_bit_ = false;
01517   return false;
01518 }
01519 
01520 ACE_CDR::Boolean
01521 ACE_InputCDR::skip_string (void)
01522 {
01523   ACE_CDR::ULong len = 0;
01524   if (this->read_ulong (len))
01525     {
01526       if (this->rd_ptr () + len <= this->wr_ptr ())
01527         {
01528           this->rd_ptr (len);
01529           return true;
01530         }
01531       this->good_bit_ = false;
01532     }
01533   return false;
01534 }
01535 
01536 ACE_CDR::Boolean
01537 ACE_InputCDR::skip_wstring (void)
01538 {
01539   ACE_CDR::Boolean continue_skipping = true;
01540   ACE_CDR::ULong len = 0;
01541 
01542   continue_skipping = read_ulong (len);
01543 
01544   if (continue_skipping && len != 0)
01545     {
01546       if (static_cast<ACE_CDR::Short> (this->major_version_) == 1
01547             && static_cast<ACE_CDR::Short> (this->minor_version_) == 2)
01548           continue_skipping = this->skip_bytes ((size_t)len);
01549       else
01550         while (continue_skipping && len--)
01551           continue_skipping = this->skip_wchar ();
01552     }
01553   return continue_skipping;
01554 }
01555 
01556 ACE_CDR::Boolean
01557 ACE_InputCDR::skip_bytes (size_t len)
01558 {
01559   if (this->rd_ptr () + len <= this->wr_ptr ())
01560     {
01561       this->rd_ptr (len);
01562       return true;
01563     }
01564   this->good_bit_ = false;
01565   return false;
01566 }
01567 
01568 int
01569 ACE_InputCDR::grow (size_t newsize)
01570 {
01571   if (ACE_CDR::grow (&this->start_, newsize) == -1)
01572     return -1;
01573 
01574   ACE_CDR::mb_align (&this->start_);
01575   this->start_.wr_ptr (newsize);
01576   return 0;
01577 }
01578 
01579 void
01580 ACE_InputCDR::reset (const ACE_Message_Block* data,
01581                      int byte_order)
01582 {
01583   this->reset_byte_order (byte_order);
01584   ACE_CDR::consolidate (&this->start_, data);
01585 }
01586 
01587 void
01588 ACE_InputCDR::steal_from (ACE_InputCDR &cdr)
01589 {
01590   this->do_byte_swap_ = cdr.do_byte_swap_;
01591   this->start_.data_block (cdr.start_.data_block ()->duplicate ());
01592 
01593   // If the message block had a DONT_DELETE flags, just clear it off..
01594   this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE);
01595   this->start_.rd_ptr (cdr.start_.rd_ptr ());
01596 
01597   this->start_.wr_ptr (cdr.start_.wr_ptr ());
01598   this->major_version_ = cdr.major_version_;
01599   this->minor_version_ = cdr.minor_version_;
01600   cdr.reset_contents ();
01601 }
01602 
01603 void
01604 ACE_InputCDR::exchange_data_blocks (ACE_InputCDR &cdr)
01605 {
01606   // Exchange byte orders
01607   int byte_order = cdr.do_byte_swap_;
01608   cdr.do_byte_swap_ = this->do_byte_swap_;
01609   this->do_byte_swap_ = byte_order;
01610 
01611   // Get the destination read and write pointers
01612   size_t drd_pos =
01613     cdr.start_.rd_ptr () - cdr.start_.base ();
01614   size_t dwr_pos =
01615     cdr.start_.wr_ptr () - cdr.start_.base ();
01616 
01617   // Get the source read & write pointers
01618   size_t srd_pos =
01619     this->start_.rd_ptr () - this->start_.base ();
01620   size_t swr_pos =
01621     this->start_.wr_ptr () - this->start_.base ();
01622 
01623   // Exchange data_blocks. Dont release any of the data blocks.
01624   ACE_Data_Block *dnb =
01625     this->start_.replace_data_block (cdr.start_.data_block ());
01626   cdr.start_.replace_data_block (dnb);
01627 
01628   // Exchange the flags information..
01629   ACE_Message_Block::Message_Flags df = cdr.start_.self_flags ();
01630   ACE_Message_Block::Message_Flags sf = this->start_.self_flags ();
01631 
01632   cdr.start_.clr_self_flags (df);
01633   this->start_.clr_self_flags (sf);
01634 
01635   cdr.start_.set_self_flags (sf);
01636   this->start_.set_self_flags (df);
01637 
01638   // Reset the <cdr> pointers to zero before it is set again.
01639   cdr.start_.reset ();
01640   this->start_.reset ();
01641 
01642   // Set the read and write pointers.
01643   if (cdr.start_.size () >= srd_pos)
01644     cdr.start_.rd_ptr (srd_pos);
01645 
01646   if (cdr.start_.size () >= swr_pos)
01647     cdr.start_.wr_ptr (swr_pos);
01648 
01649   if (this->start_.size () >= drd_pos)
01650     this->start_.rd_ptr (drd_pos);
01651 
01652   if (this->start_.size () >= dwr_pos)
01653     this->start_.wr_ptr (dwr_pos);
01654 
01655   ACE_CDR::Octet dmajor = cdr.major_version_;
01656   ACE_CDR::Octet dminor = cdr.minor_version_;
01657 
01658   // Exchange the GIOP version info
01659   cdr.major_version_ = this->major_version_;
01660   cdr.minor_version_ = this->minor_version_;
01661 
01662   this->major_version_ = dmajor;
01663   this->minor_version_ = dminor;
01664 }
01665 
01666 ACE_Data_Block *
01667 ACE_InputCDR::clone_from (ACE_InputCDR &cdr)
01668 {
01669   this->do_byte_swap_ = cdr.do_byte_swap_;
01670 
01671   // Get the read & write pointer positions in the incoming CDR
01672   // streams
01673   char *rd_ptr = cdr.start_.rd_ptr ();
01674   char *wr_ptr = cdr.start_.wr_ptr ();
01675 
01676   // Now reset the incoming CDR stream
01677   cdr.start_.reset ();
01678 
01679   // As we have reset the stream, try to align the underlying message
01680   // block in the incoming stream
01681   ACE_CDR::mb_align (&cdr.start_);
01682 
01683   // Get the read & write pointer positions again
01684   char *nrd_ptr = cdr.start_.rd_ptr ();
01685   char *nwr_ptr = cdr.start_.wr_ptr ();
01686 
01687   // Actual length of the stream is..
01688   // @todo: This will look idiotic, but we dont seem to have much of a
01689   // choice. How do we calculate the length of the incoming stream?
01690   // Calling the method before calling reset () would give us the
01691   // wrong length of the stream that needs copying.  So we do the
01692   // calulation like this
01693   // (1) We get the <rd_ptr> and <wr_ptr> positions of the incoming
01694   // stream.
01695   // (2) Then we reset the <incoming> stream and then align it.
01696   // (3) We get the <rd_ptr> and <wr_ptr> positions again. (Points #1
01697   // thru #3 has been done already)
01698   // (4) The difference in the <rd_ptr> and <wr_ptr> positions gives
01699   // us the following, the actual bytes traversed by the <rd_ptr> and
01700   // <wr_ptr>.
01701   // (5) The bytes traversed by the <wr_ptr> is the actual length of
01702   // the stream.
01703 
01704   // Actual bytes traversed
01705   size_t rd_bytes = rd_ptr - nrd_ptr;
01706   size_t wr_bytes = wr_ptr - nwr_ptr;
01707 
01708   ACE_CDR::mb_align (&this->start_);
01709 
01710   ACE_Data_Block *db =
01711     this->start_.data_block ();
01712 
01713   // If the size of the data that needs to be copied are higher than
01714   // what is available, then do a reallocation.
01715   if (wr_bytes > (this->start_.size () - ACE_CDR::MAX_ALIGNMENT))
01716     {
01717       // @@NOTE: We need to probably add another method to the message
01718       // block interface to simplify this
01719       db =
01720         cdr.start_.data_block ()->clone_nocopy ();
01721 
01722       if (db == 0 || db->size ((wr_bytes) +
01723                                ACE_CDR::MAX_ALIGNMENT) == -1)
01724         return 0;
01725 
01726       // Replace our data block by using the incoming CDR stream.
01727       db = this->start_.replace_data_block (db);
01728 
01729       // Align the start_ message block.
01730       ACE_CDR::mb_align (&this->start_);
01731 
01732       // Clear the DONT_DELETE flag if it has been set
01733       this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE);
01734     }
01735 
01736   // Now do the copy
01737   (void) ACE_OS::memcpy (this->start_.wr_ptr (),
01738                          cdr.start_.rd_ptr (),
01739                          wr_bytes);
01740 
01741   // Set the read pointer position to the same point as that was in
01742   // <incoming> cdr.
01743   this->start_.rd_ptr (rd_bytes);
01744   this->start_.wr_ptr (wr_bytes);
01745 
01746   // We have changed the read & write pointers for the incoming
01747   // stream. Set them back to the positions that they were before..
01748   cdr.start_.rd_ptr (rd_bytes);
01749   cdr.start_.wr_ptr (wr_bytes);
01750 
01751   this->major_version_ = cdr.major_version_;
01752   this->minor_version_ = cdr.minor_version_;
01753 
01754   // Copy the char/wchar translators
01755   this->char_translator_ = cdr.char_translator_;
01756   this->wchar_translator_ = cdr.wchar_translator_;
01757 
01758   return db;
01759 }
01760 
01761 ACE_Message_Block*
01762 ACE_InputCDR::steal_contents (void)
01763 {
01764   ACE_Message_Block* block = this->start_.clone ();
01765   this->start_.data_block (block->data_block ()->clone ());
01766 
01767   // If at all our message had a DONT_DELETE flag set, just clear it
01768   // off.
01769   this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE);
01770 
01771   ACE_CDR::mb_align (&this->start_);
01772 
01773   return block;
01774 }
01775 
01776 void
01777 ACE_InputCDR::reset_contents (void)
01778 {
01779   this->start_.data_block (this->start_.data_block ()->clone_nocopy ());
01780 
01781   // Reset the flags...
01782   this->start_.clr_self_flags (ACE_Message_Block::DONT_DELETE);
01783 }
01784 
01785 // --------------------------------------------------------------
01786 
01787 ACE_Char_Codeset_Translator::~ACE_Char_Codeset_Translator (void)
01788 {
01789 }
01790 
01791 // --------------------------------------------------------------
01792 
01793 ACE_WChar_Codeset_Translator::~ACE_WChar_Codeset_Translator (void)
01794 {
01795 }
01796 
01797 // --------------------------------------------------------------
01798 
01799 ACE_CDR::Boolean
01800 operator<< (ACE_OutputCDR &os, const ACE_CString &x)
01801 {
01802   os.write_string (x);
01803   return os.good_bit ();
01804 }
01805 
01806 ACE_CDR::Boolean
01807 operator>> (ACE_InputCDR &is, ACE_CString &x)
01808 {
01809   is.read_string (x);
01810   return is.good_bit ();
01811 }
01812 
01813 #if defined (GEN_OSTREAM_OPS)
01814 
01815 std::ostream&
01816 operator<< (std::ostream &os, ACE_OutputCDR::from_boolean x)
01817 {
01818   return (x.val_ ? os << "true" : os << "false");
01819 }
01820 
01821 std::ostream&
01822 operator<< (std::ostream &os, ACE_OutputCDR::from_char x)
01823 {
01824   return os << '\'' << x.val_ << '\'';
01825 }
01826 
01827 std::ostream&
01828 operator<< (std::ostream &os, ACE_OutputCDR::from_wchar x)
01829 {
01830   os.setf (ios_base::showbase);
01831   os.setf (ios_base::hex, ios_base::basefield);
01832   os << x.val_;
01833   os.unsetf (ios_base::showbase);
01834   os.setf (ios_base::dec, ios_base::basefield);
01835   return os;
01836 }
01837 
01838 std::ostream&
01839 operator<< (std::ostream &os, ACE_OutputCDR::from_octet x)
01840 {
01841   // Same format (hex) and no risk of overflow.
01842   ACE_CDR::WChar w = static_cast<ACE_CDR::WChar> (x.val_);
01843   ACE_OutputCDR::from_wchar tmp (w);
01844   return os << tmp;
01845 }
01846 
01847 #endif /* GEN_OSTREAM_OPS */
01848 
01849 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 12:05:22 2008 for ACE by doxygen 1.3.6