Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / TAO / tao / On_Demand_Fragmentation_Strategy.cpp
blobb5261fde69721687691ae0637d6953eb0950d1a8
2 #include "tao/On_Demand_Fragmentation_Strategy.h"
4 #include "tao/Transport.h"
5 #include "tao/CDR.h"
6 #include "tao/GIOP_Message_Base.h"
7 #include "tao/debug.h"
9 #include "ace/Truncate.h"
11 TAO_On_Demand_Fragmentation_Strategy::TAO_On_Demand_Fragmentation_Strategy (
12 TAO_Transport * transport,
13 CORBA::ULong max_message_size)
14 : transport_ (transport)
15 , max_message_size_ (max_message_size)
19 TAO_On_Demand_Fragmentation_Strategy::~TAO_On_Demand_Fragmentation_Strategy (
24 int
25 TAO_On_Demand_Fragmentation_Strategy::fragment (
26 TAO_OutputCDR & cdr,
27 ACE_CDR::ULong pending_alignment,
28 ACE_CDR::ULong pending_length)
30 if (this->transport_ == nullptr)
31 return 0; // No transport. Can't fragment.
33 TAO_GIOP_Message_Version giop_version;
35 cdr.get_version (giop_version);
37 // GIOP fragments are supported in GIOP 1.1 and better, but TAO only
38 // supports them in 1.2 or better since GIOP 1.1 fragments do not
39 // have a fragment message header.
40 if (giop_version.major == 1 && giop_version.minor < 2)
41 return -1;
43 // Determine increase in CDR stream length if pending data is
44 // marshaled, taking into account the alignment for the given data
45 // type.
46 ACE_CDR::ULong const total_pending_length =
47 ACE_Utils::truncate_cast<ACE_CDR::ULong> (
48 ACE_align_binary (cdr.total_length (), pending_alignment)
49 + pending_length);
51 // Except for the last fragment, fragmented GIOP messages must
52 // always be aligned on an 8-byte boundary. Padding will be added
53 // if necessary.
54 ACE_CDR::ULong const aligned_length =
55 ACE_Utils::truncate_cast<ACE_CDR::ULong> (
56 ACE_align_binary (total_pending_length, ACE_CDR::MAX_ALIGNMENT));
58 // this->max_message_size_ must be >= 24 bytes, i.e.:
59 // 12 for GIOP protocol header
60 // + 4 for GIOP fragment header
61 // + 8 for payload (including padding)
62 // since fragments must be aligned on an 8 byte boundary.
63 if (aligned_length > this->max_message_size_)
65 // Pad the outgoing fragment if necessary.
66 if (cdr.align_write_ptr (ACE_CDR::MAX_ALIGNMENT) != 0)
67 return -1;
69 // More fragments to come.
70 cdr.more_fragments (true);
72 if (TAO_debug_level > 0)
73 TAOLIB_DEBUG ((LM_DEBUG,
74 "TAO (%P|%t) - On_Demand_Fragmentation_Strategy::fragment, "
75 "sending fragment of size %d\n",
76 cdr.total_length ()));
78 // Send the current CDR stream contents through the transport,
79 // making sure to switch on the the GIOP flags "more fragments"
80 // bit.
81 if (this->transport_->send_message (cdr,
82 cdr.stub (),
83 nullptr,
84 cdr.message_semantics (),
85 cdr.timeout ()) == -1
87 // Now generate a fragment header.
88 || this->transport_->messaging_object ()->generate_fragment_header (
89 cdr,
90 cdr.request_id ()) != 0)
91 return -1;
94 return 0;