Methods Summary |
---|
protected void | alignAndReserve(int align, int n)
// headerPadding bit is set by the write operation of RequestMessage_1_2
// or ReplyMessage_1_2 classes. When set, the very first body write
// operation (from the stub code) would trigger an alignAndReserve
// method call, that would in turn add the appropriate header padding,
// such that the body is aligned on a 8-octet boundary. The padding
// is required for GIOP versions 1.2 and above, only if body is present.
if (headerPadding == true) {
headerPadding = false;
alignOnBoundary(ORBConstants.GIOP_12_MSG_BODY_ALIGNMENT);
}
// In GIOP 1.2, we always end fragments at our
// fragment size, which is an "evenly divisible
// 8 byte boundary" (aka divisible by 16). A fragment can
// end with appropriate alignment padding, but no padding
// is needed with respect to the next GIOP fragment
// header since it ends on an 8 byte boundary.
bbwi.position(bbwi.position() + computeAlignment(align));
if (bbwi.position() + n > bbwi.buflen)
grow(align, n);
|
private void | checkPrimitiveAcrossFragmentedChunk()
if (primitiveAcrossFragmentedChunk) {
primitiveAcrossFragmentedChunk = false;
inBlock = false;
// It would be nice to have a StreamPosition
// abstraction if we could avoid allocation
// overhead.
blockSizeIndex = -1;
blockSizePosition = -1;
// Start a new chunk
start_block();
}
|
public com.sun.corba.se.spi.ior.iiop.GIOPVersion | getGIOPVersion()
return GIOPVersion.V1_2;
|
protected void | grow(int align, int n)
// Save the current size for possible post-fragmentation calculation
int oldSize = bbwi.position();
// See notes where specialChunk is defined, as well as the
// above notes for primitiveAcrossFragmentedChunk.
//
// If we're writing a primitive and chunking, we need to update
// the chunk length to include the length of the primitive (unless
// this complexity is handled by specialChunk).
//
// Note that this is wasted processing in the grow case, but that
// we don't actually close the chunk in that case.
boolean handleChunk = (inBlock && !specialChunk);
if (handleChunk) {
int oldIndex = bbwi.position();
bbwi.position(blockSizeIndex - 4);
writeLongWithoutAlign((oldIndex - blockSizeIndex) + n);
bbwi.position(oldIndex);
}
bbwi.needed = n;
bufferManagerWrite.overflow(bbwi);
// At this point, if we fragmented, we should have a ByteBufferWithInfo
// with the fragment header already marshalled. The buflen and position
// should be updated accordingly, and the fragmented flag should be set.
// Note that fragmented is only true in the streaming and collect cases.
if (bbwi.fragmented) {
// Clear the flag
bbwi.fragmented = false;
// Update fragmentOffset so indirections work properly.
// At this point, oldSize is the entire length of the
// previous buffer. bbwi.position() is the length of the
// fragment header of this buffer.
fragmentOffset += (oldSize - bbwi.position());
// We just fragmented, and need to signal that we should
// start a new chunk after writing the primitive.
if (handleChunk)
primitiveAcrossFragmentedChunk = true;
}
|
protected void | handleSpecialChunkBegin(int requiredSize)
// If we're chunking and the item won't fit in the buffer
if (inBlock && requiredSize + bbwi.position() > bbwi.buflen) {
// Duplicating some code from end_block. Compute
// and write the total chunk length.
int oldSize = bbwi.position();
bbwi.position(blockSizeIndex - 4);
//write_long(oldSize - blockSizeIndex);
writeLongWithoutAlign((oldSize - blockSizeIndex) + requiredSize);
bbwi.position(oldSize);
// Set the special flag so we don't end the chunk when
// we fragment
specialChunk = true;
}
|
protected void | handleSpecialChunkEnd()
// If we're in a chunk and the item spanned fragments
if (inBlock && specialChunk) {
// This is unnecessary, but I just want to show that
// we're done with the current chunk. (the end_block
// call is inappropriate here)
inBlock = false;
blockSizeIndex = -1;
blockSizePosition = -1;
// Start a new chunk since we fragmented during the item.
// Thus, no one can go back to add more to the chunk length
start_block();
// Now turn off the flag so we go back to the normal
// behavior of closing a chunk when we fragment and
// reopening afterwards.
specialChunk = false;
}
|
void | setHeaderPadding(boolean headerPadding)
this.headerPadding = headerPadding;
|
public void | write_long(int x)
super.write_long(x);
checkPrimitiveAcrossFragmentedChunk();
|
public void | write_longlong(long x)
super.write_longlong(x);
checkPrimitiveAcrossFragmentedChunk();
|
public void | write_octet(byte x)
super.write_octet(x);
checkPrimitiveAcrossFragmentedChunk();
|
public void | write_short(short x)
super.write_short(x);
checkPrimitiveAcrossFragmentedChunk();
|
public void | write_wchar(char x)
// In GIOP 1.2, a wchar is encoded as an unsigned octet length
// followed by the octets of the converted wchar. This is good,
// but it causes problems with our chunking code. We don't
// want that octet to get put in a different chunk at the end
// of the previous fragment.
//
// Ensure that this won't happen by overriding write_wchar_array
// and doing our own handleSpecialChunkBegin/End here.
CodeSetConversion.CTBConverter converter = getWCharConverter();
converter.convert(x);
handleSpecialChunkBegin(1 + converter.getNumBytes());
write_octet((byte)converter.getNumBytes());
byte[] result = converter.getBytes();
// Write the bytes without messing with chunking
// See CDROutputStream_1_0
internalWriteOctetArray(result, 0, converter.getNumBytes());
handleSpecialChunkEnd();
|
public void | write_wchar_array(char[] value, int offset, int length)
if (value == null) {
throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
}
CodeSetConversion.CTBConverter converter = getWCharConverter();
// Unfortunately, because of chunking, we have to convert the
// entire char[] to a byte[] array first so we can know how
// many bytes we're writing ahead of time. You can't split
// an array of primitives into multiple chunks.
int totalNumBytes = 0;
// Remember that every wchar starts with an octet telling
// its length. The buffer size is an upper bound estimate.
int maxLength = (int)Math.ceil(converter.getMaxBytesPerChar() * length);
byte[] buffer = new byte[maxLength + length];
for (int i = 0; i < length; i++) {
// Convert one wchar
converter.convert(value[offset + i]);
// Make sure to add the octet length
buffer[totalNumBytes++] = (byte)converter.getNumBytes();
// Copy it into our buffer
System.arraycopy(converter.getBytes(), 0,
buffer, totalNumBytes,
converter.getNumBytes());
totalNumBytes += converter.getNumBytes();
}
// Now that we know the total length, we can deal with chunking.
// Note that we don't have to worry about alignment since they're
// just octets.
handleSpecialChunkBegin(totalNumBytes);
// Must use totalNumBytes rather than buffer.length since the
// buffer.length is only the upper bound estimate.
internalWriteOctetArray(buffer, 0, totalNumBytes);
handleSpecialChunkEnd();
|
public void | write_wstring(java.lang.String value)
if (value == null) {
throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
}
// In GIOP 1.2, wstrings are not terminated by a null. The
// length is the number of octets in the converted format.
// A zero length string is represented with the 4 byte length
// value of 0.
if (value.length() == 0) {
write_long(0);
return;
}
CodeSetConversion.CTBConverter converter = getWCharConverter();
converter.convert(value);
handleSpecialChunkBegin(computeAlignment(4) + 4 + converter.getNumBytes());
write_long(converter.getNumBytes());
// Write the octet array without tampering with chunking
internalWriteOctetArray(converter.getBytes(), 0, converter.getNumBytes());
handleSpecialChunkEnd();
|