CDR_Base.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   CDR_Base.h
00006  *
00007  *  CDR_Base.h,v 4.32 2006/05/05 07:38:31 jwillemsen Exp
00008  *
00009  * ACE Common Data Representation (CDR) basic types.
00010  *
00011  * The current implementation assumes that the host has 1-byte,
00012  * 2-byte and 4-byte integral types, and that it has single
00013  * precision and double precision IEEE floats.
00014  * Those assumptions are pretty good these days, with Crays being
00015  * the only known exception.
00016  *
00017  *
00018  *  @author TAO version by
00019  *  @author Aniruddha Gokhale <gokhale@cs.wustl.edu>
00020  *  @author Carlos O'Ryan<coryan@cs.wustl.edu>
00021  *  @author ACE version by
00022  *  @author Jeff Parsons <parsons@cs.wustl.edu>
00023  *  @author Istvan Buki <istvan.buki@euronet.be>
00024  */
00025 //=============================================================================
00026 
00027 
00028 #ifndef ACE_CDR_BASE_H
00029 #define ACE_CDR_BASE_H
00030 
00031 #include /**/ "ace/pre.h"
00032 
00033 #include "ace/config-all.h"
00034 
00035 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00036 # pragma once
00037 #endif /* ACE_LACKS_PRAGMA_ONCE */
00038 
00039 #include "ace/Basic_Types.h"
00040 #include "ace/Default_Constants.h"
00041 
00042 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00043 
00044 class ACE_Message_Block;
00045 
00046 /**
00047  * @class ACE_CDR
00048  *
00049  * @brief Keep constants and some routines common to both Output and
00050  * Input CDR streams.
00051  */
00052 class ACE_Export ACE_CDR
00053 {
00054 public:
00055   // = Constants defined by the CDR protocol.
00056   // By defining as many of these constants as possible as enums we
00057   // ensure they get inlined and avoid pointless static memory
00058   // allocations.
00059 
00060   enum
00061   {
00062     // Note that some of these get reused as part of the standard
00063     // binary format: unsigned is the same size as its signed cousin,
00064     // float is LONG_SIZE, and double is LONGLONG_SIZE.
00065 
00066     OCTET_SIZE = 1,
00067     SHORT_SIZE = 2,
00068     LONG_SIZE = 4,
00069     LONGLONG_SIZE = 8,
00070     LONGDOUBLE_SIZE = 16,
00071 
00072     OCTET_ALIGN = 1,
00073     SHORT_ALIGN = 2,
00074     LONG_ALIGN = 4,
00075     LONGLONG_ALIGN = 8,
00076     /// @note the CORBA LongDouble alignment requirements do not
00077     /// match its size...
00078     LONGDOUBLE_ALIGN = 8,
00079 
00080     /// Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long
00081     /// double", size as above).
00082     MAX_ALIGNMENT = 8,
00083 
00084     /// The default buffer size.
00085     /**
00086      * @todo We want to add options to control this
00087      *   default value, so this constant should be read as the default
00088      *   default value ;-)
00089      */
00090     DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE,
00091 
00092     /// The buffer size grows exponentially until it reaches this size;
00093     /// afterwards it grows linearly using the next constant
00094     EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX,
00095 
00096     /// Once exponential growth is ruled out the buffer size increases
00097     /// in chunks of this size, note that this constants have the same
00098     /// value right now, but it does not need to be so.
00099     LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
00100   };
00101 
00102   /**
00103    * Do byte swapping for each basic IDL type size.  There exist only
00104    * routines to put byte, halfword (2 bytes), word (4 bytes),
00105    * doubleword (8 bytes) and quadword (16 byte); because those are
00106    * the IDL basic type sizes.
00107    */
00108   static void swap_2 (const char *orig, char *target);
00109   static void swap_4 (const char *orig, char *target);
00110   static void swap_8 (const char *orig, char *target);
00111   static void swap_16 (const char *orig, char *target);
00112   static void swap_2_array (const char *orig,
00113                             char *target,
00114                             size_t length);
00115   static void swap_4_array (const char *orig,
00116                             char *target,
00117                             size_t length);
00118   static void swap_8_array (const char *orig,
00119                             char *target,
00120                             size_t length);
00121   static void swap_16_array (const char *orig,
00122                              char *target,
00123                              size_t length);
00124 
00125   /// Align the message block to ACE_CDR::MAX_ALIGNMENT,
00126   /// set by the CORBA spec at 8 bytes.
00127   static void mb_align (ACE_Message_Block *mb);
00128 
00129   /**
00130    * Compute the size of the smallest buffer that can contain at least
00131    * @a minsize bytes.
00132    * To understand how a "best fit" is computed look at the
00133    * algorithm in the code.
00134    * Basically the buffers grow exponentially, up to a certain point,
00135    * then the buffer size grows linearly.
00136    * The advantage of this algorithm is that is rapidly grows to a
00137    * large value, but does not explode at the end.
00138    */
00139   static size_t first_size (size_t minsize);
00140 
00141   /// Compute not the smallest, but the second smallest buffer that
00142   /// will fir @a minsize bytes.
00143   static size_t next_size (size_t minsize);
00144 
00145   /**
00146    * Increase the capacity of mb to contain at least @a minsize bytes.
00147    * If @a minsize is zero the size is increased by an amount at least
00148    * large enough to contain any of the basic IDL types.
00149    * @retval -1 Failure
00150    * @retval 0 Success.
00151    */
00152   static int grow (ACE_Message_Block *mb, size_t minsize);
00153 
00154   /// Copy a message block chain into a single message block,
00155   /// preserving the alignment of the first message block of the
00156   /// original stream, not the following message blocks.
00157   static void consolidate (ACE_Message_Block *dst,
00158                           const ACE_Message_Block *src);
00159 
00160   static size_t total_length (const ACE_Message_Block *begin,
00161                               const ACE_Message_Block *end);
00162 
00163   /**
00164    * @name Basic OMG IDL Types
00165    *
00166    * These types are for use in the CDR classes.  The cleanest way to
00167    * avoid complaints from all compilers is to define them all.
00168    */
00169   //@{
00170   typedef bool Boolean;
00171   typedef unsigned char Octet;
00172   typedef char Char;
00173   typedef ACE_WCHAR_T WChar;
00174   typedef ACE_INT16 Short;
00175   typedef ACE_UINT16 UShort;
00176   typedef ACE_INT32 Long;
00177   typedef ACE_UINT32 ULong;
00178   typedef ACE_UINT64 ULongLong;
00179 
00180 #   if (defined (_MSC_VER)) || (defined (__BORLANDC__))
00181       typedef __int64 LongLong;
00182 #   elif ACE_SIZEOF_LONG == 8 && !defined(_CRAYMPP)
00183       typedef long LongLong;
00184 #   elif defined(__TANDEM)
00185       typedef long long LongLong;
00186 #   elif ACE_SIZEOF_LONG_LONG == 8 && !defined (ACE_LACKS_LONGLONG_T)
00187 #     if defined (sun) && !defined (ACE_LACKS_U_LONGLONG_T)
00188               // sun #defines   u_longlong_t, maybe other platforms do also.
00189               // Use it, at least with g++, so that its -pedantic doesn't
00190               // complain about no ANSI C++ long long.
00191               typedef   longlong_t LongLong;
00192 #     else
00193               // LynxOS 2.5.0   and Linux don't have u_longlong_t.
00194               typedef   long long LongLong;
00195 #     endif /* sun */
00196 #   else  /* no native 64 bit integer type */
00197 #     define NONNATIVE_LONGLONG
00198       struct ACE_Export LongLong
00199         {
00200 #     if defined (ACE_BIG_ENDIAN)
00201           ACE_CDR::Long h;
00202           ACE_CDR::Long l;
00203 #     else
00204           ACE_CDR::Long l;
00205           ACE_CDR::Long h;
00206 #     endif /* ! ACE_BIG_ENDIAN */
00207 
00208           /**
00209            * @name Overloaded Relation Operators.
00210            *
00211            * The canonical comparison operators.
00212            */
00213           //@{
00214           bool operator== (const LongLong &rhs) const;
00215           bool operator!= (const LongLong &rhs) const;
00216           //@}
00217         };
00218 #   endif /* no native 64 bit integer type */
00219 
00220 #   if defined (NONNATIVE_LONGLONG)
00221 #     define ACE_CDR_LONGLONG_INITIALIZER {0,0}
00222 #   else
00223 #     define ACE_CDR_LONGLONG_INITIALIZER 0
00224 #   endif /* NONNATIVE_LONGLONG */
00225 
00226 #   if ACE_SIZEOF_FLOAT == 4
00227       typedef float Float;
00228 #   else  /* ACE_SIZEOF_FLOAT != 4 */
00229       struct Float
00230       {
00231 #       if ACE_SIZEOF_INT == 4
00232           // Use unsigned int to get word alignment.
00233           unsigned int f;
00234 #       else  /* ACE_SIZEOF_INT != 4 */
00235           // Applications will probably have trouble with this.
00236           char f[4];
00237 #         if defined(_UNICOS) && !defined(_CRAYMPP)
00238             Float (void);
00239             Float (const float &init);
00240             Float & operator= (const float &rhs);
00241             bool operator!= (const Float &rhs) const;
00242 #         endif /* _UNICOS */
00243 #       endif /* ACE_SIZEOF_INT != 4 */
00244       };
00245 #   endif /* ACE_SIZEOF_FLOAT != 4 */
00246 
00247 #   if ACE_SIZEOF_DOUBLE == 8
00248       typedef double Double;
00249 #   else  /* ACE_SIZEOF_DOUBLE != 8 */
00250       struct Double
00251       {
00252 #       if ACE_SIZEOF_LONG == 8
00253           // Use u long to get word alignment.
00254           unsigned long f;
00255 #       else  /* ACE_SIZEOF_INT != 8 */
00256           // Applications will probably have trouble with this.
00257           char f[8];
00258 #       endif /* ACE_SIZEOF_INT != 8 */
00259       };
00260 #   endif /* ACE_SIZEOF_DOUBLE != 8 */
00261 
00262     // 94-9-32 Appendix A defines a 128 bit floating point "long
00263     // double" data type, with greatly extended precision and four
00264     // more bits of exponent (compared to "double").  This is an IDL
00265     // extension, not yet standard.
00266 
00267 #    if   ACE_SIZEOF_LONG_DOUBLE == 16
00268        typedef long double      LongDouble;
00269 #      define   ACE_CDR_LONG_DOUBLE_INITIALIZER 0
00270 #    else
00271 #      define NONNATIVE_LONGDOUBLE
00272 #      define   ACE_CDR_LONG_DOUBLE_INITIALIZER {{0}}
00273        struct ACE_Export LongDouble
00274        {
00275          char ld[16];
00276          bool operator== (const LongDouble &rhs) const;
00277          bool operator!= (const LongDouble &rhs) const;
00278          // @@ also need other comparison operators.
00279        };
00280 #    endif /* ACE_SIZEOF_LONG_DOUBLE != 16 */
00281 
00282   //@}
00283 
00284 #if !defined (ACE_CDR_GIOP_MAJOR_VERSION)
00285 #   define ACE_CDR_GIOP_MAJOR_VERSION 1
00286 #endif /*ACE_CDR_GIOP_MAJOR_VERSION */
00287 
00288 #if !defined (ACE_CDR_GIOP_MINOR_VERSION)
00289 #   define ACE_CDR_GIOP_MINOR_VERSION 2
00290 #endif /* ACE_CDR_GIOP_MINOR_VERSION */
00291 };
00292 
00293 ACE_END_VERSIONED_NAMESPACE_DECL
00294 
00295 #if defined (__ACE_INLINE__)
00296 # include "ace/CDR_Base.inl"
00297 #endif  /* __ACE_INLINE__ */
00298 
00299 
00300 #include /**/ "ace/post.h"
00301 
00302 #endif /* ACE_CDR_BASE_H */

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