Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / tao / CDR.h
blobf7406c6000d49ca45c6e85eedfec1a7ee5c54b72
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file CDR.h
7 * Common Data Representation (CDR) marshaling streams.
9 * This implementation assumes that the native numeric
10 * representation is two's complement for integers, IEEE
11 * single/double for floats. Also that characters are in ISO
12 * Latin/1.
14 * Note that CDR itself makes no such assumptions, but this
15 * implementation makes such assumptions for reasons of
16 * efficiency. Careful enhancements could preserve that
17 * efficiency where the assumptions are true, yet still allow the
18 * code to work when they aren't true.
20 * The implementation expects that buffers are aligned according
21 * to the strongest CDR alignment restriction.
23 * @note This does everything "CDR 1.1" does ... that is, it
24 * supports the five extended OMG-IDL data types in UNO Appendix
25 * A, which provide richer arithmetic types (64 bit integers,
26 * "quad precision" FP) and UNICODE-based characters and strings.
27 * Those types are not standard parts of OMG-IDL at this time.
29 * THREADING NOTE: CDR data structures must be protected against
30 * concurrent access by their owning thread.
32 * @author Copyright 1994-1995 by Sun Microsystems Inc.
33 * @author Aniruddha Gokhale
34 * @author Carlos O'Ryan
36 //=============================================================================
39 #ifndef TAO_CDR_H
40 #define TAO_CDR_H
42 #include /**/ "ace/pre.h"
44 #include "tao/orbconf.h"
46 #if !defined (ACE_LACKS_PRAGMA_ONCE)
47 # pragma once
48 #endif /* ACE_LACKS_PRAGMA_ONCE */
50 #include /**/ "tao/TAO_Export.h"
51 #include "tao/Basic_Types.h"
52 #include "tao/GIOP_Message_Version.h"
53 #include "tao/Message_Semantics.h"
54 #include "tao/Intrusive_Ref_Count_Handle_T.h"
55 #include "tao/Intrusive_Ref_Count_Object_T.h"
57 #include "ace/CDR_Stream.h"
58 #include "ace/SString.h"
59 #include "ace/Hash_Map_Manager_T.h"
60 #include "ace/Null_Mutex.h"
62 #include <string>
64 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
66 class TAO_ORB_Core;
67 class TAO_GIOP_Fragmentation_Strategy;
68 class TAO_Stub;
70 /**
71 * @class TAO_OutputCDR
73 * @brief A CDR stream for writing, i.e. for marshalling.
75 * This class is based on the the CORBA spec for Java (98-02-29),
76 * java class omg.org.CORBA.portable.OutputStream.
77 * It diverts in a few ways:
78 * + Operations taking arrays don't have offsets, because in C++
79 * it is easier to describe an array starting from x+offset.
80 * + Operations return an error status, because exceptions are
81 * not widely available in C++ (yet).
82 * A particularly useful static member function for this buffer is
83 * an interpretive encoding routine, usable as a typecode
84 * interpreter callback. Ditto for decoding. These are used to
85 * support all OMG-IDL datatypes, even those not supported
86 * directly by put/get primitives.
88 class TAO_Export TAO_OutputCDR : public ACE_OutputCDR
90 public:
91 /// For reading from a output CDR stream.
92 friend class TAO_InputCDR;
93 typedef ACE_Hash_Map_Manager<ACE_CString, char*, ACE_Null_Mutex> Repo_Id_Map;
94 typedef Repo_Id_Map Codebase_URL_Map;
95 typedef ACE_Hash_Map_Manager<void*, char*, ACE_Null_Mutex> Value_Map;
97 typedef TAO_Intrusive_Ref_Count_Object<Repo_Id_Map, ACE_Null_Mutex> RC_Repo_Id_Map;
98 typedef TAO_Intrusive_Ref_Count_Object<Codebase_URL_Map, ACE_Null_Mutex> RC_Codebase_URL_Map;
99 typedef TAO_Intrusive_Ref_Count_Object<Value_Map, ACE_Null_Mutex> RC_Value_Map;
101 typedef TAO_Intrusive_Ref_Count_Handle<RC_Repo_Id_Map> Repo_Id_Map_Handle;
102 typedef TAO_Intrusive_Ref_Count_Handle<RC_Codebase_URL_Map> Codebase_URL_Map_Handle;
103 typedef TAO_Intrusive_Ref_Count_Handle<RC_Value_Map> Value_Map_Handle;
105 // The default values for the allocators and memcpy_tradeoff
106 // in these constructors are not 0, but are generated by the
107 // ORB. Refer to the constructor bodies in CDR.cpp for the
108 // code that supplies these values to the base class constructor.
110 /// Default constructor, allocates @a size bytes in the internal
111 /// buffer, if @a size == 0 it allocates the default size.
112 TAO_OutputCDR (size_t size = 0,
113 int byte_order = ACE_CDR_BYTE_ORDER,
114 ACE_Allocator* buffer_allocator = 0,
115 ACE_Allocator* data_block_allocator = 0,
116 ACE_Allocator* message_block_allocator = 0,
117 size_t memcpy_tradeoff = 0,
118 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
119 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR);
121 /// Build a CDR stream with an initial buffer, it will *not* remove
122 /// @a data, since it did not allocated it.
123 TAO_OutputCDR (char *data,
124 size_t size,
125 int byte_order = ACE_CDR_BYTE_ORDER,
126 ACE_Allocator* buffer_allocator = 0,
127 ACE_Allocator* data_block_allocator = 0,
128 ACE_Allocator* message_block_allocator = 0,
129 size_t memcpy_tradeoff = 0,
130 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
131 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR);
133 /// Build a CDR stream with an initial buffer, it will *not* remove
134 /// @a data since it did not allocated it, and enable fragmentation
135 /// support.
136 TAO_OutputCDR (char *data,
137 size_t size,
138 int byte_order,
139 ACE_Allocator* buffer_allocator,
140 ACE_Allocator* data_block_allocator,
141 ACE_Allocator* message_block_allocator,
142 size_t memcpy_tradeoff,
143 TAO_GIOP_Fragmentation_Strategy * fs,
144 ACE_CDR::Octet major_version,
145 ACE_CDR::Octet minor_version);
147 /// Build a CDR stream with an initial Message_Block chain, it will *not*
148 /// remove @a data, since it did not allocate it.
149 TAO_OutputCDR (ACE_Message_Block *data,
150 int byte_order = ACE_CDR_BYTE_ORDER,
151 size_t memcpy_tradeoff = 0,
152 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
153 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR);
155 /// Build a CDR stream with an initial data block, it will *not* remove
156 /// @a data, since it did not allocated it.
157 TAO_OutputCDR (ACE_Data_Block *data,
158 int byte_order = ACE_CDR_BYTE_ORDER,
159 ACE_Allocator* message_block_allocator = 0,
160 size_t memcpy_tradeoff = 0,
161 TAO_GIOP_Fragmentation_Strategy * fs = 0,
162 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
163 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR);
165 /// Destructor.
166 ~TAO_OutputCDR (void);
168 // @todo do we want a special method to write an array of
169 // strings and wstrings?
171 // = TAO specific methods.
172 static void throw_stub_exception (int error_num);
173 static void throw_skel_exception (int error_num);
175 void get_version (TAO_GIOP_Message_Version& giop_version);
178 * @name Outgoing GIOP Fragment Related Methods
180 * These methods are only used when fragmenting outgoing GIOP
181 * requests and replies.
183 //@{
184 /// Fragment this output CDR stream if necessary.
186 * Fragmentation will done through GIOP fragments when the length of
187 * the CDR stream length will exceed the configured threshold.
189 bool fragment_stream (ACE_CDR::ULong pending_alignment,
190 ACE_CDR::ULong pending_length);
192 /// Are there more data fragments to come?
193 bool more_fragments (void) const;
195 /// Specify whether there are more data fragments to come.
196 void more_fragments (bool more);
198 /// Set fragmented message attributes.
199 void message_attributes (CORBA::ULong request_id,
200 TAO_Stub * stub,
201 TAO_Message_Semantics message_semantics,
202 ACE_Time_Value * timeout);
204 /// Fragmented message request ID.
205 CORBA::ULong request_id (void) const;
207 /// Stub object associated with the request.
208 TAO_Stub * stub (void) const;
210 /// Message semantics (twoway, oneway, reply)
211 TAO_Message_Semantics message_semantics (void) const;
213 /// Maximum time to wait for outgoing message to be sent.
214 ACE_Time_Value * timeout (void) const;
215 //@}
217 /// These methods are used by valuetype indirection support.
218 /// Accessor to the indirect maps.
219 Repo_Id_Map_Handle& get_repo_id_map ();
220 #ifdef TAO_HAS_VALUETYPE_CODEBASE
221 Codebase_URL_Map_Handle& get_codebase_url_map ();
222 #endif
223 Value_Map_Handle& get_value_map ();
225 /// Updater of the maps.
226 /// These updaters are used to make indirect maps in original stream
227 /// take effect even during marshalling/demarshalling a redirected stream.
228 void set_repo_id_map (Repo_Id_Map_Handle& map);
229 #ifdef TAO_HAS_VALUETYPE_CODEBASE
230 Codebase_URL_Map_Handle& get_codebase_url_map ();
231 void set_codebase_url_map (Codebase_URL_Map_Handle& map);
232 #endif
233 void set_value_map (Value_Map_Handle& map);
235 /// If indirect map is not nil and not empty, unbind all entries.
236 /// Called after marshalling.
237 void reset_vt_indirect_maps ();
239 /// Calculate the offset between pos and current wr_ptr.
240 int offset (char* pos);
242 private:
243 // disallow copying...
244 TAO_OutputCDR (const TAO_OutputCDR& rhs);
245 TAO_OutputCDR& operator= (const TAO_OutputCDR& rhs);
247 private:
249 * @name Outgoing GIOP Fragment Related Attributes
251 * These attributes are only used when fragmenting outgoing GIOP
252 * requests and replies.
254 //@{
255 /// Strategy that sends data currently marshaled into this
256 /// TAO_OutputCDR stream if necessary.
257 TAO_GIOP_Fragmentation_Strategy * const fragmentation_strategy_;
259 /// Are there more data fragments to come?
260 bool more_fragments_;
262 /// Request ID for the request currently being marshaled.
263 CORBA::ULong request_id_;
265 /// Stub object associated with the request.
266 TAO_Stub * stub_;
268 /// Twoway, oneway, reply?
270 * @see TAO_Transport
272 TAO_Message_Semantics message_semantics_;
274 /// Request/reply send timeout.
275 ACE_Time_Value * timeout_;
276 //@}
278 /// These maps are used by valuetype indirection support.
279 Repo_Id_Map_Handle repo_id_map_;
280 #ifdef TAO_HAS_VALUETYPE_CODEBASE
281 Codebase_URL_Map_Handle codebase_map_;
282 #endif
283 Value_Map_Handle value_map_;
287 * @class TAO_InputCDR
289 * @brief A CDR stream for reading, i.e. for demarshalling.
291 * This class is based on the the CORBA spec for Java (98-02-29),
292 * java class omg.org.CORBA.portable.InputStream.
293 * It diverts in a few ways:
294 * + Operations to retrieve basic types take parameters by
295 * reference.
296 * + Operations taking arrays don't have offsets, because in C++
297 * it is easier to describe an array starting from x+offset.
298 * + Operations return an error status, because exceptions are
299 * not widely available in C++ (yet).
300 * A particularly useful static member function for this buffer is
301 * an interpretive encoding routine, usable as a typecode
302 * interpreter callback. Ditto for decoding. These are used to
303 * support all OMG-IDL datatypes, even those not supported
304 * directly by put/get primitives.
306 class TAO_Export TAO_InputCDR : public ACE_InputCDR
308 public:
309 typedef ACE_Hash_Map_Manager<void*, ACE_CString, ACE_Null_Mutex> Repo_Id_Map;
310 typedef Repo_Id_Map Codebase_URL_Map;
311 typedef ACE_Hash_Map_Manager<void*, void*, ACE_Null_Mutex> Value_Map;
313 typedef TAO_Intrusive_Ref_Count_Object<Repo_Id_Map, ACE_Null_Mutex> RC_Repo_Id_Map;
314 typedef TAO_Intrusive_Ref_Count_Object<Codebase_URL_Map, ACE_Null_Mutex> RC_Codebase_URL_Map;
315 typedef TAO_Intrusive_Ref_Count_Object<Value_Map, ACE_Null_Mutex> RC_Value_Map;
317 typedef TAO_Intrusive_Ref_Count_Handle<RC_Repo_Id_Map> Repo_Id_Map_Handle;
318 typedef TAO_Intrusive_Ref_Count_Handle<RC_Codebase_URL_Map> Codebase_URL_Map_Handle;
319 typedef TAO_Intrusive_Ref_Count_Handle<RC_Value_Map> Value_Map_Handle;
322 * Create an input stream from an arbitrary buffer, care must be
323 * exercised wrt alignment, because this constructor will *not* work
324 * if the buffer is unproperly aligned.
326 TAO_InputCDR (const char* buf,
327 size_t bufsiz,
328 int byte_order = ACE_CDR_BYTE_ORDER,
329 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
330 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
331 TAO_ORB_Core* orb_core = 0);
333 /// Create an empty input stream. The caller is responsible for
334 /// putting the right data and providing the right alignment.
335 TAO_InputCDR (size_t bufsiz,
336 int byte_order = ACE_CDR_BYTE_ORDER,
337 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
338 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
339 TAO_ORB_Core* orb_core = 0);
341 /// Create an input stream from an ACE_Message_Block
342 TAO_InputCDR (const ACE_Message_Block *data,
343 int byte_order = ACE_CDR_BYTE_ORDER,
344 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
345 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
346 TAO_ORB_Core* orb_core = 0);
348 /// Create an input stream from an ACE_Message_Block with an optional lock
349 /// used to protect the data.
350 TAO_InputCDR (const ACE_Message_Block *data,
351 ACE_Lock* lock,
352 int byte_order = ACE_CDR_BYTE_ORDER,
353 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
354 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
355 TAO_ORB_Core* orb_core = 0);
358 /// Create an input stream from an ACE_Data_Block
359 TAO_InputCDR (ACE_Data_Block *data,
360 ACE_Message_Block::Message_Flags flag = 0,
361 int byte_order = ACE_CDR_BYTE_ORDER,
362 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
363 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
364 TAO_ORB_Core* orb_core = 0);
366 /// Create an input stream from an ACE_Data_Block
367 TAO_InputCDR (ACE_Data_Block *data,
368 ACE_Message_Block::Message_Flags flag,
369 size_t read_pointer_position,
370 size_t write_pointer_position,
371 int byte_order = ACE_CDR_BYTE_ORDER,
372 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
373 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
374 TAO_ORB_Core* orb_core = 0);
377 * Make a copy of the current stream state, but does not copy the
378 * internal buffer; so the same stream can be read multiple times
379 * efficiently.
381 TAO_InputCDR (const TAO_InputCDR& rhs);
383 /// When interpreting indirected TypeCodes it is useful to make a
384 /// "copy" of the stream starting in the new position.
385 TAO_InputCDR (const TAO_InputCDR& rhs,
386 size_t size,
387 ACE_CDR::Long offset);
389 * This creates an encapsulated stream, the first byte must be (per
390 * the spec) the byte order of the encapsulation. The default
391 * values for the allocators in this constructor are not 0, but are
392 * generated by the ORB. Refer to the constructor body in CDR.cpp
393 * for the code that supplies these values to the base class
394 * constructor.
396 TAO_InputCDR (const TAO_InputCDR& rhs,
397 size_t size);
399 /// Create an input CDR from an output CDR.
400 TAO_InputCDR (const TAO_OutputCDR& rhs,
401 ACE_Allocator* buffer_allocator = 0,
402 ACE_Allocator* data_block_allocator = 0,
403 ACE_Allocator* message_block_allocator = 0,
404 TAO_ORB_Core* orb_core = 0);
406 /// Initialize the contents of one CDR from another, without data
407 /// copying and with minimum locking overhead.
408 TAO_InputCDR (ACE_InputCDR::Transfer_Contents rhs,
409 TAO_ORB_Core* orb_core = 0);
411 #if defined (ACE_HAS_CPP11)
412 TAO_InputCDR& operator= (const TAO_InputCDR&) = default;
413 #endif /* ACE_HAS_CPP11 */
415 /// Destructor
416 virtual ~TAO_InputCDR (void);
418 // = TAO specific methods.
420 /// Accessor
421 TAO_ORB_Core *orb_core (void) const;
423 ACE_Message_Block::Message_Flags
424 clr_mb_flags( ACE_Message_Block::Message_Flags less_flags );
426 // = TAO specific methods.
427 static void throw_stub_exception (int error_num);
428 static void throw_skel_exception (int error_num);
430 /// These methods are used by valuetype indirection support.
431 /// Accessor to the indirect maps.
432 Repo_Id_Map_Handle& get_repo_id_map ();
433 Codebase_URL_Map_Handle& get_codebase_url_map ();
434 Value_Map_Handle& get_value_map ();
436 /// Updater of the maps.
437 /// These updaters are used to make indirect maps in original stream
438 /// take effect even during marshalling/demarshalling a redirected stream.
439 void set_repo_id_map (Repo_Id_Map_Handle& map);
440 void set_codebase_url_map (Codebase_URL_Map_Handle& map);
441 void set_value_map (Value_Map_Handle& map);
443 /// If indirect map is not nil and not empty, unbind all entries.
444 /// Called after demarshalling.
445 void reset_vt_indirect_maps ();
447 private:
448 /// The ORB_Core, required to extract object references.
449 TAO_ORB_Core* orb_core_;
451 /// These maps are used by valuetype indirection support.
452 Repo_Id_Map_Handle repo_id_map_;
453 Codebase_URL_Map_Handle codebase_map_;
454 Value_Map_Handle value_map_;
457 TAO_END_VERSIONED_NAMESPACE_DECL
459 #if defined(__ACE_INLINE__)
460 # include "tao/CDR.inl"
461 #else
463 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
465 // CDR output operators for CORBA types
467 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
468 CORBA::Short x);
469 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
470 CORBA::UShort x);
471 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
472 CORBA::Long x);
473 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
474 CORBA::ULong x);
475 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
476 CORBA::LongLong x);
477 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
478 CORBA::ULongLong x);
479 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR& os,
480 CORBA::LongDouble x);
481 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
482 CORBA::Float x);
483 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
484 CORBA::Double x);
485 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
486 const CORBA::Char* x);
487 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
488 const CORBA::WChar* x);
489 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
490 ACE_OutputCDR::from_string x);
491 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
492 ACE_OutputCDR::from_wstring x);
493 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
494 const std::string &x);
495 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
496 ACE_OutputCDR::from_std_string x);
497 #if !defined(ACE_LACKS_STD_WSTRING)
498 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
499 const std::wstring &x);
500 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
501 ACE_OutputCDR::from_std_wstring x);
502 #endif /* ACE_LACKS_STD_WSTRING */
504 // CDR input operators for CORBA types
506 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
507 CORBA::Short &x);
508 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
509 CORBA::UShort &x);
510 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
511 CORBA::Long &x);
512 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
513 CORBA::ULong &x);
514 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
515 CORBA::LongLong &x);
516 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
517 CORBA::ULongLong &x);
518 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
519 CORBA::LongDouble &x);
520 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
521 CORBA::Float &x);
522 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
523 CORBA::Double &x);
524 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
525 CORBA::Char* &x);
526 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
527 CORBA::WChar* &x);
528 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
529 ACE_InputCDR::to_string x);
530 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
531 ACE_InputCDR::to_wstring x);
532 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
533 std::string &x);
534 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
535 ACE_InputCDR::to_std_string x);
536 #if !defined(ACE_LACKS_STD_WSTRING)
537 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
538 std::wstring &x);
539 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
540 ACE_InputCDR::to_std_wstring x);
541 #endif /* ACE_LACKS_STD_WSTRING */
543 TAO_END_VERSIONED_NAMESPACE_DECL
545 #endif /* __ACE_INLINE */
547 #include /**/ "ace/post.h"
548 #endif /* TAO_CDR_H */