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