/** * Construct a new AZ message instance from the given message raw byte stream. * @param stream_payload data * @return decoded/deserialized AZ message * @throws MessageException if message creation failed. * NOTE: Does not auto-return to buffer pool the given direct buffer on thrown exception. */ public static Message createAZMessage( DirectByteBuffer stream_payload ) throws MessageException { int id_length = stream_payload.getInt( bss ); if( id_length < 1 || id_length > 1024 || id_length > stream_payload.remaining( bss ) - 1 ) { byte bt_id = stream_payload.get( (byte)0, 0 ); throw new MessageException( "invalid AZ id length given: " +id_length+ ", stream_payload.remaining(): " +stream_payload.remaining( bss )+ ", BT id?=" +bt_id ); } byte[] id_bytes = new byte[ id_length ]; stream_payload.get( bss, id_bytes ); // if only the version came first we could save a lot of space by changing the id length + id.... // in the meantime we overload the version byte to have a version number and flags // flags = top 4 bits, version = bottom 4 bits byte version_and_flags = stream_payload.get( bss ); byte version = (byte)( version_and_flags & 0x0f ); if ( version >= MESSAGE_VERSION_SUPPORTS_PADDING ){ byte flags = (byte)(( version_and_flags >> 4 ) & 0x0f ); if ( ( flags & 0x01 ) != 0 ){ short padding_length = stream_payload.getShort( bss ); byte[] padding = new byte[padding_length]; stream_payload.get( bss, padding ); } } return MessageManager.getSingleton().createMessage( id_bytes, stream_payload, version ); }
@Override public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException { byte[] dict_bytes = new byte[ Math.min( 128, data.remaining( DirectByteBuffer.SS_MSG )) ]; data.get( DirectByteBuffer.SS_MSG, dict_bytes ); if ( dict_bytes.length != 1 ){ throw( new MessageException( "decode failed: incorrect length" )); } boolean ulo = dict_bytes[0] != 0; return( new UTUploadOnly( ulo, version )); }
if( !msg_id_read_complete ) { payload_buffer.position( SS, 4 ); payload_buffer.get( SS, msg_id_bytes );
@Override public byte[] toByteArray() { buffer.position( DirectByteBuffer.SS_EXTERNAL, 0 ); int len = buffer.limit( DirectByteBuffer.SS_EXTERNAL ); byte[] res = new byte[len]; buffer.get( DirectByteBuffer.SS_EXTERNAL, res ); buffer.position( DirectByteBuffer.SS_EXTERNAL, 0 ); return( res ); }
public static int getMessageType( DirectByteBuffer stream_payload ) { byte id = stream_payload.get( DirectByteBuffer.SS_MSG, 0 ); if( id == 84 ) return Message.TYPE_PROTOCOL_PAYLOAD; //handshake message byte in position 4 if ( id >= 0 && id < id_to_name.length ){ String name = id_to_name[ id ]; if ( name != null ){ Message message = MessageManager.getSingleton().lookupMessage( name ); if ( message != null ){ return( message.getType()); } } } // invalid, return whatever return Message.TYPE_PROTOCOL_PAYLOAD; }
if( data.get( DirectByteBuffer.SS_MSG ) != (byte)PROTOCOL.length() ) { throw new MessageException( "[" +getID() + "] decode error: payload.get() != (byte)PROTOCOL.length()" ); data.get( DirectByteBuffer.SS_MSG, header ); data.get( DirectByteBuffer.SS_MSG, reserved ); data.get( DirectByteBuffer.SS_MSG, infohash ); data.get( DirectByteBuffer.SS_MSG, peerid );
@Override public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException { int pos = data.position( DirectByteBuffer.SS_MSG ); byte[] dict_bytes = new byte[ Math.min( 128, data.remaining( DirectByteBuffer.SS_MSG )) ]; data.get( DirectByteBuffer.SS_MSG, dict_bytes ); try{ Map root = BDecoder.decode( dict_bytes ); data.position( DirectByteBuffer.SS_MSG, pos + BEncoder.encode( root ).length ); return( new AZMetaData( root, data, version )); }catch( Throwable e ){ e.printStackTrace(); throw( new MessageException( "decode failed", e )); } }
@Override public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException { int pos = data.position( DirectByteBuffer.SS_MSG ); byte[] dict_bytes = new byte[ Math.min( 128, data.remaining( DirectByteBuffer.SS_MSG )) ]; data.get( DirectByteBuffer.SS_MSG, dict_bytes ); try{ Map root = BDecoder.decode( dict_bytes ); data.position( DirectByteBuffer.SS_MSG, pos + BEncoder.encode( root ).length ); return( new UTMetaData( root, data, version )); }catch( Throwable e ){ e.printStackTrace(); throw( new MessageException( "decode failed", e )); } }
/** * Convert the given bencoded byte stream into a message map. * @param stream to convert * @param min_size of stream * @param id of message * @return mapped deserialization * @throws MessageException on convertion error * NOTE: Does not auto-return given direct buffer on thrown exception. */ public static Map convertBencodedByteStreamToPayload( DirectByteBuffer stream, int min_size, String id ) throws MessageException { if( stream == null ) { throw new MessageException( "[" +id +"] decode error: stream == null" ); } if( stream.remaining( DirectByteBuffer.SS_MSG ) < min_size ) { throw new MessageException( "[" +id +"] decode error: stream.remaining[" +stream.remaining( DirectByteBuffer.SS_MSG )+ "] < " +min_size ); } byte[] raw = new byte[ stream.remaining( DirectByteBuffer.SS_MSG ) ]; stream.get( DirectByteBuffer.SS_MSG, raw ); try { Map result = BDecoder.decode( raw ); stream.returnToPool(); return( result ); }catch( Throwable t ) { throw new MessageException( "[" +id+ "] payload stream b-decode error: " +t.getMessage() ); } }
field.get( DirectByteBuffer.SS_PEER, dataf );
byte id = stream_payload.get( DirectByteBuffer.SS_MSG );