in yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPIncomingMessage.java [306:586]
boolean consumeBuffer(org.apache.yoko.orb.OCI.Buffer buf) {
//
// Consume input buffer
//
boolean result = false;
//
// Handle initial fragmented message
//
if (fragment_ && type_ != org.omg.GIOP.MsgType_1_1.Fragment) {
if (version_.minor < 1) {
throw new org.omg.CORBA.COMM_FAILURE(org.apache.yoko.orb.OB.MinorCodes
.describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorFragment),
org.apache.yoko.orb.OB.MinorCodes.MinorFragment,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
} else if (version_.minor == 1) {
//
// In GIOP 1.1, fragments are only supported for request and
// reply messages
//
if (type_ != org.omg.GIOP.MsgType_1_1.Request
&& type_ != org.omg.GIOP.MsgType_1_1.Reply)
throw new org.omg.CORBA.COMM_FAILURE(org.apache.yoko.orb.OB.MinorCodes
.describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorFragment),
org.apache.yoko.orb.OB.MinorCodes.MinorFragment,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
//
// If lastFragment_ is not 0, then the previous fragmented
// message may have been cancelled
//
if (lastFragment_ != null)
lastFragment_ = null;
//
// Try to obtain the request ID by unmarshalling the
// Request or Reply header data. If the header is fragmented,
// a MARSHAL exception could be raised if we don't have enough
// data.
//
int reqId = 0;
boolean haveReqId = false;
try {
org.apache.yoko.orb.CORBA.InputStream in = new org.apache.yoko.orb.CORBA.InputStream(
buf, 12, swap());
skipServiceContextList(in);
reqId = in.read_ulong();
haveReqId = true;
} catch (org.omg.CORBA.MARSHAL ex) {
}
lastFragment_ = new Fragment();
lastFragment_.version = new org.omg.GIOP.Version(
version_.major, version_.minor);
lastFragment_.byteOrder = byteOrder_;
lastFragment_.reqId = reqId;
lastFragment_.haveReqId = haveReqId;
lastFragment_.type = type_;
lastFragment_.buf = buf;
lastFragment_.next = null;
} else // GIOP 1.2
{
//
// In GIOP 1.2, fragments are only supported for request,
// reply, locate request and locate reply messages
//
if (type_ != org.omg.GIOP.MsgType_1_1.Request
&& type_ != org.omg.GIOP.MsgType_1_1.Reply
&& type_ != org.omg.GIOP.MsgType_1_1.LocateRequest
&& type_ != org.omg.GIOP.MsgType_1_1.LocateReply) {
throw new org.omg.CORBA.COMM_FAILURE(org.apache.yoko.orb.OB.MinorCodes
.describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorFragment),
org.apache.yoko.orb.OB.MinorCodes.MinorFragment,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
}
//
// Try to obtain the request ID by unmarshalling the
// header data. If the header is fragmented, a MARSHAL
// exception could be raised if we don't have enough
// data.
//
int reqId = 0;
boolean haveReqId = false;
try {
org.apache.yoko.orb.CORBA.InputStream in = new org.apache.yoko.orb.CORBA.InputStream(
buf, 12, swap());
reqId = in.read_ulong();
haveReqId = true;
} catch (org.omg.CORBA.MARSHAL ex) {
}
//
// What to do if initial message doesn't contain the
// request ID?
//
Assert._OB_assert(haveReqId);
//
// Add new fragment to fragment list
//
Fragment f = new Fragment();
f.version = new org.omg.GIOP.Version(version_.major,
version_.minor);
f.byteOrder = byteOrder_;
f.reqId = reqId;
f.haveReqId = haveReqId;
f.type = type_;
f.buf = buf;
f.next = fragmentHead_;
fragmentHead_ = f;
}
} else if (type_ == org.omg.GIOP.MsgType_1_1.Fragment) {
Fragment complete = null;
if (version_.minor < 1) {
//
// Fragment not supported in GIOP 1.0
//
throw new org.omg.CORBA.COMM_FAILURE(org.apache.yoko.orb.OB.MinorCodes
.describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorFragment),
org.apache.yoko.orb.OB.MinorCodes.MinorFragment,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
} else if (version_.minor == 1) {
//
// If lastFragment_ == 0, then we received a Fragment message
// without an initial message
//
if (lastFragment_ == null)
throw new org.omg.CORBA.COMM_FAILURE(org.apache.yoko.orb.OB.MinorCodes
.describeCommFailure(org.apache.yoko.orb.OB.MinorCodes.MinorFragment),
org.apache.yoko.orb.OB.MinorCodes.MinorFragment,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
//
// Append buffer to existing data. We need to skip the
// header data (the input stream is already positioned
// past the header).
//
lastFragment_.add(orbInstance_, buf);
//
// If we haven't read the request ID yet, then try to
// get it now
//
if (!lastFragment_.haveReqId) {
org.apache.yoko.orb.CORBA.InputStream reqIn = new org.apache.yoko.orb.CORBA.InputStream(
lastFragment_.buf, 12, swap());
try {
skipServiceContextList(reqIn);
lastFragment_.reqId = reqIn.read_ulong();
lastFragment_.haveReqId = true;
} catch (org.omg.CORBA.MARSHAL ex) {
}
}
//
// If fragment_ == false, then this is the last fragment
//
if (!fragment_) {
complete = lastFragment_;
lastFragment_ = null;
}
} else // GIOP 1.2
{
//
// GIOP 1.2 defines the FragmentHeader message header,
// to allow interleaving of Fragment messages for
// different requests
//
org.apache.yoko.orb.CORBA.InputStream in = new org.apache.yoko.orb.CORBA.InputStream(
buf, 12, swap());
int reqId = readFragmentHeader(in);
//
// Find fragment data for request
//
Fragment frag = null;
Fragment p = fragmentHead_;
Fragment prev = null;
while (p != null) {
Fragment f = p;
if (f.haveReqId && f.reqId == reqId) {
frag = f;
break;
} else {
prev = p;
p = f.next;
}
}
//
// If no fragment was found for the request, then either
// the request was discarded, or the server is sending
// invalid messages. Otherwise, we can append the buffer
// to the existing data.
//
if (frag != null) {
//
// Append buffer to existing data. We need to skip the
// header data (the input stream is already positioned
// past the header).
//
frag.add(orbInstance_, in._OB_buffer());
//
// If fragment_ == false, then this is the last fragment
//
if (!fragment_) {
//
// Remove fragment from list
//
if (prev == null)
fragmentHead_ = frag.next;
else
prev.next = frag.next;
complete = frag;
}
}
}
//
// We have received the last fragment, so reset our internal
// state to appear as if we had just received the entire message
//
if (complete != null) {
version_ = complete.version;
byteOrder_ = complete.byteOrder;
type_ = complete.type;
fragment_ = false;
// NOTE: size_ is the size of the message, which doesn't
// include the message header. We need to adjust this for
// fragmented messages otherwise we risk not detecting the
// correct end of the buffer.
size_ = complete.buf.length() - 12;
in_ = new org.apache.yoko.orb.CORBA.InputStream(complete.buf,
12, swap());
complete = null;
result = true;
}
} else if (type_ == org.omg.GIOP.MsgType_1_1.CancelRequest) {
in_ = new org.apache.yoko.orb.CORBA.InputStream(buf, 12, swap());
//
// Check if cancelled message corresponds to a fragment
//
int reqId = readCancelRequestHeader();
if (version_.minor == 1) // GIOP 1.1
{
if (lastFragment_ != null && lastFragment_.haveReqId
&& lastFragment_.reqId == reqId) {
lastFragment_ = null;
}
} else // GIOP 1.2
{
Fragment p = fragmentHead_;
while (p != null) {
Fragment f = p;
if (f.haveReqId && f.reqId == reqId) {
p = f.next;
f = null;
break;
} else
p = f.next;
}
}
in_._OB_reset();
result = true;
} else {
//
// Message is not fragmented and is not a CancelRequest, so
// we must have the complete message
//
in_ = new org.apache.yoko.orb.CORBA.InputStream(buf, 12, swap());
result = true;
}
return result;
}