/*
* Created by Andrey Cherkashin (acherkashin)
* http://acherkashin.me
*
* License
* Copyright (c) 2015 Andrey Cherkashin
* The project released under the MIT license: http://opensource.org/licenses/MIT
*/
package ragefist.core.network;
import java.io.IOException;
import java.net.ConnectException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author acherkashin
*/
public class SocketStrategyDefault implements ISocketStrategy
{
private static final Charset _charset = Charset.defaultCharset();
private final static ISocketStrategy _instance = new SocketStrategyDefault();
public static final ISocketStrategy getInstance() { return _instance; }
@Override
public byte[][] readPackets(SocketClient socket, ByteBuffer readBuffer) throws IOException {
PacketBufferDefault packetBuffer = (PacketBufferDefault)socket.getPacketBuffer(PacketBufferDefault.class);
List<byte[]> packets = new ArrayList<>();
int bytesRead;
while ((bytesRead = socket.read(readBuffer)) > 0) {
readBuffer.flip();
while(readBuffer.remaining() > 0) {
// No header yet
if (packetBuffer.hasHeader() == false) {
// Can't read header - need to put 4 bytes into the buffer
if (packetBuffer.canReadHeader() == false) {
packetBuffer.put(readBuffer, 0, Math.min(4, readBuffer.remaining()));
if (readBuffer.remaining() == 0) {
break;
}
}
// Can read header - its already in a packet buffer
if (packetBuffer.canReadHeader()) {
packetBuffer.readHeader();
}
}
// Packet header is already exist
if (packetBuffer.hasHeader()) {
int bytesToWrite = packetBuffer.getBytesToFinishPacket();
if (bytesToWrite > 0) {
packetBuffer.put(readBuffer, 0, Math.min(bytesToWrite, readBuffer.remaining()));
}
if (packetBuffer.hasPacket()) {
packets.add(packetBuffer.readPacket());
}
}
}
readBuffer.clear();
}
if (bytesRead < 0) {
throw new ConnectException();
}
byte[][] array = new byte[packets.size()][];
for(int i = 0; i < array.length; i++) {
byte[] byteArray = packets.get(i);
array[i] = byteArray;
}
return array;
}
@Override
public int writePacket(SocketClient socket, String packet) throws IOException {
return socket.write(_charset.encode(packet));
}
@Override
public int writePacket(SocketClient socket, byte[] bytes) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(bytes.length + 4); // 4 bytes for length
buffer.putInt((int)bytes.length);
buffer.put(bytes);
buffer.flip();
return socket.write(buffer);
}
}