CDR_Stream.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   CDR_Stream.h
00006  *
00007  *  $Id: CDR_Stream.h 79028 2007-07-25 08:24:55Z johnnyw $
00008  *
00009  * ACE Common Data Representation (CDR) marshaling and demarshaling
00010  * classes.
00011  *
00012  * This implementation was inspired in the CDR class in SunSoft's
00013  * IIOP engine, but has a completely different implementation and a
00014  * different interface too.
00015  *
00016  * The current implementation assumes that the host has 1-byte,
00017  * 2-byte and 4-byte integral types, and that it has single
00018  * precision and double precision IEEE floats.
00019  * Those assumptions are pretty good these days, with Crays beign
00020  * the only known exception.
00021  *
00022  * Optimizations
00023  * -------------
00024  *  ACE_LACKS_CDR_ALIGNMENT
00025  *  @author Arvind S. Krishna <arvindk@dre.vanderbilt.edu>
00026  *
00027  *  CDR stream ignores alignment when marshaling data. Use this option
00028  *  only when ACE_DISABLE_SWAP_ON_READ can be enabled. This option requires
00029  *  ACE CDR engine to do both marshaling and demarshaling.
00030  *
00031  *
00032  *  @author TAO version by Aniruddha Gokhale <gokhale@cs.wustl.edu>
00033  *  @author Carlos O'Ryan <coryan@cs.wustl.edu>
00034  *  @author ACE version by Jeff Parsons <parsons@cs.wustl.edu>
00035  *  @author Istvan Buki <istvan.buki@euronet.be>
00036  *  @author Codeset translation by Jim Rogers <jrogers@viasoft.com>
00037  */
00038 //=============================================================================
00039 
00040 #ifndef ACE_CDR_STREAM_H
00041 #define ACE_CDR_STREAM_H
00042 
00043 #include /**/ "ace/pre.h"
00044 
00045 #include "ace/CDR_Base.h"
00046 
00047 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00048 # pragma once
00049 #endif /* ACE_LACKS_PRAGMA_ONCE */
00050 
00051 #include "ace/SStringfwd.h"
00052 #include "ace/Message_Block.h"
00053 
00054 #if defined (GEN_OSTREAM_OPS)
00055 #include "ace/streams.h"
00056 #endif /* GEN_OSTREAM_OPS */
00057 
00058 // Stuff used by the ACE CDR classes.
00059 #if defined ACE_LITTLE_ENDIAN
00060 #  define ACE_CDR_BYTE_ORDER 1
00061 // little endian encapsulation byte order has value = 1
00062 #else  /* ! ACE_LITTLE_ENDIAN */
00063 #  define ACE_CDR_BYTE_ORDER 0
00064 // big endian encapsulation byte order has value = 0
00065 #endif /* ! ACE_LITTLE_ENDIAN */
00066 
00067 
00068 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00069 
00070 class ACE_Char_Codeset_Translator;
00071 class ACE_WChar_Codeset_Translator;
00072 
00073 class ACE_InputCDR;
00074 
00075 /**
00076  * @class ACE_OutputCDR
00077  *
00078  * @brief A CDR stream for writing, i.e. for marshalling.
00079  *
00080  * This class is based on the the CORBA spec for Java (98-02-29),
00081  * java class omg.org.CORBA.portable.OutputStream.  It diverts in
00082  * a few ways:
00083  * + Operations taking arrays don't have offsets, because in C++
00084  *   it is easier to describe an array starting from x+offset.
00085  * + Operations return an error status, because exceptions are
00086  *   not widely available in C++ (yet).
00087  */
00088 class ACE_Export ACE_OutputCDR
00089 {
00090 public:
00091   /**
00092    * The Codeset translators need access to some private members to
00093    * efficiently marshal arrays
00094    * For reading from an output CDR stream.
00095    */
00096   friend class ACE_Char_Codeset_Translator;
00097   friend class ACE_WChar_Codeset_Translator;
00098   friend class ACE_InputCDR;
00099 
00100   /// Default constructor, allocates @a size bytes in the internal
00101   /// buffer, if @a size == 0 it allocates the default size.
00102   ACE_OutputCDR (size_t size = 0,
00103                  int byte_order = ACE_CDR_BYTE_ORDER,
00104                  ACE_Allocator* buffer_allocator = 0,
00105                  ACE_Allocator* data_block_allocator = 0,
00106                  ACE_Allocator* message_block_allocator = 0,
00107                  size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF,
00108                  ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00109                  ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00110 
00111   /// Build a CDR stream with an initial buffer, it will *not* remove
00112   /// <data>, since it did not allocated it.  It's important to be careful
00113   /// with the alignment of <data>.
00114   /**
00115    * Create an output stream from an arbitrary buffer, care must be
00116    * exercised with alignment, because this contructor will align if
00117    * needed.  In this case @a data will not point to the start of the
00118    * output stream. @c begin()->rd_ptr() points to the start of the
00119    * output stream.  See @c ACE_ptr_align_binary() to properly align a
00120    * pointer and use ACE_CDR::MAX_ALIGNMENT for the correct alignment.
00121    */
00122   ACE_OutputCDR (char *data,
00123                  size_t size,
00124                  int byte_order = ACE_CDR_BYTE_ORDER,
00125                  ACE_Allocator* buffer_allocator = 0,
00126                  ACE_Allocator* data_block_allocator = 0,
00127                  ACE_Allocator* message_block_allocator = 0,
00128                  size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF,
00129                  ACE_CDR::Octet giop_major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00130                  ACE_CDR::Octet giop_minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00131 
00132   /// Build a CDR stream with an initial data block, it will *not* remove
00133   /// <data_block>, since it did not allocated it.  It's important to be
00134   // careful with the alignment of <data_block>.
00135   /**
00136    * Create an output stream from an arbitrary data block, care must be
00137    * exercised with alignment, because this contructor will align if
00138    * needed.  In this case @a data_block will not point to the
00139    * start of the output stream. begin()->rd_ptr() points to the start
00140    * off the output stream.  See ACE_ptr_align_binary() to properly align a
00141    * pointer and use ACE_CDR::MAX_ALIGNMENT for the correct alignment.
00142    */
00143   ACE_OutputCDR (ACE_Data_Block *data_block,
00144                  int byte_order = ACE_CDR_BYTE_ORDER,
00145                  ACE_Allocator* message_block_allocator = 0,
00146                  size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF,
00147                  ACE_CDR::Octet giop_major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00148                  ACE_CDR::Octet giop_minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00149 
00150   /// Build a CDR stream with an initial Message_Block chain, it will
00151   /// *not* remove @a data, since it did not allocate it.
00152   ACE_OutputCDR (ACE_Message_Block *data,
00153                  int byte_order = ACE_CDR_BYTE_ORDER,
00154                  size_t memcpy_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF,
00155                  ACE_CDR::Octet giop_major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00156                  ACE_CDR::Octet giop_minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00157 
00158   /// destructor
00159   ~ACE_OutputCDR (void);
00160 
00161   /**
00162    * Disambiguate overload when inserting booleans, octets, chars, and
00163    * bounded strings.
00164    */
00165   //@{ @name Helper classes
00166 
00167   struct ACE_Export from_boolean
00168   {
00169     explicit from_boolean (ACE_CDR::Boolean b);
00170     ACE_CDR::Boolean val_;
00171   };
00172 
00173   struct ACE_Export from_octet
00174   {
00175     explicit from_octet (ACE_CDR::Octet o);
00176     ACE_CDR::Octet val_;
00177   };
00178 
00179   struct ACE_Export from_char
00180   {
00181     explicit from_char (ACE_CDR::Char c);
00182     ACE_CDR::Char val_;
00183   };
00184 
00185   struct ACE_Export from_wchar
00186   {
00187     explicit from_wchar (ACE_CDR::WChar wc);
00188     ACE_CDR::WChar val_;
00189   };
00190 
00191   struct ACE_Export from_string
00192   {
00193     from_string (ACE_CDR::Char* s,
00194                  ACE_CDR::ULong b,
00195                  ACE_CDR::Boolean nocopy = 0);
00196     from_string (const ACE_CDR::Char* s,
00197                  ACE_CDR::ULong b,
00198                  ACE_CDR::Boolean nocopy = 0);
00199     ACE_CDR::Char *val_;
00200     ACE_CDR::ULong bound_;
00201     ACE_CDR::Boolean nocopy_;
00202   };
00203 
00204   struct ACE_Export from_wstring
00205   {
00206     from_wstring (ACE_CDR::WChar* ws,
00207                   ACE_CDR::ULong b,
00208                   ACE_CDR::Boolean nocopy = 0);
00209     from_wstring (const ACE_CDR::WChar* ws,
00210                   ACE_CDR::ULong b,
00211                   ACE_CDR::Boolean nocopy = 0);
00212     ACE_CDR::WChar *val_;
00213     ACE_CDR::ULong bound_;
00214     ACE_CDR::Boolean nocopy_;
00215   };
00216   //@}
00217 
00218   // Return 0 on failure and 1 on success.
00219   //@{ @name Write operations
00220   ACE_CDR::Boolean write_boolean (ACE_CDR::Boolean x);
00221   ACE_CDR::Boolean write_char (ACE_CDR::Char x);
00222   ACE_CDR::Boolean write_wchar (ACE_CDR::WChar x);
00223   ACE_CDR::Boolean write_octet (ACE_CDR::Octet x);
00224   ACE_CDR::Boolean write_short (ACE_CDR::Short x);
00225   ACE_CDR::Boolean write_ushort (ACE_CDR::UShort x);
00226   ACE_CDR::Boolean write_long (ACE_CDR::Long x);
00227   ACE_CDR::Boolean write_ulong (ACE_CDR::ULong x);
00228   ACE_CDR::Boolean write_longlong (const ACE_CDR::LongLong &x);
00229   ACE_CDR::Boolean write_ulonglong (const ACE_CDR::ULongLong &x);
00230   ACE_CDR::Boolean write_float (ACE_CDR::Float x);
00231   ACE_CDR::Boolean write_double (const ACE_CDR::Double &x);
00232   ACE_CDR::Boolean write_longdouble (const ACE_CDR::LongDouble &x);
00233 
00234   // Overwrite the stream at the specified location that is previously
00235   // written as a long type placeholder. There is no alignment required
00236   // since the alignment is done before writing the long type placeholder.
00237   ACE_CDR::Boolean replace (ACE_CDR::Long x, char* loc);
00238 
00239   /// For string we offer methods that accept a precomputed length.
00240   ACE_CDR::Boolean write_string (const ACE_CDR::Char *x);
00241   ACE_CDR::Boolean write_string (ACE_CDR::ULong len,
00242                                  const ACE_CDR::Char *x);
00243   ACE_CDR::Boolean write_string (const ACE_CString &x);
00244   ACE_CDR::Boolean write_wstring (const ACE_CDR::WChar *x);
00245   ACE_CDR::Boolean write_wstring (ACE_CDR::ULong length,
00246                                   const ACE_CDR::WChar *x);
00247   //@}
00248 
00249   /// @note the portion written starts at <x> and ends
00250   ///    at <x + length>.
00251   /// The length is *NOT* stored into the CDR stream.
00252   //@{ @name Array write operations
00253   ACE_CDR::Boolean write_boolean_array (const ACE_CDR::Boolean *x,
00254                                         ACE_CDR::ULong length);
00255   ACE_CDR::Boolean write_char_array (const ACE_CDR::Char *x,
00256                                      ACE_CDR::ULong length);
00257   ACE_CDR::Boolean write_wchar_array (const ACE_CDR::WChar* x,
00258                                       ACE_CDR::ULong length);
00259   ACE_CDR::Boolean write_octet_array (const ACE_CDR::Octet* x,
00260                                       ACE_CDR::ULong length);
00261   ACE_CDR::Boolean write_short_array (const ACE_CDR::Short *x,
00262                                       ACE_CDR::ULong length);
00263   ACE_CDR::Boolean write_ushort_array (const ACE_CDR::UShort *x,
00264                                        ACE_CDR::ULong length);
00265   ACE_CDR::Boolean write_long_array (const ACE_CDR::Long *x,
00266                                      ACE_CDR::ULong length);
00267   ACE_CDR::Boolean write_ulong_array (const ACE_CDR::ULong *x,
00268                                       ACE_CDR::ULong length);
00269   ACE_CDR::Boolean write_longlong_array (const ACE_CDR::LongLong* x,
00270                                          ACE_CDR::ULong length);
00271   ACE_CDR::Boolean write_ulonglong_array (const ACE_CDR::ULongLong *x,
00272                                           ACE_CDR::ULong length);
00273   ACE_CDR::Boolean write_float_array (const ACE_CDR::Float *x,
00274                                       ACE_CDR::ULong length);
00275   ACE_CDR::Boolean write_double_array (const ACE_CDR::Double *x,
00276                                        ACE_CDR::ULong length);
00277   ACE_CDR::Boolean write_longdouble_array (const ACE_CDR::LongDouble* x,
00278                                            ACE_CDR::ULong length);
00279 
00280   /// Write an octet array contained inside a MB, this can be optimized
00281   /// to minimize copies.
00282   ACE_CDR::Boolean write_octet_array_mb (const ACE_Message_Block* mb);
00283   //@}
00284 
00285   /**
00286    * Return 0 on failure and 1 on success.
00287    */
00288   //@{ @name Append contents of own CDR stream to another
00289   ACE_CDR::Boolean append_boolean (ACE_InputCDR &);
00290   ACE_CDR::Boolean append_char (ACE_InputCDR &);
00291   ACE_CDR::Boolean append_wchar (ACE_InputCDR &);
00292   ACE_CDR::Boolean append_octet (ACE_InputCDR &);
00293   ACE_CDR::Boolean append_short (ACE_InputCDR &);
00294   ACE_CDR::Boolean append_ushort (ACE_InputCDR &);
00295   ACE_CDR::Boolean append_long (ACE_InputCDR &);
00296   ACE_CDR::Boolean append_ulong (ACE_InputCDR &);
00297   ACE_CDR::Boolean append_longlong (ACE_InputCDR &);
00298   ACE_CDR::Boolean append_ulonglong (ACE_InputCDR &);
00299   ACE_CDR::Boolean append_float (ACE_InputCDR &);
00300   ACE_CDR::Boolean append_double (ACE_InputCDR &);
00301   ACE_CDR::Boolean append_longdouble (ACE_InputCDR &);
00302 
00303   ACE_CDR::Boolean append_wstring (ACE_InputCDR &);
00304   ACE_CDR::Boolean append_string (ACE_InputCDR &);
00305   //@}
00306 
00307   /// Returns @c false if an error has ocurred.
00308   /**
00309    * @note The only expected error is to run out of memory.
00310    */
00311   bool good_bit (void) const;
00312 
00313   /// Reuse the CDR stream to write on the old buffer.
00314   void reset (void);
00315 
00316   /// Add the length of each message block in the chain.
00317   size_t total_length (void) const;
00318 
00319   /**
00320    * Return the start of the message block chain for this CDR stream.
00321    * @note The complete CDR stream is represented by a chain of
00322    * message blocks.
00323    */
00324   const ACE_Message_Block *begin (void) const;
00325 
00326   /// Return the last message in the chain that is is use.
00327   const ACE_Message_Block *end (void) const;
00328 
00329   /// Return the <current_> message block in chain.
00330   const ACE_Message_Block *current (void) const;
00331 
00332   /// Replace the message block chain with a single message block.
00333   /**
00334    * Upon successful completion, there will be a single message block
00335    * containing the data from the complete message block chain.
00336    *
00337    * @note The only expected error is to run out of memory.
00338    */
00339   int consolidate (void);
00340 
00341   /**
00342    * Access the underlying buffer (read only).  @note This
00343    * method only returns a pointer to the first block in the
00344    * chain.
00345    */
00346   const char *buffer (void) const;
00347 
00348   /**
00349    * Return the size of first message block in the block chain. @note This
00350    * method only returns information about the first block in the
00351    * chain.
00352    */
00353   size_t length (void) const;
00354 
00355   /**
00356    * Utility function to allow the user more flexibility.
00357    * Pads the stream up to the nearest <alignment>-byte boundary.
00358    * Argument MUST be a power of 2.
00359    * Returns 0 on success and -1 on failure.
00360    */
00361   int align_write_ptr (size_t alignment);
00362 
00363   /// Access the codeset translators. They can be null!
00364   ACE_Char_Codeset_Translator *char_translator (void) const;
00365   ACE_WChar_Codeset_Translator *wchar_translator (void) const;
00366 
00367   /// Set the char codeset translator.
00368   void char_translator (ACE_Char_Codeset_Translator *);
00369   /// Set the wchar codeset translator.
00370   void wchar_translator (ACE_WChar_Codeset_Translator *);
00371 
00372   /// set the global size of serialized wchars. This may be different
00373   /// than the size of a wchar_t.
00374   static void wchar_maxbytes (size_t max_bytes);
00375 
00376   /// access the serialized size of wchars.
00377   static size_t wchar_maxbytes (void);
00378 
00379   /**
00380    * Return alignment of the wr_ptr(), with respect to the start of
00381    * the CDR stream.  This is not the same as the alignment of
00382    * current->wr_ptr()!
00383    */
00384   size_t current_alignment (void) const;
00385 
00386   /**
00387    * Returns (in @a buf) the next position in the buffer aligned to
00388    * @a size, it advances the Message_Block wr_ptr past the data
00389    * (i.e., @a buf + @a size). If necessary it grows the Message_Block
00390    * buffer.  Sets the good_bit to false and returns a -1 on failure.
00391    */
00392   int adjust (size_t size,
00393               char *&buf);
00394 
00395   /// As above, but now the size and alignment requirements may be
00396   /// different.
00397   int adjust (size_t size,
00398               size_t align,
00399               char *&buf);
00400 
00401   /// If non-zero then this stream is writing in non-native byte order,
00402   /// this is only meaningful if ACE_ENABLE_SWAP_ON_WRITE is defined.
00403   bool do_byte_swap (void) const;
00404 
00405   /// If <do_byte_swap> returns 0, this returns ACE_CDR_BYTE_ORDER else
00406   /// it returns !ACE_CDR_BYTE_ORDER.
00407   int byte_order (void) const;
00408 
00409   /// For use by a gateway, which creates the output stream for the
00410   /// reply to the client in its native byte order, but which must
00411   /// send the reply in the byte order of the target's reply to the
00412   /// gateway.
00413   void reset_byte_order (int byte_order);
00414 
00415   /// set GIOP version info
00416   void set_version (ACE_CDR::Octet major, ACE_CDR::Octet minor);
00417 
00418   /// Set the underlying GIOP version..
00419   void get_version (ACE_CDR::Octet &major, ACE_CDR::Octet &minor);
00420 
00421 private:
00422 
00423   // Find the message block in the chain of message blocks
00424   // that the provide location locates.
00425   ACE_Message_Block* find (char* loc);
00426 
00427   /// disallow copying...
00428   ACE_OutputCDR (const ACE_OutputCDR& rhs);
00429   ACE_OutputCDR& operator= (const ACE_OutputCDR& rhs);
00430 
00431   ACE_CDR::Boolean write_1 (const ACE_CDR::Octet *x);
00432   ACE_CDR::Boolean write_2 (const ACE_CDR::UShort *x);
00433   ACE_CDR::Boolean write_4 (const ACE_CDR::ULong *x);
00434   ACE_CDR::Boolean write_8 (const ACE_CDR::ULongLong *x);
00435   ACE_CDR::Boolean write_16 (const ACE_CDR::LongDouble *x);
00436 
00437   /**
00438    * write an array of @a length elements, each of @a size bytes and the
00439    * start aligned at a multiple of <align>. The elements are assumed
00440    * to be packed with the right alignment restrictions.  It is mostly
00441    * designed for buffers of the basic types.
00442    *
00443    * This operation uses <memcpy>; as explained above it is expected
00444    * that using assignment is faster that <memcpy> for one element,
00445    * but for several elements <memcpy> should be more efficient, it
00446    * could be interesting to find the break even point and optimize
00447    * for that case, but that would be too platform dependent.
00448    */
00449   ACE_CDR::Boolean write_array (const void *x,
00450                                 size_t size,
00451                                 size_t align,
00452                                 ACE_CDR::ULong length);
00453 
00454 
00455   ACE_CDR::Boolean write_wchar_array_i (const ACE_CDR::WChar* x,
00456                                         ACE_CDR::ULong length);
00457 
00458 
00459   /**
00460    * Grow the CDR stream. When it returns @a buf contains a pointer to
00461    * memory in the CDR stream, with at least @a size bytes ahead of it
00462    * and aligned to an <align> boundary. It moved the <wr_ptr> to <buf
00463    * + size>.
00464    */
00465   int grow_and_adjust (size_t size,
00466                        size_t align,
00467                        char *&buf);
00468 
00469 private:
00470   /// The start of the chain of message blocks.
00471   ACE_Message_Block start_;
00472 
00473   /// The current block in the chain where we are writing.
00474   ACE_Message_Block *current_;
00475 
00476 #if !defined (ACE_LACKS_CDR_ALIGNMENT)
00477   /**
00478    * The current alignment as measured from the start of the buffer.
00479    * Usually this coincides with the alignment of the buffer in
00480    * memory, but, when we chain another buffer this "quasi invariant"
00481    * is broken.
00482    * The current_alignment is used to readjust the buffer following
00483    * the stolen message block.
00484    */
00485   size_t current_alignment_;
00486 #endif /* ACE_LACKS_CDR_ALIGNMENT */
00487 
00488   /**
00489    * Is the current block writable.  When we steal a buffer from the
00490    * user and just chain it into the message block we are not supposed
00491    * to write on it, even if it is past the start and end of the
00492    * buffer.
00493    */
00494   bool current_is_writable_;
00495 
00496   /**
00497    * If not zero swap bytes at writing so the created CDR stream byte
00498    * order does *not* match the machine byte order.  The motivation
00499    * for such a beast is that in some setting a few (fast) machines
00500    * can be serving hundreds of slow machines with the opposite byte
00501    * order, so it makes sense (as a load balancing device) to put the
00502    * responsibility in the writers.  THIS IS NOT A STANDARD IN CORBA,
00503    * USE AT YOUR OWN RISK
00504    */
00505   bool do_byte_swap_;
00506 
00507   /// Set to false when an error ocurrs.
00508   bool good_bit_;
00509 
00510   /// Break-even point for copying.
00511   size_t const memcpy_tradeoff_;
00512 
00513 protected:
00514   /// GIOP version information
00515   ACE_CDR::Octet major_version_;
00516   ACE_CDR::Octet minor_version_;
00517 
00518   /// If not nil, invoke for translation of character and string data.
00519   ACE_Char_Codeset_Translator *char_translator_;
00520   ACE_WChar_Codeset_Translator *wchar_translator_;
00521 
00522   /**
00523    * Some wide char codesets may be defined with a maximum number
00524    * of bytes that is smaller than the size of a wchar_t. This means
00525    * that the CDR cannot simply memcpy a block of wchars to and from
00526    * the stream, but must instead realign the bytes appropriately.
00527    * In cases when wchar i/o is not allowed, such as with GIOP 1.0,
00528    * or not having a native wchar codeset defined, the maxbytes is
00529    * set to zero, indicating no wchar data is allowed.
00530    */
00531   static size_t wchar_maxbytes_;
00532 };
00533 
00534 
00535 // ****************************************************************
00536 
00537 /**
00538  * @class ACE_InputCDR
00539  *
00540  * @brief A CDR stream for reading, i.e. for demarshalling.
00541  *
00542  * This class is based on the the CORBA spec for Java (98-02-29),
00543  * java class omg.org.CORBA.portable.InputStream.  It diverts in a
00544  * few ways:
00545  * + Operations to retrieve basic types take parameters by
00546  * reference.
00547  * + Operations taking arrays don't have offsets, because in C++
00548  * it is easier to describe an array starting from x+offset.
00549  * + Operations return an error status, because exceptions are
00550  * not widely available in C++ (yet).
00551  */
00552 class ACE_Export ACE_InputCDR
00553 {
00554 public:
00555   /// The translator need privileged access to efficiently demarshal
00556   /// arrays and the such
00557   friend class ACE_Char_Codeset_Translator;
00558   friend class ACE_WChar_Codeset_Translator;
00559 
00560   /**
00561    * Create an input stream from an arbitrary buffer.  The buffer must
00562    * be properly aligned because this contructor will *not* work if
00563    * the buffer is aligned unproperly.See ACE_ptr_align_binary() for
00564    * instructions on how to align a pointer properly and use
00565    * ACE_CDR::MAX_ALIGNMENT for the correct alignment.
00566    */
00567   ACE_InputCDR (const char *buf,
00568                 size_t bufsiz,
00569                 int byte_order = ACE_CDR_BYTE_ORDER,
00570                 ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00571                 ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00572 
00573   /// Create an empty input stream. The caller is responsible for
00574   /// putting the right data and providing the right alignment.
00575   ACE_InputCDR (size_t bufsiz,
00576                 int byte_order = ACE_CDR_BYTE_ORDER,
00577                 ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00578                 ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00579 
00580   /// Create an input stream from an ACE_Message_Block
00581   /**
00582    * The alignment of the @arg data block is carried into the new
00583    * ACE_InputCDR object. This constructor either increments the
00584    * @arg data reference count, or copies the data (if it's a compound
00585    * message block) so the caller can release the block immediately
00586    * upon return.
00587    */
00588   ACE_InputCDR (const ACE_Message_Block *data,
00589                 int byte_order = ACE_CDR_BYTE_ORDER,
00590                 ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00591                 ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION,
00592                 ACE_Lock* lock = 0);
00593 
00594   /// Create an input stream from an ACE_Data_Block. The <flag>
00595   /// indicates whether the <data> can be deleted by the CDR stream
00596   /// or not
00597   ACE_InputCDR (ACE_Data_Block *data,
00598                 ACE_Message_Block::Message_Flags flag = 0,
00599                 int byte_order = ACE_CDR_BYTE_ORDER,
00600                 ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00601                 ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00602 
00603   /// Create an input stream from an ACE_Data_Block. It also sets the
00604   /// read and write pointers at the desired positions. This would be
00605   /// helpful if the applications desires to create a new CDR stream
00606   /// from a semi-processed datablock.
00607   ACE_InputCDR (ACE_Data_Block *data,
00608                 ACE_Message_Block::Message_Flags flag,
00609                 size_t read_pointer_position,
00610                 size_t write_pointer_position,
00611                 int byte_order = ACE_CDR_BYTE_ORDER,
00612                 ACE_CDR::Octet major_version = ACE_CDR_GIOP_MAJOR_VERSION,
00613                 ACE_CDR::Octet minor_version = ACE_CDR_GIOP_MINOR_VERSION);
00614 
00615   /**
00616    * These make a copy of the current stream state, but do not copy
00617    * the internal buffer, so the same stream can be read multiple
00618    * times efficiently.
00619    */
00620   ACE_InputCDR (const ACE_InputCDR& rhs);
00621 
00622   ACE_InputCDR& operator= (const ACE_InputCDR& rhs);
00623 
00624   /// When interpreting indirected TypeCodes it is useful to make a
00625   /// "copy" of the stream starting in the new position.
00626   ACE_InputCDR (const ACE_InputCDR& rhs,
00627                 size_t size,
00628                 ACE_CDR::Long offset);
00629 
00630   /// This creates an encapsulated stream, the first byte must be (per
00631   /// the spec) the byte order of the encapsulation.
00632   ACE_InputCDR (const ACE_InputCDR& rhs,
00633                 size_t size);
00634 
00635   /// Create an input CDR from an output CDR.
00636   ACE_InputCDR (const ACE_OutputCDR& rhs,
00637                 ACE_Allocator* buffer_allocator = 0,
00638                 ACE_Allocator* data_block_allocator = 0,
00639                 ACE_Allocator* message_block_allocator = 0);
00640 
00641   /// Helper class to transfer the contents from one input CDR to
00642   /// another without requiring any extra memory allocations, data
00643   /// copies or too many temporaries.
00644   struct ACE_Export Transfer_Contents
00645   {
00646     Transfer_Contents (ACE_InputCDR &rhs);
00647 
00648     ACE_InputCDR &rhs_;
00649   };
00650   /// Transfer the contents from <rhs> to a new CDR
00651   ACE_InputCDR (Transfer_Contents rhs);
00652 
00653   /// Destructor
00654   ~ACE_InputCDR (void);
00655 
00656   /// Disambiguate overloading when extracting octets, chars,
00657   /// booleans, and bounded strings
00658   //@{ @name Helper classes
00659 
00660   struct ACE_Export to_boolean
00661   {
00662     explicit to_boolean (ACE_CDR::Boolean &b);
00663     ACE_CDR::Boolean &ref_;
00664   };
00665 
00666   struct ACE_Export to_char
00667   {
00668     explicit to_char (ACE_CDR::Char &c);
00669     ACE_CDR::Char &ref_;
00670   };
00671 
00672   struct ACE_Export to_wchar
00673   {
00674     explicit to_wchar (ACE_CDR::WChar &wc);
00675     ACE_CDR::WChar &ref_;
00676   };
00677 
00678   struct ACE_Export to_octet
00679   {
00680     explicit to_octet (ACE_CDR::Octet &o);
00681     ACE_CDR::Octet &ref_;
00682   };
00683 
00684   struct ACE_Export to_string
00685   {
00686     /**
00687      * @deprecated The constructor taking a non-const string is now
00688      *             deprecated (C++ mapping 00-01-02), but we keep it
00689      *             around for backward compatibility.
00690      */
00691     to_string (ACE_CDR::Char *&s,
00692                ACE_CDR::ULong b);
00693     to_string (const ACE_CDR::Char *&s,
00694                ACE_CDR::ULong b);
00695     const ACE_CDR::Char *&val_;
00696     ACE_CDR::ULong bound_;
00697   };
00698 
00699   struct ACE_Export to_wstring
00700   {
00701     /// The constructor taking a non-const wstring is
00702     /// now deprecated (C++ mapping 00-01-02), but we
00703     /// keep it around for backward compatibility.
00704     to_wstring (ACE_CDR::WChar *&ws,
00705                 ACE_CDR::ULong b);
00706     to_wstring (const ACE_CDR::WChar *&ws,
00707                 ACE_CDR::ULong b);
00708     const ACE_CDR::WChar *&val_;
00709     ACE_CDR::ULong bound_;
00710   };
00711   //@}
00712 
00713   /**
00714    * Return @c false on failure and @c true on success.
00715    */
00716   //@{ @name Read basic IDL types
00717   ACE_CDR::Boolean read_boolean (ACE_CDR::Boolean& x);
00718   ACE_CDR::Boolean read_char (ACE_CDR::Char &x);
00719   ACE_CDR::Boolean read_wchar (ACE_CDR::WChar& x);
00720   ACE_CDR::Boolean read_octet (ACE_CDR::Octet& x);
00721   ACE_CDR::Boolean read_short (ACE_CDR::Short &x);
00722   ACE_CDR::Boolean read_ushort (ACE_CDR::UShort &x);
00723   ACE_CDR::Boolean read_long (ACE_CDR::Long &x);
00724   ACE_CDR::Boolean read_ulong (ACE_CDR::ULong &x);
00725   ACE_CDR::Boolean read_longlong (ACE_CDR::LongLong& x);
00726   ACE_CDR::Boolean read_ulonglong (ACE_CDR::ULongLong& x);
00727   ACE_CDR::Boolean read_float (ACE_CDR::Float &x);
00728   ACE_CDR::Boolean read_double (ACE_CDR::Double &x);
00729   ACE_CDR::Boolean read_longdouble (ACE_CDR::LongDouble &x);
00730 
00731   ACE_CDR::Boolean read_string (ACE_CDR::Char *&x);
00732   ACE_CDR::Boolean read_string (ACE_CString &x);
00733   ACE_CDR::Boolean read_wstring (ACE_CDR::WChar*& x);
00734   //@}
00735 
00736   /**
00737    * The buffer @a x must be large enough to contain @a length
00738    * elements.
00739    * Return @c false on failure and @c true on success.
00740    */
00741   //@{ @name Read basic IDL types arrays
00742   ACE_CDR::Boolean read_boolean_array (ACE_CDR::Boolean* x,
00743                                        ACE_CDR::ULong length);
00744   ACE_CDR::Boolean read_char_array (ACE_CDR::Char *x,
00745                                     ACE_CDR::ULong length);
00746   ACE_CDR::Boolean read_wchar_array (ACE_CDR::WChar* x,
00747                                      ACE_CDR::ULong length);
00748   ACE_CDR::Boolean read_octet_array (ACE_CDR::Octet* x,
00749                                      ACE_CDR::ULong length);
00750   ACE_CDR::Boolean read_short_array (ACE_CDR::Short *x,
00751                                      ACE_CDR::ULong length);
00752   ACE_CDR::Boolean read_ushort_array (ACE_CDR::UShort *x,
00753                                       ACE_CDR::ULong length);
00754   ACE_CDR::Boolean read_long_array (ACE_CDR::Long *x,
00755                                     ACE_CDR::ULong length);
00756   ACE_CDR::Boolean read_ulong_array (ACE_CDR::ULong *x,
00757                                      ACE_CDR::ULong length);
00758   ACE_CDR::Boolean read_longlong_array (ACE_CDR::LongLong* x,
00759                                         ACE_CDR::ULong length);
00760   ACE_CDR::Boolean read_ulonglong_array (ACE_CDR::ULongLong* x,
00761                                          ACE_CDR::ULong length);
00762   ACE_CDR::Boolean read_float_array (ACE_CDR::Float *x,
00763                                      ACE_CDR::ULong length);
00764   ACE_CDR::Boolean read_double_array (ACE_CDR::Double *x,
00765                                       ACE_CDR::ULong length);
00766   ACE_CDR::Boolean read_longdouble_array (ACE_CDR::LongDouble* x,
00767                                           ACE_CDR::ULong length);
00768   //@}
00769 
00770   /**
00771    * Return @c false on failure and @c true on success.
00772    */
00773   //@{ @name Skip elements
00774   ACE_CDR::Boolean skip_boolean (void);
00775   ACE_CDR::Boolean skip_char (void);
00776   ACE_CDR::Boolean skip_wchar (void);
00777   ACE_CDR::Boolean skip_octet (void);
00778   ACE_CDR::Boolean skip_short (void);
00779   ACE_CDR::Boolean skip_ushort (void);
00780   ACE_CDR::Boolean skip_long (void);
00781   ACE_CDR::Boolean skip_ulong (void);
00782   ACE_CDR::Boolean skip_longlong (void);
00783   ACE_CDR::Boolean skip_ulonglong (void);
00784   ACE_CDR::Boolean skip_float (void);
00785   ACE_CDR::Boolean skip_double (void);
00786   ACE_CDR::Boolean skip_longdouble (void);
00787   //@}
00788 
00789   /**
00790    * The next field must be a string, this method skips it. It is
00791    * useful in parsing a TypeCode.
00792    * @return @c false on failure and @c true on success.
00793    */
00794   ACE_CDR::Boolean skip_wstring (void);
00795   ACE_CDR::Boolean skip_string (void);
00796 
00797   /// Skip @a n bytes in the CDR stream.
00798   /**
00799    * @return @c false on failure and @c true on success.
00800    */
00801   ACE_CDR::Boolean skip_bytes (size_t n);
00802 
00803   /// returns @c false if a problem has been detected.
00804   bool good_bit (void) const;
00805 
00806   /**
00807    * @return The start of the message block chain for this CDR
00808    *         stream.
00809    *
00810    * @note In the current implementation the chain has length 1, but
00811    *       we are planning to change that.
00812    */
00813   const ACE_Message_Block* start (void) const;
00814 
00815   // = The following functions are useful to read the contents of the
00816   //   CDR stream from a socket or file.
00817 
00818   /**
00819    * Grow the internal buffer, reset @c rd_ptr to the first byte in
00820    * the new buffer that is properly aligned, and set @c wr_ptr to @c
00821    * rd_ptr @c + @c newsize
00822    */
00823   int grow (size_t newsize);
00824 
00825   /**
00826    * After reading and partially parsing the contents the user can
00827    * detect a change in the byte order, this method will let him/her
00828    * change it.
00829    */
00830   void reset_byte_order (int byte_order);
00831 
00832   /// Re-initialize the CDR stream, copying the contents of the chain
00833   /// of message_blocks starting from @a data.
00834   void reset (const ACE_Message_Block *data,
00835               int byte_order);
00836 
00837   /// Steal the contents from the current CDR.
00838   ACE_Message_Block *steal_contents (void);
00839 
00840   /// Steal the contents of @a cdr and make a shallow copy into this
00841   /// stream.
00842   void steal_from (ACE_InputCDR &cdr);
00843 
00844   /// Exchange data blocks with the caller of this method. The read
00845   /// and write pointers are also exchanged.
00846   /**
00847    * @note We now do only with the start_ message block.
00848    */
00849   void exchange_data_blocks (ACE_InputCDR &cdr);
00850 
00851   /// Copy the data portion from the @c cdr to this cdr and return the
00852   /// data content (ie. the ACE_Data_Block) from this CDR to the
00853   /// caller.
00854   /**
00855    * @note The caller is responsible for managing the memory of the
00856    *       returned ACE_Data_Block.
00857    */
00858   ACE_Data_Block* clone_from (ACE_InputCDR &cdr);
00859 
00860   /// Re-initialize the CDR stream, forgetting about the old contents
00861   /// of the stream and allocating a new buffer (from the allocators).
00862   void reset_contents (void);
00863 
00864   /// Returns the current position for the @c rd_ptr.
00865   char* rd_ptr (void);
00866 
00867   /// Returns the current position for the @c wr_ptr.
00868   char* wr_ptr (void);
00869 
00870   /// Return how many bytes are left in the stream.
00871   size_t length (void) const;
00872 
00873   /**
00874    * Utility function to allow the user more flexibility.
00875    * Skips up to the nearest @a alignment-byte boundary.
00876    * Argument MUST be a power of 2.
00877    *
00878    * @return 0 on success and -1 on failure.
00879    */
00880   int align_read_ptr (size_t alignment);
00881 
00882   /// If @c true then this stream is writing in non-native byte order.
00883   /// This is only meaningful if ACE_ENABLE_SWAP_ON_WRITE is defined.
00884   bool do_byte_swap (void) const;
00885 
00886   /// If @c do_byte_swap() returns @c false, this returns
00887   /// ACE_CDR_BYTE_ORDER else it returns !ACE_CDR_BYTE_ORDER.
00888   int byte_order (void) const;
00889 
00890   /// Access the codeset translators. They can be nil!
00891   ACE_Char_Codeset_Translator *char_translator (void) const;
00892   ACE_WChar_Codeset_Translator *wchar_translator (void) const;
00893 
00894   /// Set the codeset translators.
00895   void char_translator (ACE_Char_Codeset_Translator *);
00896   void wchar_translator (ACE_WChar_Codeset_Translator *);
00897 
00898   /**
00899    * Returns (in @a buf) the next position in the buffer aligned to
00900    * @a size.  It advances the Message_Block @c rd_ptr past the data
00901    * (i.e., @c buf @c + @c size).  Sets the good_bit to @c false and
00902    * returns a -1 on failure.
00903    */
00904   int adjust (size_t size,
00905               char *&buf);
00906 
00907   /// As above, but now the size and alignment requirements may be
00908   /// different.
00909   int adjust (size_t size,
00910               size_t align,
00911               char *&buf);
00912 
00913   /// Set the underlying GIOP version..
00914   void set_version (ACE_CDR::Octet major, ACE_CDR::Octet minor);
00915 
00916   /// Set the underlying GIOP version..
00917   void get_version (ACE_CDR::Octet &major, ACE_CDR::Octet &minor);
00918 
00919 protected:
00920 
00921   /// The start of the chain of message blocks, even though in the
00922   /// current version the chain always has length 1.
00923   ACE_Message_Block start_;
00924 
00925   /// The CDR stream byte order does not match the one on the machine,
00926   /// swapping is needed while reading.
00927   bool do_byte_swap_;
00928 
00929   /// set to @c false when an error occurs.
00930   bool good_bit_;
00931 
00932   /// The GIOP versions for this stream
00933   ACE_CDR::Octet major_version_;
00934   ACE_CDR::Octet minor_version_;
00935 
00936   /// If not nil, invoke for translation of character and string data.
00937   ACE_Char_Codeset_Translator *char_translator_;
00938   ACE_WChar_Codeset_Translator *wchar_translator_;
00939 
00940 private:
00941 
00942   ACE_CDR::Boolean read_1 (ACE_CDR::Octet *x);
00943   ACE_CDR::Boolean read_2 (ACE_CDR::UShort *x);
00944   ACE_CDR::Boolean read_4 (ACE_CDR::ULong *x);
00945   ACE_CDR::Boolean read_8 (ACE_CDR::ULongLong *x);
00946   ACE_CDR::Boolean read_16 (ACE_CDR::LongDouble *x);
00947 
00948   // Several types can be read using the same routines, since TAO
00949   // tries to use native types with known size for each CORBA type.
00950   // We could use void* or char* to make the interface more
00951   // consistent, but using native types let us exploit the strict
00952   // alignment requirements of CDR streams and implement the
00953   // operations using asignment.
00954 
00955   /**
00956    * Read an array of @a length elements, each of @a size bytes and the
00957    * start aligned at a multiple of <align>. The elements are assumed
00958    * to be packed with the right alignment restrictions.  It is mostly
00959    * designed for buffers of the basic types.
00960    *
00961    * This operation uses <memcpy>; as explained above it is expected
00962    * that using assignment is faster that <memcpy> for one element,
00963    * but for several elements <memcpy> should be more efficient, it
00964    * could be interesting to find the break even point and optimize
00965    * for that case, but that would be too platform dependent.
00966    */
00967   ACE_CDR::Boolean read_array (void* x,
00968                                size_t size,
00969                                size_t align,
00970                                ACE_CDR::ULong length);
00971 
00972   /**
00973    * On those occasions when the native codeset for wchar is smaller than
00974    * the size of a wchar_t, such as using UTF-16 with a 4-byte wchar_t, a
00975    * special form of reading the array is needed. Actually, this should be
00976    * a default translator.
00977    */
00978   ACE_CDR::Boolean read_wchar_array_i (ACE_CDR::WChar * x,
00979                                        ACE_CDR::ULong length);
00980 
00981   /// Move the rd_ptr ahead by <offset> bytes.
00982   void rd_ptr (size_t offset);
00983 
00984   /// Points to the continuation field of the current message block.
00985   char* end (void);
00986 };
00987 
00988 // ****************************************************************
00989 
00990 /**
00991  * @class ACE_Char_Codeset_Translator
00992  *
00993  * @brief Codeset translation routines common to both Output and Input
00994  * CDR streams.
00995  *
00996  * This class is a base class for defining codeset translation
00997  * routines to handle the character set translations required by
00998  * both CDR Input streams and CDR Output streams.
00999  *
01000  * Translators are reference counted. This allows for stateful as well
01001  * as stateless translators. Stateless translators will be allocated
01002  * once whereas CDR Streams own their own copy of a stateful translator.
01003  */
01004 class ACE_Export ACE_Char_Codeset_Translator
01005 {
01006 public:
01007   virtual ~ACE_Char_Codeset_Translator ();
01008 
01009   /// Read a single character from the stream, converting from the
01010   /// stream codeset to the native codeset
01011   virtual ACE_CDR::Boolean read_char (ACE_InputCDR&,
01012                                       ACE_CDR::Char&) = 0;
01013 
01014   /// Read a string from the stream, including the length, converting
01015   /// the characters from the stream codeset to the native codeset
01016   virtual ACE_CDR::Boolean read_string (ACE_InputCDR&,
01017                                         ACE_CDR::Char *&) = 0;
01018 
01019   /// Read an array of characters from the stream, converting the
01020   /// characters from the stream codeset to the native codeset.
01021   virtual ACE_CDR::Boolean read_char_array (ACE_InputCDR&,
01022                                             ACE_CDR::Char*,
01023                                             ACE_CDR::ULong) = 0;
01024 
01025   /// Write a single character to the stream, converting from the
01026   /// native codeset to the stream codeset
01027   virtual ACE_CDR::Boolean write_char (ACE_OutputCDR&,
01028                                        ACE_CDR::Char) = 0;
01029 
01030   /// Write a string to the stream, including the length, converting
01031   /// from the native codeset to the stream codeset
01032   virtual ACE_CDR::Boolean write_string (ACE_OutputCDR&,
01033                                          ACE_CDR::ULong,
01034                                          const ACE_CDR::Char*) = 0;
01035 
01036   /// Write an array of characters to the stream, converting from the
01037   /// native codeset to the stream codeset
01038   virtual ACE_CDR::Boolean write_char_array (ACE_OutputCDR&,
01039                                              const ACE_CDR::Char*,
01040                                              ACE_CDR::ULong) = 0;
01041 
01042   virtual ACE_CDR::ULong ncs () = 0;
01043   virtual ACE_CDR::ULong tcs () = 0;
01044 protected:
01045   /// Children have access to low-level routines because they cannot
01046   /// use read_char or something similar (it would recurse).
01047   ACE_CDR::Boolean read_1 (ACE_InputCDR& input,
01048                            ACE_CDR::Octet *x);
01049   ACE_CDR::Boolean write_1 (ACE_OutputCDR& output,
01050                             const ACE_CDR::Octet *x);
01051 
01052   /// Efficiently read @a length elements of size @a size each from
01053   /// <input> into <x>; the data must be aligned to <align>.
01054   ACE_CDR::Boolean read_array (ACE_InputCDR& input,
01055                                void* x,
01056                                size_t size,
01057                                size_t align,
01058                                ACE_CDR::ULong length);
01059 
01060   /**
01061    * Efficiently write @a length elements of size @a size from <x> into
01062    * <output>. Before inserting the elements enough padding is added
01063    * to ensure that the elements will be aligned to <align> in the
01064    * stream.
01065    */
01066   ACE_CDR::Boolean write_array (ACE_OutputCDR& output,
01067                                 const void *x,
01068                                 size_t size,
01069                                 size_t align,
01070                                 ACE_CDR::ULong length);
01071 
01072   /**
01073    * Exposes the stream implementation of <adjust>, this is useful in
01074    * many cases to minimize memory allocations during marshaling.
01075    * On success @a buf will contain a contiguous area in the CDR stream
01076    * that can hold @a size bytes aligned to <align>.
01077    * Results
01078    */
01079   int adjust (ACE_OutputCDR& out,
01080               size_t size,
01081               size_t align,
01082               char *&buf);
01083 
01084   /// Used by derived classes to set errors in the CDR stream.
01085   void good_bit (ACE_OutputCDR& out, bool bit);
01086 
01087   /// Obtain the CDR Stream's major & minor version values.
01088   ACE_CDR::Octet major_version (ACE_InputCDR& input);
01089   ACE_CDR::Octet minor_version (ACE_InputCDR& input);
01090   ACE_CDR::Octet major_version (ACE_OutputCDR& output);
01091   ACE_CDR::Octet minor_version (ACE_OutputCDR& output);
01092 };
01093 
01094 // ****************************************************************
01095 
01096 /**
01097  * @class ACE_WChar_Codeset_Translator
01098  *
01099  * @brief Codeset translation routines common to both Output and Input
01100  * CDR streams.
01101  *
01102  * This class is a base class for defining codeset translation
01103  * routines to handle the character set translations required by
01104  * both CDR Input streams and CDR Output streams.
01105  */
01106 class ACE_Export ACE_WChar_Codeset_Translator
01107 {
01108 public:
01109   virtual ~ACE_WChar_Codeset_Translator ();
01110 
01111   virtual ACE_CDR::Boolean read_wchar (ACE_InputCDR&,
01112                                        ACE_CDR::WChar&) = 0;
01113   virtual ACE_CDR::Boolean read_wstring (ACE_InputCDR&,
01114                                          ACE_CDR::WChar *&) = 0;
01115   virtual ACE_CDR::Boolean read_wchar_array (ACE_InputCDR&,
01116                                              ACE_CDR::WChar*,
01117                                              ACE_CDR::ULong) = 0;
01118   virtual ACE_CDR::Boolean write_wchar (ACE_OutputCDR&,
01119                                         ACE_CDR::WChar) = 0;
01120   virtual ACE_CDR::Boolean write_wstring (ACE_OutputCDR&,
01121                                           ACE_CDR::ULong,
01122                                           const ACE_CDR::WChar*) = 0;
01123   virtual ACE_CDR::Boolean write_wchar_array (ACE_OutputCDR&,
01124                                               const ACE_CDR::WChar*,
01125                                               ACE_CDR::ULong) = 0;
01126 
01127   virtual ACE_CDR::ULong ncs () = 0;
01128   virtual ACE_CDR::ULong tcs () = 0;
01129 protected:
01130   /// Children have access to low-level routines because they cannot
01131   /// use read_char or something similar (it would recurse).
01132   ACE_CDR::Boolean read_1 (ACE_InputCDR& input,
01133                            ACE_CDR::Octet *x);
01134   ACE_CDR::Boolean read_2 (ACE_InputCDR& input,
01135                            ACE_CDR::UShort *x);
01136   ACE_CDR::Boolean read_4 (ACE_InputCDR& input,
01137                            ACE_CDR::ULong *x);
01138   ACE_CDR::Boolean write_1 (ACE_OutputCDR& output,
01139                             const ACE_CDR::Octet *x);
01140   ACE_CDR::Boolean write_2 (ACE_OutputCDR& output,
01141                             const ACE_CDR::UShort *x);
01142   ACE_CDR::Boolean write_4 (ACE_OutputCDR& output,
01143                             const ACE_CDR::ULong *x);
01144 
01145   /// Efficiently read @a length elements of size @a size each from
01146   /// <input> into <x>; the data must be aligned to <align>.
01147   ACE_CDR::Boolean read_array (ACE_InputCDR& input,
01148                                void* x,
01149                                size_t size,
01150                                size_t align,
01151                                ACE_CDR::ULong length);
01152 
01153   /**
01154    * Efficiently write @a length elements of size @a size from <x> into
01155    * <output>. Before inserting the elements enough padding is added
01156    * to ensure that the elements will be aligned to <align> in the
01157    * stream.
01158    */
01159   ACE_CDR::Boolean write_array (ACE_OutputCDR& output,
01160                                 const void *x,
01161                                 size_t size,
01162                                 size_t align,
01163                                 ACE_CDR::ULong length);
01164 
01165   /**
01166    * Exposes the stream implementation of <adjust>, this is useful in
01167    * many cases to minimize memory allocations during marshaling.
01168    * On success @a buf will contain a contiguous area in the CDR stream
01169    * that can hold @a size bytes aligned to <align>.
01170    * Results
01171    */
01172   int adjust (ACE_OutputCDR& out,
01173               size_t size,
01174               size_t align,
01175               char *&buf);
01176 
01177   /// Used by derived classes to set errors in the CDR stream.
01178   void good_bit (ACE_OutputCDR& out, bool bit);
01179 
01180   /// Obtain the CDR Stream's major & minor version values.
01181   ACE_CDR::Octet major_version (ACE_InputCDR& input);
01182   ACE_CDR::Octet minor_version (ACE_InputCDR& input);
01183   ACE_CDR::Octet major_version (ACE_OutputCDR& output);
01184   ACE_CDR::Octet minor_version (ACE_OutputCDR& output);
01185 
01186 };
01187 
01188 // @@ These operators should not be inlined since they force SString.h
01189 //    to be included in this header.
01190 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01191                                                const ACE_CString &x);
01192 
01193 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01194                                                ACE_CString &x);
01195 
01196 
01197 ACE_END_VERSIONED_NAMESPACE_DECL
01198 
01199 #if defined (__ACE_INLINE__)
01200 # include "ace/CDR_Stream.inl"
01201 #else /* __ACE_INLINE__ */
01202 
01203 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01204 
01205 // Not used by CORBA or TAO
01206 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01207                                                ACE_CDR::Char x);
01208 // CDR output operators for primitive types
01209 
01210 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01211                                                ACE_CDR::Short x);
01212 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01213                                                ACE_CDR::UShort x);
01214 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01215                                                ACE_CDR::Long x);
01216 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01217                                                ACE_CDR::ULong x);
01218 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01219                                                ACE_CDR::LongLong x);
01220 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01221                                                ACE_CDR::ULongLong x);
01222 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR& os,
01223                                                ACE_CDR::LongDouble x);
01224 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01225                                                ACE_CDR::Float x);
01226 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01227                                                ACE_CDR::Double x);
01228 
01229 // CDR output operator from helper classes
01230 
01231 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01232                                                ACE_OutputCDR::from_boolean x);
01233 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01234                                                ACE_OutputCDR::from_char x);
01235 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01236                                                ACE_OutputCDR::from_wchar x);
01237 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01238                                                ACE_OutputCDR::from_octet x);
01239 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01240                                                ACE_OutputCDR::from_string x);
01241 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01242                                                ACE_OutputCDR::from_wstring x);
01243 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01244                                                const ACE_CDR::Char* x);
01245 extern ACE_Export ACE_CDR::Boolean operator<< (ACE_OutputCDR &os,
01246                                                const ACE_CDR::WChar* x);
01247 
01248 // Not used by CORBA or TAO
01249 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01250                                                ACE_CDR::Char &x);
01251 // CDR input operators for primitive types
01252 
01253 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01254                                                ACE_CDR::Short &x);
01255 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01256                                                ACE_CDR::UShort &x);
01257 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01258                                                ACE_CDR::Long &x);
01259 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01260                                                ACE_CDR::ULong &x);
01261 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01262                                                ACE_CDR::LongLong &x);
01263 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01264                                                ACE_CDR::ULongLong &x);
01265 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01266                                                ACE_CDR::LongDouble &x);
01267 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01268                                                ACE_CDR::Float &x);
01269 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01270                                                ACE_CDR::Double &x);
01271 
01272 // CDR input operator from helper classes
01273 
01274 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01275                                                ACE_InputCDR::to_boolean x);
01276 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01277                                                ACE_InputCDR::to_char x);
01278 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01279                                                ACE_InputCDR::to_wchar x);
01280 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01281                                                ACE_InputCDR::to_octet x);
01282 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01283                                                ACE_InputCDR::to_string x);
01284 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01285                                                ACE_InputCDR::to_wstring x);
01286 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01287                                                ACE_CDR::Char*& x);
01288 extern ACE_Export ACE_CDR::Boolean operator>> (ACE_InputCDR &is,
01289                                                ACE_CDR::WChar*& x);
01290 
01291 ACE_END_VERSIONED_NAMESPACE_DECL
01292 
01293 #endif /* __ACE_INLINE__ */
01294 
01295 #if defined (GEN_OSTREAM_OPS)
01296 
01297 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01298 
01299 // ostream insertion operators for debugging code generated from IDL. All
01300 // but these below are either in generated code itself or are unambiguous
01301 // primitive types.
01302 
01303 ACE_Export std::ostream& operator<< (std::ostream &os,
01304                                      ACE_OutputCDR::from_boolean x);
01305 
01306 ACE_Export std::ostream& operator<< (std::ostream &os,
01307                                      ACE_OutputCDR::from_char x);
01308 
01309 ACE_Export std::ostream& operator<< (std::ostream &os,
01310                                      ACE_OutputCDR::from_wchar x);
01311 
01312 ACE_Export std::ostream& operator<< (std::ostream &os,
01313                                      ACE_OutputCDR::from_octet x);
01314 
01315 ACE_END_VERSIONED_NAMESPACE_DECL
01316 
01317 #endif /* GEN_OSTREAM_OPS */
01318 
01319 #include /**/ "ace/post.h"
01320 
01321 #endif /* ACE_CDR_STREAM_H */

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