Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / CDR_Base.h
bloba8b49e5a0a1636e5e905bd4257050683a3664b50
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file CDR_Base.h
7 * ACE Common Data Representation (CDR) basic types.
9 * The current implementation assumes that the host has 1-byte,
10 * 2-byte and 4-byte integral types, and that it has single
11 * precision and double precision IEEE floats.
12 * Those assumptions are pretty good these days, with Crays being
13 * the only known exception.
15 * @author TAO version by
16 * @author Aniruddha Gokhale <gokhale@cs.wustl.edu>
17 * @author Carlos O'Ryan<coryan@cs.wustl.edu>
18 * @author ACE version by
19 * @author Jeff Parsons <parsons@cs.wustl.edu>
20 * @author Istvan Buki <istvan.buki@euronet.be>
22 //=============================================================================
24 #ifndef ACE_CDR_BASE_H
25 #define ACE_CDR_BASE_H
27 #include /**/ "ace/pre.h"
29 #include /**/ "ace/config-all.h"
31 #if !defined (ACE_LACKS_PRAGMA_ONCE)
32 # pragma once
33 #endif /* ACE_LACKS_PRAGMA_ONCE */
35 #include "ace/Basic_Types.h"
36 #include "ace/Default_Constants.h"
37 #include "ace/Global_Macros.h"
38 #include "ace/iosfwd.h"
40 #include <iterator>
42 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
44 // Stuff used by the ACE CDR classes. Watch these values... they're also used
45 // in the ACE_CDR Byte_Order enum below.
46 #if defined ACE_LITTLE_ENDIAN
47 # define ACE_CDR_BYTE_ORDER 1
48 // little endian encapsulation byte order has value = 1
49 #else /* ! ACE_LITTLE_ENDIAN */
50 # define ACE_CDR_BYTE_ORDER 0
51 // big endian encapsulation byte order has value = 0
52 #endif /* ! ACE_LITTLE_ENDIAN */
54 class ACE_Message_Block;
56 /**
57 * @class ACE_CDR
59 * @brief Keep constants and some routines common to both Output and
60 * Input CDR streams.
62 class ACE_Export ACE_CDR
64 public:
65 // = Constants defined by the CDR protocol.
66 // By defining as many of these constants as possible as enums we
67 // ensure they get inlined and avoid pointless static memory
68 // allocations.
70 enum
72 // Note that some of these get reused as part of the standard
73 // binary format: unsigned is the same size as its signed cousin,
74 // float is LONG_SIZE, and double is LONGLONG_SIZE.
76 OCTET_SIZE = 1,
77 SHORT_SIZE = 2,
78 LONG_SIZE = 4,
79 LONGLONG_SIZE = 8,
80 LONGDOUBLE_SIZE = 16,
82 OCTET_ALIGN = 1,
83 SHORT_ALIGN = 2,
84 LONG_ALIGN = 4,
85 LONGLONG_ALIGN = 8,
86 /// @note the CORBA LongDouble alignment requirements do not
87 /// match its size...
88 LONGDOUBLE_ALIGN = 8,
90 /// Maximal CDR 1.1 alignment: "quad precision" FP (i.e. "CDR::Long
91 /// double", size as above).
92 MAX_ALIGNMENT = 8,
94 /// The default buffer size.
95 /**
96 * @todo We want to add options to control this
97 * default value, so this constant should be read as the default
98 * default value ;-)
100 DEFAULT_BUFSIZE = ACE_DEFAULT_CDR_BUFSIZE,
102 /// The buffer size grows exponentially until it reaches this size;
103 /// afterwards it grows linearly using the next constant
104 EXP_GROWTH_MAX = ACE_DEFAULT_CDR_EXP_GROWTH_MAX,
106 /// Once exponential growth is ruled out the buffer size increases
107 /// in chunks of this size, note that this constants have the same
108 /// value right now, but it does not need to be so.
109 LINEAR_GROWTH_CHUNK = ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK
113 * @enum Byte_Order
115 * Defines values for the byte_order argument to ACE_OutputCDR and
116 * ACE_InputCDR.
118 enum Byte_Order
120 /// Use big-endian order (also known as network byte order).
121 BYTE_ORDER_BIG_ENDIAN = 0,
122 /// Use little-endian order.
123 BYTE_ORDER_LITTLE_ENDIAN = 1,
124 /// Use whichever byte order is native to this machine.
125 BYTE_ORDER_NATIVE = ACE_CDR_BYTE_ORDER
129 * Do byte swapping for each basic IDL type size. There exist only
130 * routines to put byte, halfword (2 bytes), word (4 bytes),
131 * doubleword (8 bytes) and quadword (16 byte); because those are
132 * the IDL basic type sizes.
134 static void swap_2 (char const *orig, char *target);
135 static void swap_4 (char const *orig, char *target);
136 static void swap_8 (char const *orig, char *target);
137 static void swap_16 (char const *orig, char *target);
138 static void swap_2_array (char const *orig,
139 char *target,
140 size_t length);
141 static void swap_4_array (char const *orig,
142 char *target,
143 size_t length);
144 static void swap_8_array (char const *orig,
145 char *target,
146 size_t length);
147 static void swap_16_array (char const *orig,
148 char *target,
149 size_t length);
151 /// Align the message block to ACE_CDR::MAX_ALIGNMENT,
152 /// set by the CORBA spec at 8 bytes.
153 static void mb_align (ACE_Message_Block *mb);
156 * Compute the size of the smallest buffer that can contain at least
157 * @a minsize bytes.
158 * To understand how a "best fit" is computed look at the
159 * algorithm in the code.
160 * Basically the buffers grow exponentially, up to a certain point,
161 * then the buffer size grows linearly.
162 * The advantage of this algorithm is that is rapidly grows to a
163 * large value, but does not explode at the end.
165 static size_t first_size (size_t minsize);
167 /// Compute not the smallest, but the second smallest buffer that
168 /// will fir @a minsize bytes.
169 static size_t next_size (size_t minsize);
172 * Increase the capacity of mb to contain at least @a minsize bytes.
173 * If @a minsize is zero the size is increased by an amount at least
174 * large enough to contain any of the basic IDL types.
175 * @retval -1 Failure
176 * @retval 0 Success.
178 static int grow (ACE_Message_Block *mb, size_t minsize);
181 * Copy a message block chain into a single message block,
182 * preserving the alignment of the first message block of the
183 * original stream, not the following message blocks.
184 * @retval -1 Failure
185 * @retval 0 Success.
187 static int consolidate (ACE_Message_Block *dst,
188 const ACE_Message_Block *src);
190 static size_t total_length (const ACE_Message_Block *begin,
191 const ACE_Message_Block *end);
194 * @name Basic OMG IDL Types
196 * These types are for use in the CDR classes. The cleanest way to
197 * avoid complaints from all compilers is to define them all.
199 //@{
200 typedef bool Boolean;
201 typedef unsigned char Octet;
202 typedef char Char;
203 typedef ACE_WCHAR_T WChar;
204 typedef ACE_INT16 Short;
205 typedef ACE_UINT16 UShort;
206 typedef ACE_INT32 Long;
207 typedef ACE_UINT32 ULong;
208 typedef ACE_INT64 LongLong;
209 typedef ACE_UINT64 ULongLong;
211 # if ACE_SIZEOF_FLOAT == 4
212 typedef float Float;
213 # else /* ACE_SIZEOF_FLOAT != 4 */
214 struct Float
216 # if ACE_SIZEOF_INT == 4
217 // Use unsigned int to get word alignment.
218 unsigned int f;
219 # else /* ACE_SIZEOF_INT != 4 */
220 // Applications will probably have trouble with this.
221 char f[4];
222 # endif /* ACE_SIZEOF_INT != 4 */
224 # endif /* ACE_SIZEOF_FLOAT != 4 */
226 # if ACE_SIZEOF_DOUBLE == 8
227 typedef double Double;
228 # else /* ACE_SIZEOF_DOUBLE != 8 */
229 struct Double
231 # if ACE_SIZEOF_LONG == 8
232 // Use u long to get word alignment.
233 unsigned long f;
234 # else /* ACE_SIZEOF_INT != 8 */
235 // Applications will probably have trouble with this.
236 char f[8];
237 # endif /* ACE_SIZEOF_INT != 8 */
239 # endif /* ACE_SIZEOF_DOUBLE != 8 */
241 // 94-9-32 Appendix A defines a 128 bit floating point "long
242 // double" data type, with greatly extended precision and four
243 // more bits of exponent (compared to "double"). This is an IDL
244 // extension, not yet standard.
246 # if ACE_SIZEOF_LONG_DOUBLE == 16
247 typedef long double LongDouble;
248 # define ACE_CDR_LONG_DOUBLE_INITIALIZER 0
249 # define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS = RHS
250 # else
251 # define NONNATIVE_LONGDOUBLE
252 # define ACE_CDR_LONG_DOUBLE_INITIALIZER {{0}}
253 # define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS.assign (RHS)
254 struct ACE_Export LongDouble
256 // VxWorks' compiler (gcc 2.96) gets confused by the operator long
257 // double, so we avoid using long double as the NativeImpl.
258 // Linux's x86 long double format (12 or 16 bytes) is incompatible
259 // with Windows, Solaris, AIX, MacOS X and HP-UX (and probably others)
260 // long double format (8 or 16 bytes). If you need 32-bit Linux to
261 // inter-operate with 64-bit Linux you will want to define this
262 // macro to 0 so that "long double" is used. Otherwise, do not define
263 // this macro.
264 # if defined (ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE) && \
265 (ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE == 1)
266 typedef double NativeImpl;
267 # else
268 typedef long double NativeImpl;
269 # endif /* ACE_CDR_IMPLEMENT_WITH_NATIVE_DOUBLE==1 */
271 char ld[16];
273 LongDouble& assign (const NativeImpl& rhs);
274 LongDouble& assign (const LongDouble& rhs);
276 bool operator== (const LongDouble &rhs) const;
277 bool operator!= (const LongDouble &rhs) const;
279 LongDouble& operator*= (const NativeImpl rhs) {
280 return this->assign (static_cast<NativeImpl> (*this) * rhs);
282 LongDouble& operator/= (const NativeImpl rhs) {
283 return this->assign (static_cast<NativeImpl> (*this) / rhs);
285 LongDouble& operator+= (const NativeImpl rhs) {
286 return this->assign (static_cast<NativeImpl> (*this) + rhs);
288 LongDouble& operator-= (const NativeImpl rhs) {
289 return this->assign (static_cast<NativeImpl> (*this) - rhs);
291 LongDouble& operator++ () {
292 return this->assign (static_cast<NativeImpl> (*this) + 1);
294 LongDouble& operator-- () {
295 return this->assign (static_cast<NativeImpl> (*this) - 1);
297 LongDouble operator++ (int) {
298 LongDouble ldv = *this;
299 this->assign (static_cast<NativeImpl> (*this) + 1);
300 return ldv;
302 LongDouble operator-- (int) {
303 LongDouble ldv = *this;
304 this->assign (static_cast<NativeImpl> (*this) - 1);
305 return ldv;
308 operator NativeImpl () const;
310 # endif /* ACE_SIZEOF_LONG_DOUBLE != 16 */
312 #define ACE_HAS_CDR_FIXED
313 /// Fixed-point data type: up to 31 decimal digits and a sign bit
315 /// See OMG 2011-11-01 CORBA Interfaces v3.2 sections 7.10, 7.11.3.4
316 /// See OMG 2011-11-02 CORBA Interoperability v3.2 section 9.3.2.8
317 /// See OMG 2012-07-02 IDL-to-C++ Mapping v1.3 section 5.13
318 /// This class doesn't exactly match the IDL-to-C++ mapping because
319 /// it is meant for use inside a union in the IDL compiler and therefore
320 /// has no constructors. Standards-based middleware libraries such as
321 /// ORBs and DDSs can wrap this class in a class of their own to provide
322 /// the exact interface described by the mapping specification.
323 class ACE_Export Fixed
325 public:
326 enum
328 MAX_DIGITS = 31,
329 MAX_STRING_SIZE = 4 + MAX_DIGITS, // includes -, 0, ., terminator
330 POSITIVE = 0xc,
331 NEGATIVE = 0xd
334 static Fixed from_integer (LongLong val = 0);
335 static Fixed from_integer (ULongLong val);
336 static Fixed from_floating (LongDouble val);
337 static Fixed from_string (const char *str);
338 static Fixed from_octets (const Octet *array, int len,
339 unsigned int scale = 0);
341 operator LongLong () const;
342 operator LongDouble () const;
344 Fixed round (UShort scale) const;
345 Fixed truncate (UShort scale) const;
347 bool to_string (char *buffer, size_t buffer_size) const;
348 const Octet *to_octets (int &n) const;
350 Fixed &operator+= (const Fixed &rhs);
351 Fixed &operator-= (const Fixed &rhs);
352 Fixed &operator*= (const Fixed &rhs);
353 Fixed &operator/= (const Fixed &rhs);
355 Fixed &operator++ ();
356 Fixed operator++ (int);
357 Fixed &operator-- ();
358 Fixed operator-- (int);
360 Fixed operator+ () const;
361 Fixed operator- () const;
362 bool operator! () const;
364 UShort fixed_digits () const;
365 UShort fixed_scale () const;
367 bool sign () const;
368 Octet digit (int n) const;
369 void digit (int n, int value);
371 bool less (const Fixed &rhs) const;
372 bool equal (const Fixed &rhs) const;
374 class Proxy
376 bool high_nibble_;
377 Octet &element_;
378 public:
379 Proxy (bool high_nibble, Octet &element);
380 Proxy &operator= (Octet val);
381 Proxy &operator+= (int rhs);
382 Proxy &operator-= (int rhs);
383 Proxy &operator++ ();
384 Proxy &operator-- ();
385 operator Octet () const;
388 class IteratorBase
390 protected:
391 explicit IteratorBase (int digit);
392 bool high_nibble () const;
393 Octet &storage (Fixed *outer) const;
394 Octet storage (const Fixed *outer) const;
395 bool compare (const IteratorBase &rhs) const;
396 int digit_;
399 class Iterator
400 : public std::iterator<std::bidirectional_iterator_tag, Proxy>
401 , private IteratorBase
403 public:
404 explicit Iterator (Fixed *outer, int digit = 0);
405 Proxy operator* ();
406 Iterator &operator+= (std::ptrdiff_t n);
407 Iterator &operator++ ();
408 Iterator operator++ (int);
409 Iterator &operator-- ();
410 Iterator operator-- (int);
411 bool operator== (const Iterator &rhs) const;
412 bool operator!= (const Iterator &rhs) const;
413 private:
414 Fixed *outer_;
417 class ConstIterator
418 : public std::iterator<std::bidirectional_iterator_tag, Octet>
419 , private IteratorBase
421 public:
422 explicit ConstIterator (const Fixed *outer, int digit = 0);
423 Octet operator* ();
424 ConstIterator &operator+= (std::ptrdiff_t n);
425 ConstIterator &operator++ ();
426 ConstIterator operator++ (int);
427 ConstIterator &operator-- ();
428 ConstIterator operator-- (int);
429 bool operator== (const ConstIterator &rhs) const;
430 bool operator!= (const ConstIterator &rhs) const;
431 private:
432 const Fixed *outer_;
435 Iterator begin ();
436 ConstIterator begin () const;
437 ConstIterator cbegin () const;
438 Iterator end ();
439 ConstIterator end () const;
440 ConstIterator cend () const;
442 private:
443 /// CDR wire format for Fixed: marshaled as an octet array with
444 /// index 0 as the most significant octet and index n the least
445 /// significant. Each octet contains two decimal digits except for
446 /// the last octet (least sig) which has one decimal digit in
447 /// the high nibble and the sign indicator in the low nibble.
448 Octet value_[16];
450 /// digits_ is not marshaled, the receiver needs to know it
451 /// from the type information (for example, IDL). The value of
452 /// digits_ determines how many octets of value_ are masharled.
453 Octet digits_;
455 /// scale_ is not marshaled, the receiver needs to know it
456 /// from the type information (for example, IDL).
457 Octet scale_;
459 /// remove trailing zeros, shift down and reduce digits and scale
460 void normalize (UShort min_scale = 0);
462 /// Add up to 'digits' of additional scale by shifting left without
463 /// removing significant digits. Returns number of digits shifted.
464 int lshift (int digits);
466 /// Prepare to add (or subtract) f by changing the digits and scale
467 /// of *this, returnins an iterator to the least significant
468 /// digit of f that will influence the sum (or difference).
469 ConstIterator pre_add (const Fixed &f);
471 Fixed div_helper2 (const Fixed &rhs, Fixed &r) const;
472 Fixed div_helper1 (const Fixed &rhs, Fixed &r) const;
473 Fixed join (int digits, const Fixed &bottom) const;
474 void ltrim ();
477 //@}
479 #if !defined (ACE_CDR_GIOP_MAJOR_VERSION)
480 # define ACE_CDR_GIOP_MAJOR_VERSION 1
481 #endif /*ACE_CDR_GIOP_MAJOR_VERSION */
483 #if !defined (ACE_CDR_GIOP_MINOR_VERSION)
484 # define ACE_CDR_GIOP_MINOR_VERSION 2
485 #endif /* ACE_CDR_GIOP_MINOR_VERSION */
488 ACE_Export
489 ACE_OSTREAM_TYPE &operator<< (ACE_OSTREAM_TYPE &lhs, const ACE_CDR::Fixed &rhs);
491 #ifndef ACE_LACKS_IOSTREAM_TOTALLY
492 ACE_Export
493 std::istream &operator>> (std::istream &lhs, ACE_CDR::Fixed &rhs);
494 #endif
496 ACE_Export
497 bool operator< (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
499 ACE_Export
500 bool operator> (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
502 ACE_Export
503 bool operator>= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
505 ACE_Export
506 bool operator<= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
508 ACE_Export
509 bool operator== (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
511 ACE_Export
512 bool operator!= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
514 ACE_Export
515 ACE_CDR::Fixed operator+ (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
517 ACE_Export
518 ACE_CDR::Fixed operator- (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
520 ACE_Export
521 ACE_CDR::Fixed operator* (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
523 ACE_Export
524 ACE_CDR::Fixed operator/ (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs);
526 ACE_END_VERSIONED_NAMESPACE_DECL
528 #if defined (__ACE_INLINE__)
529 # include "ace/CDR_Base.inl"
530 #endif /* __ACE_INLINE__ */
533 #include /**/ "ace/post.h"
535 #endif /* ACE_CDR_BASE_H */