
org.jgroups.nio.Buffers Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote Jakarta Enterprise Beans and Jakarta Messaging, including
all dependencies. It is intended for use by those not using maven, maven users should just import the Jakarta Enterprise Beans and
Jakarta Messaging BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
package org.jgroups.nio;
import org.jgroups.Global;
import org.jgroups.util.Util;
import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SocketChannel;
/**
* Use to write or read {length, data} pairs to or from a channel using gathering writes or scattering reads. This
* class is not synchronized.
* @author Bela Ban
* @since 3.6.5
*/
public class Buffers {
// bufs[0] contains the number of bytes to write or read (length)
// bufs[1] contains the data to be written or read
protected final ByteBuffer[] bufs;
public Buffers() {
this(null);
}
public Buffers(int capacity) {
bufs=new ByteBuffer[capacity *2];
}
public Buffers(ByteBuffer data) {
bufs=new ByteBuffer[]{ByteBuffer.allocate(Global.INT_SIZE), data};
}
public int remaining() {
return bufs[0].remaining() + (bufs[1] != null? bufs[1].remaining() : 0);
}
/**
* Writes the length and data with a gathering write
* @param ch The channel to write to
* @param buf The data buffer. Note that {@link ByteBuffer#position} needs to be at the start of the data to be
* written. The buffer must not be reused by the application as the write may not be synchronous; that is,
* after this call returns, the data is not guaranteed to be completely written and may be written later.
* @return True if all the bytes of the buffer were written successfully, false otherwise.
* @throws Exception Thrown if the write failed
*/
public boolean write(SocketChannel ch, ByteBuffer buf) throws Exception {
if(bufs[1] != null && !write(ch))
return false; // didn't manage to write all bytes
bufs[0].clear();
bufs[0].putInt(buf.remaining()).flip();
bufs[1]=buf;
return write(ch);
}
/**
* Tries to complete a previous (unfinished) write
* @param ch The channel to write to
* @return True of all remaining bytes could be written, false otherwise
* @throws Exception Thrown if the write failed
*/
public boolean write(SocketChannel ch) throws Exception {
if(bufs[1] == null) return true;
if(ch != null /* && ch.isConnected() */) {
try {
ch.write(bufs); // send the (unfinished) buffer from the previous write
}
catch(ClosedChannelException closed_ex) {
throw closed_ex;
}
catch(NotYetConnectedException | IOException others) {
; // ignore, we'll queue 1 write
}
}
return nullData(remaining() == 0);
}
/**
* Reads length, then allocates a data buffer and reads all data into it. Returns the data buffer when complete, or
* null when not all data has been read
* @param ch The channel to read from
* @return The complete data buffer, or null when more data needs to be read
* @throws Exception Thrown when the read failed
*/
public ByteBuffer read(SocketChannel ch) throws Exception {
if(bufs[0].hasRemaining() && ch.read(bufs[0]) < 0)
throw new EOFException();
if(bufs[0].hasRemaining())
return null;
if(bufs[1] == null) {
int len=bufs[0].getInt(0); // we know bufs[0] is always 4 bytes, no need to clear or flip it
bufs[1]=ByteBuffer.allocate(len);
}
if(bufs[1].hasRemaining() && ch.read(bufs[1]) < 0)
throw new EOFException();
if(!bufs[1].hasRemaining()) {
try {
return (ByteBuffer)bufs[1].clear();
}
finally {
bufs[0].clear();
bufs[1]=null;
}
}
return null; // has remaining; not all data read yet
}
public String toString() {
StringBuilder sb=new StringBuilder(Util.print(bufs[0]));
if(bufs[1] != null)
sb.append(", ").append(Util.print(bufs[1]));
sb.append(", rem ").append(remaining());
return sb.toString();
}
protected boolean nullData(boolean all_data_sent) {
if(all_data_sent)
bufs[1]=null;
return all_data_sent;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy