use of com.biglybt.core.util.DirectByteBuffer in project BiglyBT by BiglySoftware.
the class AZMessageDecoder method postReadProcess.
private int postReadProcess() throws IOException {
int prot_bytes_read = 0;
int data_bytes_read = 0;
if (!reading_length_mode && !destroyed) {
// reading payload data mode
// ensure-restore proper buffer limits
payload_buffer.limit(SS, message_length);
length_buffer.limit(SS, 4);
int curr_position = payload_buffer.position(SS);
int read = curr_position - pre_read_start_position;
if (msg_id_bytes == null && curr_position >= 4) {
// need to have read the message id length first 4 bytes
payload_buffer.position(SS, 0);
int id_size = payload_buffer.getInt(SS);
// restore
payload_buffer.position(SS, curr_position);
if (id_size < 1 || id_size > 1024)
throw new IOException("invalid id_size [" + id_size + "]");
msg_id_bytes = new byte[id_size];
}
if (msg_id_bytes != null && curr_position >= msg_id_bytes.length + 4) {
// need to have also read the message id bytes
if (!msg_id_read_complete) {
payload_buffer.position(SS, 4);
payload_buffer.get(SS, msg_id_bytes);
// restore
payload_buffer.position(SS, curr_position);
msg_id_read_complete = true;
}
Message message = MessageManager.getSingleton().lookupMessage(msg_id_bytes);
if (message == null) {
Debug.out("Unknown message type '" + new String(msg_id_bytes) + "'");
throw (new IOException("Unknown message type"));
}
if (message.getType() == Message.TYPE_DATA_PAYLOAD) {
data_bytes_read += read;
} else {
prot_bytes_read += read;
}
} else {
prot_bytes_read += read;
}
if (!payload_buffer.hasRemaining(SS) && !is_paused) {
// full message received!
// prepare for use
payload_buffer.position(SS, 0);
DirectByteBuffer ref_buff = payload_buffer;
payload_buffer = null;
try {
Message msg = AZMessageFactory.createAZMessage(ref_buff);
messages_last_read.add(msg);
} catch (Throwable e) {
ref_buff.returnToPoolIfNotFree();
if (e instanceof RuntimeException) {
throw ((RuntimeException) e);
}
throw new IOException("AZ message decode failed: " + e.getMessage());
}
// see if we've already read the next message's length
reading_length_mode = true;
// reset receive percentage
percent_complete = -1;
msg_id_bytes = null;
msg_id_read_complete = false;
} else {
// only partial received so far
// compute receive percentage
percent_complete = (payload_buffer.position(SS) * 100) / message_length;
}
}
if (reading_length_mode && !destroyed) {
// ensure proper buffer limit
length_buffer.limit(SS, 4);
prot_bytes_read += (pre_read_start_buffer == 1) ? length_buffer.position(SS) - pre_read_start_position : length_buffer.position(SS);
if (!length_buffer.hasRemaining(SS)) {
// done reading the length
reading_length_mode = false;
length_buffer.position(SS, 0);
message_length = length_buffer.getInt(SS);
// reset it for next length read
length_buffer.position(SS, 0);
if (message_length < MIN_MESSAGE_LENGTH || message_length > maximum_message_size) {
throw new IOException("Invalid message length given for AZ message decode: " + message_length + " (max=" + maximum_message_size + ")");
}
payload_buffer = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_AZ_PAYLOAD, message_length);
}
}
protocol_bytes_last_read += prot_bytes_read;
data_bytes_last_read += data_bytes_read;
return prot_bytes_read + data_bytes_read;
}
use of com.biglybt.core.util.DirectByteBuffer in project BiglyBT by BiglySoftware.
the class AZMessageFactory method createAZRawMessage.
/**
* Create the proper AZ raw message from the given base message.
* @param base_message to create from
* @return AZ raw message
*/
public static RawMessage createAZRawMessage(Message base_message, int padding_mode) {
byte[] id_bytes = base_message.getIDBytes();
byte version = base_message.getVersion();
DirectByteBuffer[] payload = base_message.getData();
int payload_size = 0;
for (int i = 0; i < payload.length; i++) {
payload_size += payload[i].remaining(bss);
}
// create and fill header buffer
DirectByteBuffer header;
if (version >= MESSAGE_VERSION_SUPPORTS_PADDING) {
boolean enable_padding = padding_mode != AZMessageEncoder.PADDING_MODE_NONE;
short padding_length;
if (enable_padding) {
if (padding_mode == AZMessageEncoder.PADDING_MODE_MINIMAL) {
padding_length = (short) (RandomUtils.nextInt(SMALL_PAD_MAX));
} else {
padding_length = (short) (RandomUtils.nextInt(payload_size > 256 ? SMALL_PAD_MAX : BIG_PAD_MAX));
}
if (padding_length == 0) {
enable_padding = false;
}
} else {
padding_length = 0;
}
byte flags = enable_padding ? (byte) 0x01 : (byte) 0x00;
int header_size = 4 + 4 + id_bytes.length + 1 + (enable_padding ? (2 + padding_length) : 0);
header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_AZ_HEADER, header_size);
header.putInt(bss, header_size - 4 + payload_size);
header.putInt(bss, id_bytes.length);
header.put(bss, id_bytes);
byte version_and_flags = (byte) ((flags << 4) | version);
header.put(bss, version_and_flags);
if (enable_padding) {
byte[] padding = new byte[padding_length];
header.putShort(bss, padding_length);
header.put(bss, padding);
}
} else {
int header_size = 4 + 4 + id_bytes.length + 1;
header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_AZ_HEADER, header_size);
header.putInt(bss, header_size - 4 + payload_size);
header.putInt(bss, id_bytes.length);
header.put(bss, id_bytes);
header.put(bss, version);
}
header.flip(bss);
DirectByteBuffer[] raw_buffs = new DirectByteBuffer[payload.length + 1];
raw_buffs[0] = header;
System.arraycopy(payload, 0, raw_buffs, 1, payload.length);
String message_id = base_message.getID();
// determine if a legacy BT message
LegacyData ld = (LegacyData) legacy_data.get(message_id);
if (ld != null) {
// legacy message, use pre-configured values
return new RawMessageImpl(base_message, raw_buffs, ld.priority, ld.is_no_delay, ld.to_remove);
}
// these should really be properties of the message...
int priority;
boolean no_delay = true;
if (message_id == AZMessage.ID_AZ_HANDSHAKE) {
// handshake needs to go out first - if not high then bitfield can get in front of it...
priority = RawMessage.PRIORITY_HIGH;
} else if (message_id == AZMessage.ID_AZ_HAVE) {
priority = RawMessage.PRIORITY_LOW;
no_delay = false;
} else {
// standard message, ensure that protocol messages have wire priority over data payload messages
priority = base_message.getType() == Message.TYPE_DATA_PAYLOAD ? RawMessage.PRIORITY_LOW : RawMessage.PRIORITY_NORMAL;
}
return new RawMessageImpl(base_message, raw_buffs, priority, no_delay, null);
}
use of com.biglybt.core.util.DirectByteBuffer in project BiglyBT by BiglySoftware.
the class BTMessageFactory method createBTRawMessage.
/**
* Create the proper BT raw message from the given base message.
* @param base_message to create from
* @return BT raw message
*/
public static RawMessage createBTRawMessage(Message base_message) {
if (base_message instanceof RawMessage) {
// used for handshake and keep-alive messages
return (RawMessage) base_message;
}
LegacyData ld = (LegacyData) legacy_data.get(base_message.getID());
if (ld == null) {
Debug.out("legacy message type id not found for [" + base_message.getID() + "]");
// message id type not found
return null;
}
DirectByteBuffer[] payload = base_message.getData();
int payload_size = 0;
for (int i = 0; i < payload.length; i++) {
payload_size += payload[i].remaining(DirectByteBuffer.SS_MSG);
}
DirectByteBuffer header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_BT_HEADER, 5);
header.putInt(DirectByteBuffer.SS_MSG, 1 + payload_size);
header.put(DirectByteBuffer.SS_MSG, ld.bt_id);
header.flip(DirectByteBuffer.SS_MSG);
DirectByteBuffer[] raw_buffs = new DirectByteBuffer[payload.length + 1];
raw_buffs[0] = header;
System.arraycopy(payload, 0, raw_buffs, 1, payload.length);
return new RawMessageImpl(base_message, raw_buffs, ld.priority, ld.is_no_delay, ld.to_remove);
}
use of com.biglybt.core.util.DirectByteBuffer in project BiglyBT by BiglySoftware.
the class AZStatRequest method getData.
@Override
public DirectByteBuffer[] getData() {
if (buffer == null) {
Map map = new HashMap();
map.put("request", request);
buffer = MessagingUtil.convertPayloadToBencodedByteStream(map, DirectByteBuffer.AL_MSG);
}
return new DirectByteBuffer[] { buffer };
}
use of com.biglybt.core.util.DirectByteBuffer in project BiglyBT by BiglySoftware.
the class UTMetaData method getData.
@Override
public DirectByteBuffer[] getData() {
if (buffer == null) {
Map payload_map = new HashMap();
payload_map.put("msg_type", new Long(msg_type));
payload_map.put("piece", new Long(piece));
if (total_size > 0) {
payload_map.put("total_size", total_size);
}
buffer = MessagingUtil.convertPayloadToBencodedByteStream(payload_map, DirectByteBuffer.AL_MSG_UT_METADATA);
}
if (msg_type == MSG_TYPE_DATA) {
return new DirectByteBuffer[] { buffer, metadata };
} else {
return new DirectByteBuffer[] { buffer };
}
}
Aggregations