lowentry.ue4.libs.pyronet.jawnae.pyronet.traffic.PyroByteSinkFeeder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java Show documentation
Show all versions of java Show documentation
A Java library for the Low Entry UE4 plugins.
The newest version!
package lowentry.ue4.libs.pyronet.jawnae.pyronet.traffic;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import lowentry.ue4.libs.pyronet.jawnae.pyronet.PyroClient;
import lowentry.ue4.libs.pyronet.jawnae.pyronet.PyroSelector;
import lowentry.ue4.libs.pyronet.jawnae.pyronet.events.PyroClientAdapter;
public class PyroByteSinkFeeder extends PyroClientAdapter
{
private final PyroSelector selector;
private final ByteBuffer buf;
private final ByteStream inbound;
private final LinkedList sinks;
public PyroByteSinkFeeder(PyroClient client)
{
this(client.selector());
}
public PyroByteSinkFeeder(PyroSelector selector)
{
this(selector, 8 * 1024);
}
public PyroByteSinkFeeder(PyroSelector selector, int bufferSize)
{
this.selector = selector;
this.buf = ByteBuffer.allocate(bufferSize);
this.inbound = new ByteStream();
this.sinks = new LinkedList();
}
//
@Override
public void receivedData(PyroClient client, ByteBuffer data)
{
this.feed(data);
}
//
public ByteBuffer shutdown()
{
int bytes = this.inbound.getByteCount();
ByteBuffer tmp = ByteBuffer.allocate(bytes);
this.inbound.get(tmp);
this.inbound.discard(bytes);
tmp.flip();
return tmp;
}
public void addByteSink(ByteSink sink)
{
this.selector.checkThread();
this.register(sink);
}
public void feed(ByteBuffer data)
{
ByteBuffer copy = this.selector.copy(data);
this.inbound.append(copy);
this.fill();
}
final void register(ByteSink sink)
{
this.sinks.addLast(sink);
this.fill();
}
private final void fill()
{
if(this.sinks.isEmpty())
{
return;
}
this.buf.clear();
this.inbound.get(this.buf);
int off = 0;
int end = this.buf.position();
ByteSink currentSink = this.sinks.removeFirst();
outer: while(off < end)
{
switch(currentSink.feed(this.buf.get(off)))
{
case ByteSink.FEED_ACCEPTED:
off += 1;
continue outer;
case ByteSink.FEED_ACCEPTED_LAST:
off += 1;
break;
case ByteSink.FEED_REJECTED:
off += 0;
break;
}
if(this.sinks.isEmpty())
{
currentSink = null;
break;
}
currentSink = this.sinks.removeFirst();
}
if(currentSink != null)
{
this.sinks.addFirst(currentSink);
}
this.inbound.discard(off);
}
}