CDR_Stream.cpp

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

Generated on Thu Nov 9 09:41:48 2006 for ACE by doxygen 1.3.6