/* * Created on Mar 7, 2012 * Created by Paul Gardner * * Copyright 2012 Vuze, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ package com.aelitis.azureus.core.peermanager.messaging.azureus; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import org.gudy.azureus2.core3.util.BDecoder; import org.gudy.azureus2.core3.util.BEncoder; import org.gudy.azureus2.core3.util.DirectByteBuffer; import com.aelitis.azureus.core.peermanager.messaging.Message; import com.aelitis.azureus.core.peermanager.messaging.MessageException; import com.aelitis.azureus.core.peermanager.messaging.MessagingUtil; public class AZMetaData implements AZMessage, AZUTMetaData { private final byte version; private DirectByteBuffer buffer = null; private int msg_type; private int piece; private DirectByteBuffer metadata; private int total_size; public AZMetaData( int _piece, byte _version ) { msg_type = MSG_TYPE_REQUEST; piece = _piece; version = _version; } public AZMetaData( int _piece, ByteBuffer _data, int _total_size, byte _version ) { msg_type = _data==null?MSG_TYPE_REJECT:MSG_TYPE_DATA; piece = _piece; total_size = _total_size; version = _version; if ( _data != null ){ metadata = new DirectByteBuffer( _data ); } } public AZMetaData( Map map, DirectByteBuffer data, byte _version ) { if ( map != null ){ msg_type = ((Long)map.get( "msg_type" )).intValue(); piece = ((Long)map.get( "piece" )).intValue(); } metadata = data; version = _version; } public String getID() { return( ID_AZ_METADATA ); } public byte[] getIDBytes() { return( ID_AZ_METADATA_BYTES ); } public String getFeatureID() { return( AZ_FEATURE_ID ); } public int getFeatureSubID() { return SUBID_ID_AZ_METADATA; } public int getType() { return Message.TYPE_PROTOCOL_PAYLOAD; } public byte getVersion() { return( version ); }; public String getDescription() { return( getID() + " piece #" + piece + ", mt=" + msg_type ); } public int getMessageType() { return( msg_type ); } public int getPiece() { return( piece ); } public DirectByteBuffer getMetadata() { return( metadata ); } public void setMetadata( DirectByteBuffer b ) { metadata = b; } 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_AZ_METADATA ); } if ( msg_type == MSG_TYPE_DATA ){ return new DirectByteBuffer[]{ buffer, metadata }; }else{ return new DirectByteBuffer[]{ buffer }; } } 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 )); } } public void destroy() { if ( buffer != null ){ buffer.returnToPool(); } if ( metadata != null ){ metadata.returnToPool(); } } }