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

CDR_Base.h

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

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