2 #include "tao/On_Demand_Fragmentation_Strategy.h"
4 #include "tao/Transport.h"
6 #include "tao/GIOP_Message_Base.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 (
25 TAO_On_Demand_Fragmentation_Strategy::fragment (
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)
43 // Determine increase in CDR stream length if pending data is
44 // marshaled, taking into account the alignment for the given data
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
)
51 // Except for the last fragment, fragmented GIOP messages must
52 // always be aligned on an 8-byte boundary. Padding will be added
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)
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"
81 if (this->transport_
->send_message (cdr
,
84 cdr
.message_semantics (),
87 // Now generate a fragment header.
88 || this->transport_
->messaging_object ()->generate_fragment_header (
90 cdr
.request_id ()) != 0)