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

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7