mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
376 lines
12 KiB
C++
376 lines
12 KiB
C++
// -*- C++ -*-
|
|
|
|
//=============================================================================
|
|
/**
|
|
* @file CDR_Base.h
|
|
*
|
|
* $Id: CDR_Base.h 95761 2012-05-15 18:23:04Z johnnyw $
|
|
*
|
|
* ACE Common Data Representation (CDR) basic types.
|
|
*
|
|
* The current implementation assumes that the host has 1-byte,
|
|
* 2-byte and 4-byte integral types, and that it has single
|
|
* precision and double precision IEEE floats.
|
|
* Those assumptions are pretty good these days, with Crays being
|
|
* the only known exception.
|
|
*
|
|
*
|
|
* @author TAO version by
|
|
* @author Aniruddha Gokhale <gokhale@cs.wustl.edu>
|
|
* @author Carlos O'Ryan<coryan@cs.wustl.edu>
|
|
* @author ACE version by
|
|
* @author Jeff Parsons <parsons@cs.wustl.edu>
|
|
* @author Istvan Buki <istvan.buki@euronet.be>
|
|
*/
|
|
//=============================================================================
|
|
|
|
|
|
#ifndef ACE_CDR_BASE_H
|
|
#define ACE_CDR_BASE_H
|
|
|
|
#include /**/ "ace/pre.h"
|
|
|
|
#include /**/ "ace/config-all.h"
|
|
|
|
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
|
|
|
#include "ace/Basic_Types.h"
|
|
#include "ace/Default_Constants.h"
|
|
|
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
|
|
|
// Stuff used by the ACE CDR classes. Watch these values... they're also used
|
|
// in the ACE_CDR Byte_Order enum below.
|
|
#if defined ACE_LITTLE_ENDIAN
|
|
# define ACE_CDR_BYTE_ORDER 1
|
|
// little endian encapsulation byte order has value = 1
|
|
#else /* ! ACE_LITTLE_ENDIAN */
|
|
# define ACE_CDR_BYTE_ORDER 0
|
|
// big endian encapsulation byte order has value = 0
|
|
#endif /* ! ACE_LITTLE_ENDIAN */
|
|
|
|
class ACE_Message_Block;
|
|
|
|
/**
|
|
* @class ACE_CDR
|
|
*
|
|
* @brief Keep constants and some routines common to both Output and
|
|
* Input CDR streams.
|
|
*/
|
|
class ACE_Export ACE_CDR
|
|
{
|
|
public:
|
|
// = Constants defined by the CDR protocol.
|
|
// By defining as many of these constants as possible as enums we
|
|
// ensure they get inlined and avoid pointless static memory
|
|
// allocations.
|
|
|
|
enum
|
|
{
|
|
// Note that some of these get reused as part of the standard
|
|
// binary format: unsigned is the same size as its signed cousin,
|
|
// float is LONG_SIZE, and double is LONGLONG_SIZE.
|
|
|
|
OCTET_SIZE = 1,
|
|
SHORT_SIZE = 2,
|
|
LONG_SIZE = 4,
|
|
LONGLONG_SIZE = 8,
|
|
LONGDOUBLE_SIZE = 16,
|
|
|
|
OCTET_ALIGN = 1,
|
|
SHORT_ALIGN = 2,
|
|
LONG_ALIGN = 4,
|
|
LONGLONG_ALIGN = 8,
|
|
/// @note the CORBA LongDouble alignment requirements do not
|
|
/// match its size...
|
|
LONGDOUBLE_ALIGN = 8,
|
|
|
|
/// Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long
|
|
/// double", size as above).
|
|
MAX_ALIGNMENT = 8,
|
|
|
|
/// The default buffer size.
|
|
/**
|
|
* @todo We want to add options to control this
|
|
* default value, so this constant should be read as the default
|
|
* default value ;-)
|
|
*/
|
|
DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE,
|
|
|
|
/// The buffer size grows exponentially until it reaches this size;
|
|
/// afterwards it grows linearly using the next constant
|
|
EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX,
|
|
|
|
/// Once exponential growth is ruled out the buffer size increases
|
|
/// in chunks of this size, note that this constants have the same
|
|
/// value right now, but it does not need to be so.
|
|
LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
|
|
};
|
|
|
|
/**
|
|
* @enum Byte_Order
|
|
*
|
|
* Defines values for the byte_order argument to ACE_OutputCDR and
|
|
* ACE_InputCDR.
|
|
*/
|
|
enum Byte_Order
|
|
{
|
|
/// Use big-endian order (also known as network byte order).
|
|
BYTE_ORDER_BIG_ENDIAN = 0,
|
|
/// Use little-endian order.
|
|
BYTE_ORDER_LITTLE_ENDIAN = 1,
|
|
/// Use whichever byte order is native to this machine.
|
|
BYTE_ORDER_NATIVE = ACE_CDR_BYTE_ORDER
|
|
};
|
|
|
|
/**
|
|
* Do byte swapping for each basic IDL type size. There exist only
|
|
* routines to put byte, halfword (2 bytes), word (4 bytes),
|
|
* doubleword (8 bytes) and quadword (16 byte); because those are
|
|
* the IDL basic type sizes.
|
|
*/
|
|
static void swap_2 (char const *orig, char *target);
|
|
static void swap_4 (char const *orig, char *target);
|
|
static void swap_8 (char const *orig, char *target);
|
|
static void swap_16 (char const *orig, char *target);
|
|
static void swap_2_array (char const *orig,
|
|
char *target,
|
|
size_t length);
|
|
static void swap_4_array (char const *orig,
|
|
char *target,
|
|
size_t length);
|
|
static void swap_8_array (char const *orig,
|
|
char *target,
|
|
size_t length);
|
|
static void swap_16_array (char const *orig,
|
|
char *target,
|
|
size_t length);
|
|
|
|
/// Align the message block to ACE_CDR::MAX_ALIGNMENT,
|
|
/// set by the CORBA spec at 8 bytes.
|
|
static void mb_align (ACE_Message_Block *mb);
|
|
|
|
/**
|
|
* Compute the size of the smallest buffer that can contain at least
|
|
* @a minsize bytes.
|
|
* To understand how a "best fit" is computed look at the
|
|
* algorithm in the code.
|
|
* Basically the buffers grow exponentially, up to a certain point,
|
|
* then the buffer size grows linearly.
|
|
* The advantage of this algorithm is that is rapidly grows to a
|
|
* large value, but does not explode at the end.
|
|
*/
|
|
static size_t first_size (size_t minsize);
|
|
|
|
/// Compute not the smallest, but the second smallest buffer that
|
|
/// will fir @a minsize bytes.
|
|
static size_t next_size (size_t minsize);
|
|
|
|
/**
|
|
* Increase the capacity of mb to contain at least @a minsize bytes.
|
|
* If @a minsize is zero the size is increased by an amount at least
|
|
* large enough to contain any of the basic IDL types.
|
|
* @retval -1 Failure
|
|
* @retval 0 Success.
|
|
*/
|
|
static int grow (ACE_Message_Block *mb, size_t minsize);
|
|
|
|
/**
|
|
* Copy a message block chain into a single message block,
|
|
* preserving the alignment of the first message block of the
|
|
* original stream, not the following message blocks.
|
|
* @retval -1 Failure
|
|
* @retval 0 Success.
|
|
*/
|
|
static int consolidate (ACE_Message_Block *dst,
|
|
const ACE_Message_Block *src);
|
|
|
|
static size_t total_length (const ACE_Message_Block *begin,
|
|
const ACE_Message_Block *end);
|
|
|
|
/**
|
|
* @name Basic OMG IDL Types
|
|
*
|
|
* These types are for use in the CDR classes. The cleanest way to
|
|
* avoid complaints from all compilers is to define them all.
|
|
*/
|
|
//@{
|
|
typedef bool Boolean;
|
|
typedef unsigned char Octet;
|
|
typedef char Char;
|
|
typedef ACE_WCHAR_T WChar;
|
|
typedef ACE_INT16 Short;
|
|
typedef ACE_UINT16 UShort;
|
|
typedef ACE_INT32 Long;
|
|
typedef ACE_UINT32 ULong;
|
|
typedef ACE_UINT64 ULongLong;
|
|
|
|
# if (defined (_MSC_VER)) || (defined (__BORLANDC__))
|
|
typedef __int64 LongLong;
|
|
# elif ACE_SIZEOF_LONG == 8
|
|
typedef long LongLong;
|
|
# elif defined(__TANDEM)
|
|
typedef long long LongLong;
|
|
# elif ACE_SIZEOF_LONG_LONG == 8
|
|
# if defined (sun) && !defined (ACE_LACKS_U_LONGLONG_T)
|
|
// sun #defines u_longlong_t, maybe other platforms do also.
|
|
// Use it, at least with g++, so that its -pedantic doesn't
|
|
// complain about no ANSI C++ long long.
|
|
typedef longlong_t LongLong;
|
|
# else
|
|
typedef long long LongLong;
|
|
# endif /* sun */
|
|
# else /* no native 64 bit integer type */
|
|
# define NONNATIVE_LONGLONG
|
|
struct ACE_Export LongLong
|
|
{
|
|
# if defined (ACE_BIG_ENDIAN)
|
|
ACE_CDR::Long h;
|
|
ACE_CDR::Long l;
|
|
# else
|
|
ACE_CDR::Long l;
|
|
ACE_CDR::Long h;
|
|
# endif /* ! ACE_BIG_ENDIAN */
|
|
|
|
/**
|
|
* @name Overloaded Relation Operators.
|
|
*
|
|
* The canonical comparison operators.
|
|
*/
|
|
//@{
|
|
bool operator== (const LongLong &rhs) const;
|
|
bool operator!= (const LongLong &rhs) const;
|
|
//@}
|
|
};
|
|
# endif /* no native 64 bit integer type */
|
|
|
|
# if defined (NONNATIVE_LONGLONG)
|
|
# define ACE_CDR_LONGLONG_INITIALIZER {0,0}
|
|
# else
|
|
# define ACE_CDR_LONGLONG_INITIALIZER 0
|
|
# endif /* NONNATIVE_LONGLONG */
|
|
|
|
# if ACE_SIZEOF_FLOAT == 4
|
|
typedef float Float;
|
|
# else /* ACE_SIZEOF_FLOAT != 4 */
|
|
struct Float
|
|
{
|
|
# if ACE_SIZEOF_INT == 4
|
|
// Use unsigned int to get word alignment.
|
|
unsigned int f;
|
|
# else /* ACE_SIZEOF_INT != 4 */
|
|
// Applications will probably have trouble with this.
|
|
char f[4];
|
|
# endif /* ACE_SIZEOF_INT != 4 */
|
|
};
|
|
# endif /* ACE_SIZEOF_FLOAT != 4 */
|
|
|
|
# if ACE_SIZEOF_DOUBLE == 8
|
|
typedef double Double;
|
|
# else /* ACE_SIZEOF_DOUBLE != 8 */
|
|
struct Double
|
|
{
|
|
# if ACE_SIZEOF_LONG == 8
|
|
// Use u long to get word alignment.
|
|
unsigned long f;
|
|
# else /* ACE_SIZEOF_INT != 8 */
|
|
// Applications will probably have trouble with this.
|
|
char f[8];
|
|
# endif /* ACE_SIZEOF_INT != 8 */
|
|
};
|
|
# endif /* ACE_SIZEOF_DOUBLE != 8 */
|
|
|
|
// 94-9-32 Appendix A defines a 128 bit floating point "long
|
|
// double" data type, with greatly extended precision and four
|
|
// more bits of exponent (compared to "double"). This is an IDL
|
|
// extension, not yet standard.
|
|
|
|
# if ACE_SIZEOF_LONG_DOUBLE == 16
|
|
typedef long double LongDouble;
|
|
# define ACE_CDR_LONG_DOUBLE_INITIALIZER 0
|
|
# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS = RHS
|
|
# else
|
|
# define NONNATIVE_LONGDOUBLE
|
|
# define ACE_CDR_LONG_DOUBLE_INITIALIZER {{0}}
|
|
# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS.assign (RHS)
|
|
struct ACE_Export LongDouble
|
|
{
|
|
// VxWorks' compiler (gcc 2.96) gets confused by the operator long
|
|
// double, so we avoid using long double as the NativeImpl.
|
|
// Linux's x86 long double format (12 or 16 bytes) is incompatible
|
|
// with Windows, Solaris, AIX, MacOS X and HP-UX (and probably others)
|
|
// long double format (8 or 16 bytes). If you need 32-bit Linux to
|
|
// inter-operate with 64-bit Linux you will want to define this
|
|
// macro to 0 so that "long double" is used. Otherwise, do not define
|
|
// this macro.
|
|
# if defined (ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE) && \
|
|
(ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE == 1)
|
|
typedef double NativeImpl;
|
|
# else
|
|
typedef long double NativeImpl;
|
|
# endif /* ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE==1 */
|
|
|
|
char ld[16];
|
|
|
|
LongDouble& assign (const NativeImpl& rhs);
|
|
LongDouble& assign (const LongDouble& rhs);
|
|
|
|
bool operator== (const LongDouble &rhs) const;
|
|
bool operator!= (const LongDouble &rhs) const;
|
|
|
|
LongDouble& operator*= (const NativeImpl rhs) {
|
|
return this->assign (static_cast<NativeImpl> (*this) * rhs);
|
|
}
|
|
LongDouble& operator/= (const NativeImpl rhs) {
|
|
return this->assign (static_cast<NativeImpl> (*this) / rhs);
|
|
}
|
|
LongDouble& operator+= (const NativeImpl rhs) {
|
|
return this->assign (static_cast<NativeImpl> (*this) + rhs);
|
|
}
|
|
LongDouble& operator-= (const NativeImpl rhs) {
|
|
return this->assign (static_cast<NativeImpl> (*this) - rhs);
|
|
}
|
|
LongDouble& operator++ () {
|
|
return this->assign (static_cast<NativeImpl> (*this) + 1);
|
|
}
|
|
LongDouble& operator-- () {
|
|
return this->assign (static_cast<NativeImpl> (*this) - 1);
|
|
}
|
|
LongDouble operator++ (int) {
|
|
LongDouble ldv = *this;
|
|
this->assign (static_cast<NativeImpl> (*this) + 1);
|
|
return ldv;
|
|
}
|
|
LongDouble operator-- (int) {
|
|
LongDouble ldv = *this;
|
|
this->assign (static_cast<NativeImpl> (*this) - 1);
|
|
return ldv;
|
|
}
|
|
|
|
operator NativeImpl () const;
|
|
};
|
|
# endif /* ACE_SIZEOF_LONG_DOUBLE != 16 */
|
|
|
|
//@}
|
|
|
|
#if !defined (ACE_CDR_GIOP_MAJOR_VERSION)
|
|
# define ACE_CDR_GIOP_MAJOR_VERSION 1
|
|
#endif /*ACE_CDR_GIOP_MAJOR_VERSION */
|
|
|
|
#if !defined (ACE_CDR_GIOP_MINOR_VERSION)
|
|
# define ACE_CDR_GIOP_MINOR_VERSION 2
|
|
#endif /* ACE_CDR_GIOP_MINOR_VERSION */
|
|
};
|
|
|
|
ACE_END_VERSIONED_NAMESPACE_DECL
|
|
|
|
#if defined (__ACE_INLINE__)
|
|
# include "ace/CDR_Base.inl"
|
|
#endif /* __ACE_INLINE__ */
|
|
|
|
|
|
#include /**/ "ace/post.h"
|
|
|
|
#endif /* ACE_CDR_BASE_H */
|