
com.cosylab.epics.caj.impl.requests.AbstractCARequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jca Show documentation
Show all versions of jca Show documentation
JCA is an EPICS Channel Access library for Java. For more information concerning EPICS or Channel Access please refer to the <a href="http://www.aps.anl.gov/epics">EPICS Web pages</a> or read the <a href="http://www.aps.anl.gov/epics/base/R3-14/8-docs/CAref.html">Channel Access manual (3.14)</a>.
<p>This module also includes CAJ, A 100% pure Java implementation of the EPICS Channel Access library.</p>
/*
* Copyright (c) 2004 by Cosylab
*
* The full license specifying the redistribution, modification, usage and other
* rights and obligations is included with the distribution of this project in
* the file "LICENSE-CAJ". If the license is not included visit Cosylab web site,
* .
*
* THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND, NOT EVEN THE
* IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, ASSUMES
* _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE RESULTING FROM THE USE, MODIFICATION,
* OR REDISTRIBUTION OF THIS SOFTWARE.
*/
package com.cosylab.epics.caj.impl.requests;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.cosylab.epics.caj.impl.CAConstants;
import com.cosylab.epics.caj.impl.Request;
import com.cosylab.epics.caj.impl.Transport;
/**
* @author Matej Sekoranja
* @version $id$
*/
public abstract class AbstractCARequest implements Request {
/**
* Empty (dummy) message.
*/
private static final ByteBuffer EMPTY_MESSAGE = ByteBuffer.allocate(0);
/**
* Request message.
*/
protected ByteBuffer requestMessage = EMPTY_MESSAGE;
/**
* Transport to be used when sending.
*/
protected Transport transport;
/**
* @param transport transport to be used when sending.
*/
public AbstractCARequest(Transport transport) {
this.transport = transport;
}
/**
* Return default priority.
* @see com.cosylab.epics.caj.impl.Request#getPriority()
*/
public byte getPriority() {
return Request.DEFAULT_USER_PRIORITY;
}
/**
* @see com.cosylab.epics.caj.impl.Request#getRequestMessage()
*/
public ByteBuffer getRequestMessage()
{
if (requestMessage == null)
requestMessage = generateRequestMessage();
return requestMessage;
}
/**
* Generates (new instance) new request message.
* Used if requestMessage
not yet set - lazy message generation.
* @return generated request message.
* @see com.cosylab.epics.caj.impl.Request#getRequestMessage()
*/
public ByteBuffer generateRequestMessage()
{
// noop
return null;
}
/**
* Submit request to the corresponding transport.
* @see com.cosylab.epics.caj.impl.Request#submit()
*/
public void submit() throws IOException
{
transport.submit(this);
}
/**
* Inserts CA header to the buffer.
*
* @param transport
* transport to be used when sending.
* @param buffer
* buffer to be filled, can be null
.
* @return filled buffer, if given buffer size is less that header size,
* then new buffer is allocated and returned.
*/
public static ByteBuffer insertCAHeader(Transport transport, ByteBuffer buffer,
short command, int payloadSize,
short dataType, int dataCount,
int parameter1, int parameter2)
{
boolean useExtendedHeader = payloadSize >= 0xFFFF || dataCount >= 0xFFFF;
// check if supported by current transport protocol revision
if (useExtendedHeader && transport != null && transport.getMinorRevision() < 9)
throw new IllegalArgumentException("Out of bounds.");
int requiredSize = useExtendedHeader ?
CAConstants.CA_EXTENDED_MESSAGE_HEADER_SIZE : CAConstants.CA_MESSAGE_HEADER_SIZE;
// allocate buffer, if necessary
if (buffer == null || (buffer.limit() - buffer.position() < requiredSize))
buffer = ByteBuffer.allocate(requiredSize);
// standard header
if (!useExtendedHeader)
{
buffer.putShort(command);
// conversion int -> unsigned short is done right
buffer.putShort((short)payloadSize);
buffer.putShort(dataType);
// conversion int -> unsigned short is done right
buffer.putShort((short)dataCount);
buffer.putInt(parameter1);
buffer.putInt(parameter2);
}
// extended header
else
{
buffer.putShort(command);
buffer.putShort((short)0xFFFF);
buffer.putShort(dataType);
buffer.putShort((short)0x0000);
buffer.putInt(parameter1);
buffer.putInt(parameter2);
buffer.putInt(payloadSize);
buffer.putInt(dataCount);
}
return buffer;
}
/**
* Fills buffer to become aligned. ByteBuffer.position()
is aligned.
* @param align alignment to be used
* @param buffer buffer to be filled, non-null
.
* @return filled buffer, if given buffer size is less that aligned size,
* then new buffer is allocated and returned.
*/
public static ByteBuffer alignBuffer(int align, ByteBuffer buffer)
{
int alignedBufferSize = calculateAlignedSize(align, buffer.position());
if (alignedBufferSize > buffer.capacity())
{
ByteBuffer nbuffer = ByteBuffer.allocate(alignedBufferSize);
nbuffer.put(buffer);
buffer = nbuffer;
}
// fill w/ zeros
alignedBufferSize -= buffer.position();
for (int i = 0; i < alignedBufferSize; i++)
buffer.put((byte)0);
return buffer;
}
/**
* Calculates aligned sice.
* @param align alignment to be used
* @param nonAlignedSize current non-aligned size
* @return aligned size.
*/
public static int calculateAlignedSize(int align, int nonAlignedSize)
{
return ((nonAlignedSize+align-1)/align)*align;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy