Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / tao / CDR.h
blob8a11ed08a86b0c8828da1620aa809d53e90914c9
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_IDLv4.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 ();
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 () 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 () const;
207 /// Stub object associated with the request.
208 TAO_Stub * stub () const;
210 /// Message semantics (twoway, oneway, reply)
211 TAO_Message_Semantics message_semantics () const;
213 /// Maximum time to wait for outgoing message to be sent.
214 ACE_Time_Value * timeout () 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 TAO_OutputCDR (const TAO_OutputCDR&rhs) = delete;
244 TAO_OutputCDR& operator= (const TAO_OutputCDR&) = delete;
245 TAO_OutputCDR (TAO_OutputCDR&&) = delete;
246 TAO_OutputCDR& operator= (TAO_OutputCDR&&) = delete;
248 private:
250 * @name Outgoing GIOP Fragment Related Attributes
252 * These attributes are only used when fragmenting outgoing GIOP
253 * requests and replies.
255 //@{
256 /// Strategy that sends data currently marshaled into this
257 /// TAO_OutputCDR stream if necessary.
258 TAO_GIOP_Fragmentation_Strategy * const fragmentation_strategy_;
260 /// Are there more data fragments to come?
261 bool more_fragments_;
263 /// Request ID for the request currently being marshaled.
264 CORBA::ULong request_id_;
266 /// Stub object associated with the request.
267 TAO_Stub * stub_;
269 /// Twoway, oneway, reply?
271 * @see TAO_Transport
273 TAO_Message_Semantics message_semantics_;
275 /// Request/reply send timeout.
276 ACE_Time_Value * timeout_;
277 //@}
279 /// These maps are used by valuetype indirection support.
280 Repo_Id_Map_Handle repo_id_map_;
281 #ifdef TAO_HAS_VALUETYPE_CODEBASE
282 Codebase_URL_Map_Handle codebase_map_;
283 #endif
284 Value_Map_Handle value_map_;
288 * @class TAO_InputCDR
290 * @brief A CDR stream for reading, i.e. for demarshalling.
292 * This class is based on the the CORBA spec for Java (98-02-29),
293 * java class omg.org.CORBA.portable.InputStream.
294 * It diverts in a few ways:
295 * + Operations to retrieve basic types take parameters by
296 * reference.
297 * + Operations taking arrays don't have offsets, because in C++
298 * it is easier to describe an array starting from x+offset.
299 * + Operations return an error status, because exceptions are
300 * not widely available in C++ (yet).
301 * A particularly useful static member function for this buffer is
302 * an interpretive encoding routine, usable as a typecode
303 * interpreter callback. Ditto for decoding. These are used to
304 * support all OMG-IDL datatypes, even those not supported
305 * directly by put/get primitives.
307 class TAO_Export TAO_InputCDR : public ACE_InputCDR
309 public:
310 typedef ACE_Hash_Map_Manager<void*, ACE_CString, ACE_Null_Mutex> Repo_Id_Map;
311 typedef Repo_Id_Map Codebase_URL_Map;
312 typedef ACE_Hash_Map_Manager<void*, void*, ACE_Null_Mutex> Value_Map;
314 typedef TAO_Intrusive_Ref_Count_Object<Repo_Id_Map, ACE_Null_Mutex> RC_Repo_Id_Map;
315 typedef TAO_Intrusive_Ref_Count_Object<Codebase_URL_Map, ACE_Null_Mutex> RC_Codebase_URL_Map;
316 typedef TAO_Intrusive_Ref_Count_Object<Value_Map, ACE_Null_Mutex> RC_Value_Map;
318 typedef TAO_Intrusive_Ref_Count_Handle<RC_Repo_Id_Map> Repo_Id_Map_Handle;
319 typedef TAO_Intrusive_Ref_Count_Handle<RC_Codebase_URL_Map> Codebase_URL_Map_Handle;
320 typedef TAO_Intrusive_Ref_Count_Handle<RC_Value_Map> Value_Map_Handle;
323 * Create an input stream from an arbitrary buffer, care must be
324 * exercised wrt alignment, because this constructor will *not* work
325 * if the buffer is unproperly aligned.
327 TAO_InputCDR (const char* buf,
328 size_t bufsiz,
329 int byte_order = ACE_CDR_BYTE_ORDER,
330 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
331 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
332 TAO_ORB_Core* orb_core = 0);
334 /// Create an empty input stream. The caller is responsible for
335 /// putting the right data and providing the right alignment.
336 TAO_InputCDR (size_t bufsiz,
337 int byte_order = ACE_CDR_BYTE_ORDER,
338 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
339 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
340 TAO_ORB_Core* orb_core = 0);
342 /// Create an input stream from an ACE_Message_Block
343 TAO_InputCDR (const ACE_Message_Block *data,
344 int byte_order = ACE_CDR_BYTE_ORDER,
345 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
346 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
347 TAO_ORB_Core* orb_core = 0);
349 /// Create an input stream from an ACE_Message_Block with an optional lock
350 /// used to protect the data.
351 TAO_InputCDR (const ACE_Message_Block *data,
352 ACE_Lock* lock,
353 int byte_order = ACE_CDR_BYTE_ORDER,
354 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
355 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
356 TAO_ORB_Core* orb_core = 0);
359 /// Create an input stream from an ACE_Data_Block
360 TAO_InputCDR (ACE_Data_Block *data,
361 ACE_Message_Block::Message_Flags flag = 0,
362 int byte_order = ACE_CDR_BYTE_ORDER,
363 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
364 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
365 TAO_ORB_Core* orb_core = 0);
367 /// Create an input stream from an ACE_Data_Block
368 TAO_InputCDR (ACE_Data_Block *data,
369 ACE_Message_Block::Message_Flags flag,
370 size_t read_pointer_position,
371 size_t write_pointer_position,
372 int byte_order = ACE_CDR_BYTE_ORDER,
373 ACE_CDR::Octet major_version = TAO_DEF_GIOP_MAJOR,
374 ACE_CDR::Octet minor_version = TAO_DEF_GIOP_MINOR,
375 TAO_ORB_Core* orb_core = 0);
378 * Make a copy of the current stream state, but does not copy the
379 * internal buffer; so the same stream can be read multiple times
380 * efficiently.
382 TAO_InputCDR (const TAO_InputCDR& rhs);
384 /// When interpreting indirected TypeCodes it is useful to make a
385 /// "copy" of the stream starting in the new position.
386 TAO_InputCDR (const TAO_InputCDR& rhs,
387 size_t size,
388 ACE_CDR::Long offset);
390 * This creates an encapsulated stream, the first byte must be (per
391 * the spec) the byte order of the encapsulation. The default
392 * values for the allocators in this constructor are not 0, but are
393 * generated by the ORB. Refer to the constructor body in CDR.cpp
394 * for the code that supplies these values to the base class
395 * constructor.
397 TAO_InputCDR (const TAO_InputCDR& rhs,
398 size_t size);
400 /// Create an input CDR from an output CDR.
401 TAO_InputCDR (const TAO_OutputCDR& rhs,
402 ACE_Allocator* buffer_allocator = 0,
403 ACE_Allocator* data_block_allocator = 0,
404 ACE_Allocator* message_block_allocator = 0,
405 TAO_ORB_Core* orb_core = 0);
407 /// Initialize the contents of one CDR from another, without data
408 /// copying and with minimum locking overhead.
409 TAO_InputCDR (ACE_InputCDR::Transfer_Contents rhs,
410 TAO_ORB_Core* orb_core = 0);
412 TAO_InputCDR& operator= (const TAO_InputCDR&) = default;
414 /// Destructor
415 virtual ~TAO_InputCDR ();
417 // = TAO specific methods.
419 /// Accessor
420 TAO_ORB_Core *orb_core () const;
422 ACE_Message_Block::Message_Flags
423 clr_mb_flags( ACE_Message_Block::Message_Flags less_flags );
425 // = TAO specific methods.
426 static void throw_stub_exception (int error_num);
427 static void throw_skel_exception (int error_num);
429 /// These methods are used by valuetype indirection support.
430 /// Accessor to the indirect maps.
431 Repo_Id_Map_Handle& get_repo_id_map ();
432 Codebase_URL_Map_Handle& get_codebase_url_map ();
433 Value_Map_Handle& get_value_map ();
435 /// Updater of the maps.
436 /// These updaters are used to make indirect maps in original stream
437 /// take effect even during marshalling/demarshalling a redirected stream.
438 void set_repo_id_map (Repo_Id_Map_Handle& map);
439 void set_codebase_url_map (Codebase_URL_Map_Handle& map);
440 void set_value_map (Value_Map_Handle& map);
442 /// If indirect map is not nil and not empty, unbind all entries.
443 /// Called after demarshalling.
444 void reset_vt_indirect_maps ();
446 private:
447 /// The ORB_Core, required to extract object references.
448 TAO_ORB_Core* orb_core_;
450 /// These maps are used by valuetype indirection support.
451 Repo_Id_Map_Handle repo_id_map_;
452 Codebase_URL_Map_Handle codebase_map_;
453 Value_Map_Handle value_map_;
456 TAO_END_VERSIONED_NAMESPACE_DECL
458 #if defined(__ACE_INLINE__)
459 # include "tao/CDR.inl"
460 #else
462 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
464 // CDR output operators for CORBA types
466 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
467 CORBA::Short x);
468 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
469 CORBA::UShort x);
470 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
471 CORBA::Long x);
472 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
473 CORBA::ULong x);
474 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
475 CORBA::LongLong x);
476 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
477 CORBA::ULongLong x);
478 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR& os,
479 CORBA::LongDouble x);
480 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
481 CORBA::Float x);
482 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
483 CORBA::Double x);
484 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
485 const CORBA::Char* x);
486 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
487 const CORBA::WChar* x);
488 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
489 ACE_OutputCDR::from_string x);
490 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
491 ACE_OutputCDR::from_wstring x);
492 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
493 const std::string &x);
494 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
495 const std::string_view &x);
496 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
497 ACE_OutputCDR::from_std_string x);
498 #if !defined(ACE_LACKS_STD_WSTRING)
499 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
500 const std::wstring &x);
501 TAO_Export CORBA::Boolean operator<< (TAO_OutputCDR &os,
502 ACE_OutputCDR::from_std_wstring x);
503 #endif /* ACE_LACKS_STD_WSTRING */
505 // CDR input operators for CORBA types
507 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
508 CORBA::Short &x);
509 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
510 CORBA::UShort &x);
511 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
512 CORBA::Long &x);
513 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
514 CORBA::ULong &x);
515 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
516 CORBA::LongLong &x);
517 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
518 CORBA::ULongLong &x);
519 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
520 CORBA::LongDouble &x);
521 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
522 CORBA::Float &x);
523 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
524 CORBA::Double &x);
525 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
526 CORBA::Char* &x);
527 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &is,
528 CORBA::WChar* &x);
529 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
530 ACE_InputCDR::to_string x);
531 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
532 ACE_InputCDR::to_wstring x);
533 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
534 std::string &x);
535 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
536 ACE_InputCDR::to_std_string x);
537 #if !defined(ACE_LACKS_STD_WSTRING)
538 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
539 std::wstring &x);
540 TAO_Export CORBA::Boolean operator>> (TAO_InputCDR &os,
541 ACE_InputCDR::to_std_wstring x);
542 #endif /* ACE_LACKS_STD_WSTRING */
544 TAO_END_VERSIONED_NAMESPACE_DECL
546 #endif /* __ACE_INLINE */
548 #include /**/ "ace/post.h"
549 #endif /* TAO_CDR_H */