Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

CDR_Stream.cpp

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

Generated on Mon Jun 16 11:19:20 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002